6.8 KiB
Historical validation evidence from application commit
bd898e92d22f6c412e671908770f4d89c8ae12bc. Commands retain their original paths; current tooling is documented in README.md.
S2 implementation evidence
Validated on the development mini-PC on 2026-10-29: AMD Ryzen 7 7730U (8 cores, 16 threads), Ubuntu 26.04.1 LTS, Linux 7.0.0-38-generic x86_64, approximately 27 GiB RAM, Node v22.22.3, npm 10.9.8. The standalone Docker build uses the existing Node 24.15.0 image.
Lint scope and rules
ESLint 10.13.0, typescript-eslint 8.72.1 and angular-eslint 22.6.0 support the
existing Angular 22 and TypeScript 6.0.3 versions. Framework versions are unchanged.
The flat configuration applies recommended JavaScript, recommended type-checked
TypeScript and recommended Angular rules, plus the recommended template rules
for both inline and external templates. No rule suppressions were needed.
eslint-config-prettier prevents conflicts with the existing formatting settings.
tsconfig.eslint.json supplies one explicit type-checking project covering
application files, unit tests, Playwright tests and root TypeScript configuration.
This includes E2E and Playwright configuration outside Angular's app/test
compilation projects, without changing the application compilation scope.
Node types resolve process.env in those files. The existing test findings were
fixed by treating Playwright response JSON as unknown before checking its shape,
and returning an explicit resolved promise from the fake file reader.
Injected probes confirmed no-floating-promises for application, unit-test,
Playwright and configuration TypeScript; no-unused-vars for JavaScript;
and template/no-negated-async in both external and inline Angular templates.
Generated files are excluded. A warning-only CLI probe returned exit status 1
with --max-warnings 0.
Complete hook measurements
Run from the repository root, with dependencies installed:
node agiledancers-fe/tools/check-hook.mjs
This creates an isolated temporary Git repository from the current frontend and hook sources, links the installed dependency directory, makes an initial fixture commit and installs the real Husky wrapper. The real checkout and its index are not staged or committed by the checks. The temporary repository is retained and its report path is printed so failures can be inspected.
Each timed invocation runs sh .husky/_/pre-commit in a new process. Timing
starts before Husky and includes file selection, lint-staged backup, hiding
unstaged edits, fresh tool startup, formatting/checking, restaging and cleanup.
No ESLint or Prettier cache is enabled. The final measurement ran while the
standalone Docker build was also running; all selected-hook runs still passed. Three fresh executions per scenario and
candidate are recorded; there is no runtime timeout interrupting writers.
The combined candidate uses the same hook, adding type-aware ESLint after Prettier. The selected configuration uses only Prettier. Staged scopes are:
- Single:
src/app/app.ts. - Mixed: application TS, HTML and CSS,
angular.json,eslint.config.mjsand the Playwright spec (six files). - All: all 52 maintained frontend files, including non-applicable files that the hook must skip, plus a small TS preservation-test fixture; generated lockfile excluded. Exact paths and raw measurements are in the timing report.
| Candidate | Staged scope | Run 1 | Run 2 | Run 3 |
|---|---|---|---|---|
| combined | single | 2.875 s | 2.776 s | 2.894 s |
| combined | mixed | 3.779 s | 4.099 s | 4.478 s |
| combined | all | 5.916 s | 6.137 s | 4.728 s |
| prettier-only | single | 0.313 s | 0.338 s | 0.401 s |
| prettier-only | mixed | 0.648 s | 0.720 s | 0.647 s |
| prettier-only | all | 1.573 s | 1.441 s | 1.276 s |
The combined candidate exceeds three seconds, so it is rejected. Every measured Prettier-only execution is below three seconds, so that hook is installed. These are measurements on this mini-PC, not a guarantee for other machines or future repository sizes. Rerun the checks when the tooling or scope changes.
Preservation and installation checks
The isolated checks assert all of the following against the real hook, comparing both cached and unstaged binary diffs, status and stash state where appropriate:
- Partially staged formatting updates only the intended index version and retains independent unstaged changes in the same file.
- An unrelated file with both staged and unstaged edits remains intact.
- A commit without frontend changes leaves the state unchanged.
package-lock.jsonis not formatted or restaged.- A formatter syntax error after another file has been formatted aborts and restores the original index and worktree.
- A conflict restoring an unstaged change on the formatted line aborts and restores the original index and worktree.
- The rejected combined candidate also restores all changes when ESLint fails after successful formatting.
- No backup stash remains after successful recovery.
CI=trueandHUSKY=0leave an existing hooks configuration untouched; normal local installation selects.husky/_.
A real local npm ci successfully installed .husky/_ in this checkout.
Docker sets CI=true for installation and copies the prepare entry point before
npm ci, so the lifecycle script can safely skip hook installation. The
standalone build runs lint, tests and production compilation after copying sources.
Build and pipeline verification
The full Java-based pipeline was executed locally without invoking publication:
JAVA_HOME=/usr/lib/jvm/java-25-openjdk-amd64 \
PATH=/usr/lib/jvm/java-25-openjdk-amd64/bin:/home/wanja-krah/.nvm/versions/node/v22.22.3/bin:/usr/local/bin:/usr/bin:/bin \
TARGET_PLATFORM=linux/amd64 CI_RUN_ID=s2-local CI_RUN_ATTEMPT=2 \
java ci/Ci.java verify
Results: 20 backend tests, 17 CI-helper tests, clean frontend lint, 14 frontend
unit tests, production build, both application images and both container E2E
tests passed. Diagnostics remain in the ignored ci/artifacts/ directory.
A Gitea workflow run for these uncommitted changes has not been executed.
The CI-helper regression checks assert that lint immediately follows npm ci
and precedes tests/build; a lint failure stops frontend verification with its
nonzero status. Existing failed-verification and publication guards ensure only
a completely verified commit can publish. The shared command runner writes lint
output to the job log and retained verify.log. CI never invokes lint:fix.
npm run lint:fix followed by npm run lint also passed without further changes.
The standalone Docker build was checked separately with an isolated Docker
configuration to avoid the desktop credential helper; no images were published.