bend_puzzle/docs/test-policy.md
2026-08-01 16:06:14 +09:00

53 lines
4.5 KiB
Markdown

# Test tiers and source-guard inventory
The release pipeline has four explicit tiers:
- `npm run test:fast` — deterministic unit, contract, persistence, server, and
source-policy-compatible regression tests; no browser is launched.
- `npm run test:browser` — the required real-browser interaction/performance
matrix plus the store UI flow. Each runner owns one temporary profile and one
process tree, closes it in `finally`, and never targets an unrelated Edge
process. The UI runner uses `playwright-core` only as a driver for the
system-provided Edge binary; it does not download a second browser.
- `npm run test:storage` — opt-in large IndexedDB/archive scale coverage.
- `npm run test:ci` — source policy, fast suite, and required browser release
behavior. CI sets the small bounded browser profile and runs one job at a
time.
## Effects and cosmetics release gates
The browser performance runner loads deterministic checkpoints from `test/fixtures/effect-visual-checkpoints.json` and exercises all six reaction styles at normalized lifetimes of 0.10, 0.25, 0.50, 0.75, and 0.95. Direct main-thread rendering with glyph and path caches bypassed is the correctness reference. Cached output may differ only within the anti-aliasing tolerance, with at least 99.5% of pixels inside that tolerance. Structural reductions, style substitution, dropped overlap, shorter lifetimes, or automatic quality tiers are release failures.
Normal-speed Edge gates enforce the 30 FPS cadence, per-style work limits, the four-effect overlap budget, full rendering of eight simultaneous valid effects, bounded scheduler callback rates, reaction publication p95 at or below 2 ms, Gem and completion setup p95 at or below 3 ms, localized inventory patch p95 at or below 8 ms, exact inventory focus/scroll/node retention, Aurora active-write and inactive/hidden zero-work behavior, effect-plus-pan/zoom/pickup/edge-pan operation, and zero owned state after a 100-cycle cleanup stress. The settled heap delta must remain at or below 2 MB after the bounded caches are cleared. The 4x CPU profile is an overload diagnostic: it enforces bounded callbacks, complete rendering, and cleanup, but it does not permit the test or runtime to reduce visuals merely to meet normal-speed timing.
`effects-performance-smoke-test.js` is a documented repository-policy guard. Its source assertions protect the no-auto-degradation contract, bounded glyph/path caches, shared animation templates, localized inventory patches, and cleanup/lifecycle mechanisms that do not yet have a smaller public module seam. The browser runner always writes its report to `test-results/browser-performance-benchmark.json` unless `BEND_FIELD_BENCHMARK_OUTPUT` supplies another path, including when a gate fails after measurement.
## Source-shape guard inventory
The historical `source-smoke` and versioned `v47xx` files contain temporary
implementation-shape tripwires. They remain only where no stable public seam
exists yet. Their common reason is to prevent a known expensive or unsafe path
from being accidentally restored. Their removal condition is one of:
1. a pure module has a behavioral unit test;
2. a browser test measures the user-visible DOM, timing, or computed style;
3. a protocol/storage integration test covers the invariant; or
4. a generated artifact equality test covers the contract.
The following guards have already moved to public seams:
| Area | Public seam | Replacement coverage |
|---|---|---|
| Pointer ownership | `createGestureCoordinator` | `interaction-ownership-test.js` |
| Interaction scopes | `createInteractionState` | `interaction-ownership-test.js` |
| 60 Hz latest-value scheduling | `createFrameScheduler` | `frame-drag-scheduler-test.js` and browser cadence probes |
| Pickup lifecycle/queue | `createDragScheduler` | `frame-drag-scheduler-test.js` and release-drain behavior |
| Cursor identity/presentation | `createCursorModel` | `architecture-boundaries-test.js` and browser cursor probes |
| HTTP dispatch | `createHttpRouter` | `architecture-boundaries-test.js` and server integration |
| Authentication | `createAuthenticator` | `architecture-boundaries-test.js` and server security integration |
| Atomic JSON storage | `createJsonRepository` | recovery and server integration tests |
When touching a remaining source assertion, migrate it to the nearest seam and
delete the old assertion in the same change. New tests must not parse function
source unless they enforce a documented repository policy that cannot be
expressed as behavior.