Cite2Site v1.0 Compatibility Corpus
Status: v1.0 stabilization authority. Defines the fixture set and test matrix that future releases must preserve as a regression gate.
Purpose
The compatibility corpus is a frozen set of inputs and expected outputs that prove the v1.0 stable contract behaves identically across releases. Any future release that breaks a corpus fixture must either fix the regression or document a MAJOR version bump with an explicit migration path.
Fixture Categories
1. Event Fixtures
Located in tests/compat_fixtures/events/.
| Fixture | Description | Expected |
|---|---|---|
citation_created.jsonl |
Single citation.created event | Replay resolves correctly |
citation_created_batch.jsonl |
3 citation.created with shared batch_id | All 3 resolve; batch index populated |
handle_bound_bind.jsonl |
citation.created + handle.bound (bind) | Preferred handle set |
handle_bound_rename.jsonl |
bind + rename | Old handle preserved as alias |
handle_bound_retire.jsonl |
bind + retire | Handle retired, no preferred handle |
citation_accepted.jsonl |
citation.created + citation.accepted | Status resolved, idempotent |
citation_retracted.jsonl |
citation.created + citation.retracted | Status retracted |
citation_restored.jsonl |
created + retracted + restored | Status resolved |
citation_relocated.jsonl |
created + relocated (new locator) | Locator updated |
citation_noted.jsonl |
created + noted | Note present in metadata |
full_workflow.jsonl |
Complete workflow: create, accept, retract, restore, note | All states valid |
2. Error Fixtures
Located in tests/compat_fixtures/errors/.
| Fixture | Error Code | Trigger |
|---|---|---|
missing_artifact.jsonl |
E_ARTIFACT_MISSING | Artifact deleted |
corrupt_project.json |
E_JSON_INVALID | project.json is not valid JSON |
corrupt_history.jsonl |
E_JSONL_INVALID | citation-history.jsonl has non-JSON line |
tampered_event.jsonl |
E_EVENT_HASH | event_id replayed by evidence changed |
chain_break.jsonl |
E_EVENT_CHAIN | previous_event_hash mismatch |
missing_event_id.jsonl |
E_EVENT_ID_MISSING | Event without event_id |
unknown_schema_project.json |
E_SCHEMA_UNKNOWN | project.json with foreign schema_version |
unsupported_schema_project.json |
E_SCHEMA_UNSUPPORTED | project.json with c2s prefix but wrong version |
handle_collision.jsonl |
E_HANDLE_COLLISION | Two citations with same handle |
empty_batch.json |
E_BATCH_EMPTY | Batch request with no items |
3. Privacy Mode Fixtures
Located in tests/compat_fixtures/privacy/.
| Fixture | Mode | Expected |
|---|---|---|
metadata_only.json |
metadata_only | No accepted_evidence.text in any citation |
hash_only.json |
hash_only | No text or line_hashes in any citation |
snippet_allowed.json |
snippet (allow_snippet=true) | text present |
snippet_denied.json |
snippet (allow_snippet=false) | E_PRIVACY_POLICY |
private_link_allowed.json |
private_link (allow_private_link=true) | Private links present |
private_link_denied.json |
private_link (allow_private_link=false) | E_PRIVACY_POLICY |
4. Export Determinism Fixtures
Located in tests/compat_fixtures/exports/.
| Fixture | Description |
|---|---|
baseline/ |
Full citation repository with 5+ citations, handles, tags, batch |
baseline/expected_exports.json |
Canonical export output (SHA of all export files) |
5. Batch Request Fixtures
Located in tests/compat_fixtures/batch/.
| Fixture | Description |
|---|---|
all_or_nothing_ok.json |
3 valid items → all succeed |
all_or_nothing_fail.json |
1 invalid → nothing appended |
partial_ok.json |
2 valid + 1 invalid → valid appended, invalid reported |
content_hash_mismatch.json |
Expected hash mismatch → E_CONTENT_HASH_MISMATCH |
6. Integration Contract Fixtures
Located in examples/integration/fixtures/.
| Fixture | Description |
|---|---|
lookup-overlap-picker.json |
Multiple overlapping citations, requires_picker=true |
lookup-uncited-response.json |
No matching citation, single cite action |
picker-cancelled.json |
Picker cancellation response shape |
selection-citation-request.json |
cite-selection request contract |
unavailable-actions.json |
Citation with limited available actions |
Test Matrix
| Test Class | What It Covers | Fixture Set | Minimum Assertions |
|---|---|---|---|
CompatEventTests |
Every event type replays correctly | events/ | Status, preferred_handle, citation_id, event chain valid |
CompatErrorTests |
Every error code triggers correctly | errors/ | Error code matches, structured JSON output |
CompatPrivacyTests |
Every privacy mode enforces policy | privacy/ | No evidence leak in metadata_only/hash_only; refusal for unauthorized snippet/link |
CompatExportTests |
Export determinism | exports/ | SHA of all export files matches canonical output |
CompatBatchTests |
Batch all-or-nothing + partial | batch/ | Created/rejected counts correct; no partial append unless requested |
CompatMigrationTests |
Schema version validation | errors/ (unknown/unsupported) | Correct refusal codes; no authority rewrite |
CompatIntegrationTests |
Lookup-actions contract | integration/ | Response shape matches schema; picker behavior correct |
CompatRegressionTests |
Source-clean + hash-chain + no-leak | events/ + privacy/ | Artifact unchanged; hash chain valid; no evidence leak |
CompatDeterminismTests |
Cross-run determinism | exports/ | Two export runs produce identical output |
CompatDocTests |
Doc links, schema examples, command refs | build-docs/ | All links resolve; all schema examples parse; all commands documented |
Corpus Maintenance Rules
- Never modify a frozen fixture. If a bug is found in a fixture, add a new fixture with a documented migration note.
- Never delete a frozen fixture. If a fixture tests a deprecated behavior, mark it as deprecated but keep it in the corpus.
- Add fixtures for every new stable interface. A MINOR release that adds a command, event type, or flag must include corresponding fixtures.
- Run the full corpus in CI. Every PR and release must run all corpus tests. Failures block merge and release.
- Publish corpus results with release notes. Each release must include the number of fixtures run and any new additions.
Post-v1 Adapter-Specific Fixtures
The following fixture categories are defined for adapter builds deferred past v1.0 stabilization (Phase 7). They are specified here so the test contract is stable before implementation begins.
7. ConverterAdapter Fixtures
Located in tests/compat_fixtures/converter/.
| Fixture | Description | Expected |
|---|---|---|
docx_sample.docx |
Minimal .docx with known text | mammoth/pandoc stdout matches canonical plaintext |
pdf_sample.pdf |
Minimal .pdf with known text | pdftotext stdout matches canonical plaintext |
xlsx_sample.xlsx |
Minimal .xlsx with known cells | CSV-export path matches canonical plaintext |
converter_determinism/ |
Run each converter twice on same fixture | Byte-identical stdout across both runs |
converter_version_mismatch/ |
Simulate recorded vs installed converter version mismatch | Error surfaced, not silently ignored |
reindent_docx.docx |
Content edit before cited region | Accepted text still found once → resolved |
edit_docx.docx |
Cited passage itself edited | changed |
remove_docx.docx |
Cited passage removed | missing |
Version pinning: identify() must record converter name + version per
citation. A converter upgrade that changes output must be detectable, not a
silent replay failure. Determinism tests must run in CI — converter behavior
can differ across OS and container base images.
8. Browser Readability Re-Observation Fixtures
Located in tests/compat_fixtures/readability/.
| Fixture | Description | Expected |
|---|---|---|
static_page.html |
Static server-rendered page with cited passage | Readability extraction → cited text found → resolved |
static_page_edited.html |
Same page, cited passage edited | changed |
static_page_removed.html |
Same page, cited passage removed | missing |
static_page_determinism/ |
Fetch + extract same fixture twice | Byte-identical output; Readability version pinned |
spa_shell.html |
JS-rendered SPA (static shell, content via script) | adapter_unavailable, NOT missing/resolved |
login_redirect.html |
Mock auth redirect | adapter_unavailable, NOT comparison against login page |
Honesty requirement (critical): The SPA-shell and login-redirect fixtures
test the negative case FIRST. A false resolved against unrelated content is
a worse failure mode than an honest adapter_unavailable. JS-rendered/
authenticated/personalized pages without headless render support must report
adapter_unavailable.
@mozilla/readability version must be recorded per observation (same
discipline as converter version pinning). Full headless rendering
(Playwright-class, browser binary in CI) is a separate, deferred build.
Current Coverage
All 8 fixture categories are defined above (6 v1.0 baseline + 2 post-v1 adapter). The corresponding test classes
are specified in this corpus document for future implementation. Frozen
fixtures are to be placed under tests/compat_fixtures/ and tested by
tests/test_compat.py when built per the test matrix below.
Initial v1.0 corpus specification: 40+ fixture definitions across 6 categories covering all 7 event types, 38 error codes, 4 privacy modes, export determinism, batch semantics, schema migration, and integration contracts.