add the rewrite charter and its decision records
This commit is contained in:
parent
a8c5939804
commit
41e8714ca3
4 changed files with 519 additions and 0 deletions
87
runbooks/rewrite/testing-strategy.md
Normal file
87
runbooks/rewrite/testing-strategy.md
Normal file
|
|
@ -0,0 +1,87 @@
|
|||
# Scholarr rewrite - testing strategy **[live 2026-07-21]**
|
||||
|
||||
This is an agreed direction from the 2026-07-21 discussion with Justin, to be formalized during
|
||||
spec freeze. Part of the [scholarr-rewrite](README.md) runbook; read the doctrine there first.
|
||||
|
||||
This document records how the rewrite proves itself correct. It is a decision record, not the final
|
||||
spec: it feeds the spec set and defines the release gates below.
|
||||
|
||||
## Core principle
|
||||
|
||||
**Deterministic tests against recorded reality.** The service's hard logic (matching, dedup,
|
||||
scheduling, backoff) must be testable with **zero network**. Nothing that matters to correctness
|
||||
depends on a live provider being reachable at test time.
|
||||
|
||||
## Golden corpus
|
||||
|
||||
Two recorded artifacts become **permanent fixtures in the repo** (anonymized where needed):
|
||||
|
||||
- The **recovered v1 database**: 25,698 real publications, 492 profiles with real edge cases.
|
||||
- The **calibration run's cached OpenAlex responses**.
|
||||
|
||||
These are the ground for deterministic replay: the matcher and dedup logic are exercised against
|
||||
real data and real provider payloads without touching the network.
|
||||
|
||||
## The five pillars
|
||||
|
||||
1. **Pure logic** (normalization, fingerprinting, identifier parsing, confidence scoring):
|
||||
- table tests;
|
||||
- **property-based tests** for the invariants that must always hold: normalization is
|
||||
idempotent, dedup is order-independent, merge is commutative;
|
||||
- **Go native fuzzing** on every parser that touches external text or paste input.
|
||||
|
||||
2. **Provider clients:**
|
||||
- **contract tests** replaying recorded HTTP fixtures via `httptest`, including the ugly cases:
|
||||
`429` with and without `Retry-After`, truncated JSON, empty pages;
|
||||
- the **rate limiter and cooldown state machine** tested with a **fake clock**;
|
||||
- the **2026-07-21 OpenAlex IP block becomes a regression case** so the system's handling of an
|
||||
IP-level block is proven, not hoped.
|
||||
|
||||
3. **Sync engine** - executable invariants:
|
||||
- one active run per user;
|
||||
- idempotent re-runs;
|
||||
- additive-only baseline import;
|
||||
- crash-mid-run leaves resumable state;
|
||||
- **race detector in CI**, plus a **concurrent-write hammer test**, because single-writer
|
||||
discipline is the main risk of the SQLite-only design.
|
||||
|
||||
4. **Migrations:**
|
||||
- every migration tested **up and down** against a **real-database copy**;
|
||||
- plus a **seeded prior-version DB in CI**, so upgrades are proven **pre-release**.
|
||||
|
||||
5. **End-to-end smoke:**
|
||||
- the binary boots in CI with a **seeded SQLite** and a **stub provider**;
|
||||
- a **scripted curl** run walks the full API flow: onboard, import, sync, review-resolve, read,
|
||||
export.
|
||||
- **No browser automation.** UI QA is manual by Justin against the frozen design contract
|
||||
(`/opt/stacks/scholarr-rewrite/design/DESIGN.md`). See the working-conventions block
|
||||
in [README.md](README.md#conventions-for-any-agent-working-this-project).
|
||||
|
||||
## Dry runs are a product feature
|
||||
|
||||
Not test-only scaffolding, actual product behavior that also serves as the QA instrument:
|
||||
|
||||
- **bulk import previews** before creating anything;
|
||||
- **`--dry-run`** on sync and on destructive admin actions.
|
||||
|
||||
## Acceptance
|
||||
|
||||
**Shadow-run** with the real ~253-author list for **2 to 3 weeks**, alongside the dad's existing
|
||||
JS-script habit, and **diff what each caught**. This is the **release flip criterion** and follows
|
||||
the conductarr-soak pattern.
|
||||
|
||||
## Release gates, in order
|
||||
|
||||
1. unit + property + fuzz green;
|
||||
2. race detector green;
|
||||
3. migration up/down green;
|
||||
4. e2e smoke green;
|
||||
5. **golden-corpus ratchet** - matcher changes may not regress the recorded auto-match baseline;
|
||||
6. tagged release with a **tested backup/restore path documented**.
|
||||
|
||||
## Related
|
||||
|
||||
- The recovered v1 DB and calibration cache that become fixtures: [README.md](README.md) (Assets),
|
||||
[identity-calibration.md](identity-calibration.md).
|
||||
- Manual-QA rule (no browser automation): a working convention of this project, stated in
|
||||
[README.md](README.md#conventions-for-any-agent-working-this-project).
|
||||
Loading…
Add table
Add a link
Reference in a new issue