diff --git a/CHANGELOG.md b/CHANGELOG.md index 058d2e9..b4108b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,103 @@ All notable changes to this SDK are documented here. Format follows ## [Unreleased] +Minor release (2.21.0). Existing code keeps working unchanged; nothing to do +on upgrade. + +### Added + +- **Reads both response shapes.** The API is adding a newer, dated response + shape that gives each field one name across every endpoint. This release + still asks for the original shape (it sends the same `X-Lenz-API-Version` + as before), and every model now reads either shape. A body is read as the + newer shape only when it carries something only that shape has; every other + body is parsed exactly as before (same fields, values, dump, `repr`, + `exclude_unset`, schema and pickle). The newer names are read-only + properties, computed from whichever shape arrived, not model fields: + - `ExtractedClaims.claims`: every claim found, always a list, each an + `ExtractedClaim` with `claim` and (with `locate=True`) `positions`. + - `AssessClaim.status` (`"completed"` / `"failed"`), `AssessClaim.failure` + (`code`, `detail`, `hint`, `failure_class`, `retryable`, `docs_url`) and + `AssessClaim.more_claims`; `AssessResponse.status` (`ok` / + `no_checkable_claim` / `error`, the `AssessStatus` constant) and + `AssessResponse.failure`. + - `TaskStatus.failure`, the same block, on a failed verification. + - `TaskAccepted.claim`, `BatchItemResult.claim`, `CandidateClaim.claim`. + - `completed_at` on `Verification`, `VerificationListItem` and + `ReviewVerification`. + - `FailureBlock.code` and `FailureBlock.detail`; + `ReviewAssessment.more_claims`; `ReviewSummary.claims_found`, + `claim_limit_exceeded` (``None`` from the original shape, which says only + that the limit was reached: read `more_claims` there) and + `citation_limit_exceeded`; + `CitecheckSummary.citation_limit_exceeded`. + - Webhooks: an `event_id` property on every event, + `VerificationFailed.failure`, `VerificationNeedsInput.reason` and + `.claims` (properties: `dataclasses.asdict` and `repr` are unchanged). A review or citation-check + event in the newer shape carries no `task_id`; it then reads the + `review_id` / `citecheck_id`, so code keyed on `task_id` keeps one key per + review (deduplicate deliveries on `event_id`, as before). `parse_webhook` and + `LenzWebhooks.parse` read the newer envelope too (`event`, `event_id`, + the work's id, `status`, and the polled body under `verification` / + `review` / `citecheck`). + - Errors: a 409 for a failed run, a 429 and a 422 are read in either shape + (`failure` block, `retry_after`, `errors` list with a sentence `detail`). + +### Deprecated + +- The older names, kept with the meaning they always had, whichever shape + arrives: `ExtractedClaims.claim` / `identified_claims` / `locations`; + `AssessClaim.error_code` / `hint` / `identified_claims` (a failed row still + reads `verdict == "Error"` and `confidence == "low"`); `AssessResponse.error` + / `error_code`; `TaskStatus.error` / `failure_reason` / `failure_detail`; + `claim_text` and `CandidateClaim.text`; `modified_at` (computed from + `completed_at` with its original rule: set only when the verification + completed on a later UTC calendar day than it was created); + `FailureBlock.failure_reason`; `ReviewAssessment.error_code` / `hint` / + `identified_claims`; `claim_limit_reached` / `citation_limit_reached`; + `Usage.quota_resets_at` and the `verify` / `ask` / `assess` blocks (computed + from `credits` and `costs` when a response leaves them out). Reading them + does not warn, and the JSON schema is unchanged. "Nothing + checkable" keeps its old spelling in the old fields (`not_a_claim`, + `no_claim`) and reads `no_checkable_claim` in the new ones; + `ExtractedClaims.status` keeps `not_a_claim`. + +### Changed + +- **`verify`, `verify_and_wait`, `verify_batch` and `verify_batch_and_wait` + no longer send `webhook_url: ""`** when no webhook URL was given (nor an + empty per-item `webhook_url`). The API has always read an empty value there + as "use the key's default webhook", the same as leaving it out, so nothing + changes now; leaving it out keeps that meaning on later API versions, where + `""` means "no webhook". `review` and `citecheck` send `webhook_url` exactly as + before (there `""` means "no webhook"). +- A newer-shape body's `model_dump()` holds what the server sent plus the + original fields filled in from it. + +### Before the SDK asks for the newer shape + +This release only reads the newer shape; it keeps asking for the original +one. Two things to settle before a release sends the newer date: + +- A 422's `code` there is the server's new one (`blank_input` where the + original said `blank_item`, `validation_error` where it said nothing), and + its `message` is the server's sentence, not the field list. +- `lenz verify --json` on a `needs_input` run prints each option as the model + dumps it: from the newer shape that is `{claim, domain, text}`, not + `{text, domain}`. + +### Correction + +- **The /me/usage fields are not removed on 2026-11-29.** Earlier entries + (2.9.0 and 2.14.0) said `UsageCredits.bonus`, `UsageCapacity.credits` and the + per-capability `verify` / `ask` / `assess` blocks would go on that date. + They are deprecated and kept for existing callers; the API keeps sending + them to integrations built against its original shape. Their deprecation + warnings no longer name a date. +- **`TaskStatus.candidates` and `similar_claims` are not removed on + 2026-11-29** either (2.18.0 said so). They are deprecated, always empty, and + kept. + ## [2.20.0] - 2026-10-05 ### Added diff --git a/README.md b/README.md index efc0025..02cc3ae 100644 --- a/README.md +++ b/README.md @@ -221,7 +221,7 @@ edited = "".join(chars) `poll_after_seconds`. Pass `on_update=` to see the quick verdicts as soon as they are in and each deep check as it lands; without it the helper is silent. It raises `ReviewFailed` when the review fails (`error_code` and `hint` say -why) and `ReviewTimeout` after `timeout` seconds (600 by default); the review +why; `review.failure.code` is the cause in the newer spelling) and `ReviewTimeout` after `timeout` seconds (600 by default); the review keeps running, and the error carries its `review_id` and the last body read. To submit without waiting, `client.review(draft)` returns a `review_id`; read it with `client.get_review(review_id)`, or only the issues with @@ -297,7 +297,7 @@ client = Lenz(api_key="lenz_...") # 1. extract — pull verifiable claims out of any text (free) # add focus="..." to narrow it to the claims you care about out = client.extract(text=llm_output) -claims = out.identified_claims or [out.claim] +claims = [c.claim for c in out.claims] # 2. assess — one call per 20 claims (extract finds up to 100), one row per claim, same order quick = [row for i in range(0, len(claims), 20) for row in client.assess(claims=claims[i : i + 20]).claims] @@ -308,7 +308,7 @@ for c in quick: # 3. verify — escalate the low-confidence rows to the full panel + citations # verify_batch_and_wait takes up to 20 claims a call: the first 20 here -doubtful = [{"claim": c.claim} for c in quick if c.verdict != "Error" and c.confidence == "low"][:20] +doubtful = [{"claim": c.claim} for c in quick if c.status == "completed" and c.confidence == "low"][:20] results = client.verify_batch_and_wait(claims=doubtful) if doubtful else [] for r in results: if r.verification: @@ -322,13 +322,13 @@ print(reply.content) `assess(claims=[...])` takes up to 20 claims per call and always answers with exactly one row per claim, in the order sent. A row that could not be -given a verdict comes back in position with `verdict == "Error"`, an -`error_code` (`no_claim` / `framing_failed` / `upstream_unavailable` / -`timeout` — an open set; the last two are the ones worth resending as-is) -and a one-sentence `hint` on what to send next; it is not charged. A -compound item is assessed on its main claim and lists the other claims it -found in `identified_claims` (also with a `hint`) — send those as their own -items to check the rest. `assess(claim="...")` takes one text and answers +given a verdict comes back in position with `status == "failed"` and a +`failure` block: `failure.code` (`no_checkable_claim` / `framing_failed` / +`upstream_unavailable` / `timeout` — an open set; the last two are the ones +worth resending as-is) and `failure.hint`, one sentence on what to send next; +it is not charged. A compound item is assessed on its main claim and lists the +other claims it found in `more_claims` — send those as their own items to +check the rest. `assess(claim="...")` takes one text and answers with a row per claim found in it, up to 20, at 1 credit each; a text that makes more claims gets its 20 most check-worthy checked and the rest in `more_claims`, unchecked and free — send them back as `claims`, 20 a call. @@ -387,8 +387,8 @@ your own claims. Use webhooks for production async flows. ## What you get on the client -- **`client.extract(text=...)`** → `ExtractedClaims`. Free, capped at 1000/account/day. Add `focus=` to narrow the list — see [Steering extract](#steering-extract) — and `locate=True` to keep only the claims traced back to your text, with their positions (`out.locations`). Each attempt waits up to 150s by default (a timeout is retried like any transport error, and the call's idempotency key makes the retry replay the first answer); `timeout=` overrides it for that call. -- **`client.assess(claim=...)`** / **`client.assess(claims=[...])`** → `AssessResponse`. Sync. One statement (~15s; `text=` is accepted as an alias: a document is `text`, a claim is `claim`) or a list of up to 20 claims in one call (~15s) — exactly one row per claim, in order; rows that got no verdict are `"Error"` rows with an `error_code` and a `hint`, in position and free. A single text past 20 claims lists the rest in `more_claims` (`[]` otherwise). The two forms are mutually exclusive. `timeout=` overrides the client timeout for that call (both forms default to 100s: a long text can take up to 90s). +- **`client.extract(text=...)`** → `ExtractedClaims`. Free, capped at 1000/account/day. Add `focus=` to narrow the list — see [Steering extract](#steering-extract) — and `locate=True` to keep only the claims traced back to your text, with their positions (each `out.claims[i].positions`). Each attempt waits up to 150s by default (a timeout is retried like any transport error, and the call's idempotency key makes the retry replay the first answer); `timeout=` overrides it for that call. +- **`client.assess(claim=...)`** / **`client.assess(claims=[...])`** → `AssessResponse`. Sync. One statement (~15s; `text=` is accepted as an alias: a document is `text`, a claim is `claim`) or a list of up to 20 claims in one call (~15s) — exactly one row per claim, in order; rows that got no verdict have `status == "failed"` and a `failure` block (`failure.code`, `failure.hint`), in position and free. A single text past 20 claims lists the rest in `more_claims` (`[]` otherwise). The two forms are mutually exclusive. `timeout=` overrides the client timeout for that call (both forms default to 100s: a long text can take up to 90s). - **`client.verify(...)`** → `TaskAccepted`. Async submit; returns a `task_id`. Get the result by polling (`client.wait(...)` / `client.get_status(...)`) or via a webhook. - **`client.verify_and_wait(...)`** → `Verification`. Submit + poll until the pipeline lands (sync ergonomic). Equivalent to `wait(verify(...))`. - **`client.wait(task)`** → `Verification`. Block on a `task_id` (or a `TaskAccepted`) until it terminates. The polling counterpart to a webhook. @@ -426,9 +426,9 @@ results = client.verify_batch_and_wait( ) for r in results: if r.status == "completed": - print(r.claim_text, "→", r.verification.verdict) + print(r.claim, "→", r.verification.verdict) else: - print(r.claim_text, "→", r.status) # needs_input | failed | timeout + print(r.claim, "→", r.status) # needs_input | failed | timeout ``` A `failed` item with `status_detail is None` is a verification its account's @@ -471,6 +471,31 @@ Every claim-shaped response shares these fields at top level: | `confidence` | `str` | Categorical: `"high"` \| `"medium"` \| `"low"`. | | `lenz_score` | `int \| None` | Integer 1–10 (deep verdicts and list endpoints; `assess` omits it). | +### Field names: both response shapes + +The API is adding a newer, dated response shape that gives each field one +name across every endpoint. This SDK still asks for the original shape, and +its models read either one. The newer names are attributes already; the +older ones keep working, with the meaning they always had: + +| Read this | Instead of (deprecated, still works) | +|---|---| +| `ExtractedClaims.claims` (each `.claim`, `.positions`) | `claim`, `identified_claims`, `locations` | +| `AssessClaim.status` (`"completed"` / `"failed"`) and `.failure` | `verdict == "Error"`, `error_code`, `hint` | +| `AssessClaim.more_claims`, `ReviewAssessment.more_claims` | `identified_claims` | +| `AssessResponse.status` and `.failure` | `error`, `error_code` | +| `TaskStatus.failure` (`code`, `detail`, `hint`, `failure_class`, `retryable`, `docs_url`) | `error`, `failure_reason` and the flat fields | +| `TaskAccepted.claim`, `BatchItemResult.claim`, `CandidateClaim.claim` | `claim_text`, `text` | +| `Verification.completed_at` | `modified_at` | +| `ReviewSummary.claim_limit_exceeded`, `citation_limit_exceeded` | `claim_limit_reached`, `citation_limit_reached` | +| `FailureBlock.code`, `.detail` | `failure_reason` | +| `Usage.credits` and `Usage.costs` | the `verify` / `ask` / `assess` blocks, `quota_resets_at` | + +"Nothing checkable" is `no_checkable_claim` in the newer names; the older +fields keep their own spelling (`not_a_claim`, `no_claim`). The newer names +are read-only properties, so an original-shape response parses, dumps and +compares exactly as before. + ### A suggested rewrite (`suggested_rewrite`) A verification can carry `suggested_rewrite`: a suggested rewrite of its @@ -644,13 +669,13 @@ them. `credits.extra` is the non-expiring part of the balance. Its old name, `credits.bonus`, is deprecated: the same number, it emits a -`DeprecationWarning` when read and goes away on 2026-11-29. +`DeprecationWarning` when read and is kept for existing code. Per-capability `bonus` is that capability's share of `credits.extra`, so 200 extra credits read as `assess.bonus == 200` and `verify.bonus == 20`. The old `capability.credits` field is a deprecated alias of `bonus` (it never meant -the pool); reading it emits a `DeprecationWarning` and it goes away on -2026-11-29. +the pool); reading it emits a `DeprecationWarning` and it is kept for +existing code. ### Depth pricing @@ -815,7 +840,7 @@ At most 300 characters. A longer focus is rejected with a 422 rather than truncated, so you never get a subset you did not ask for. When the document has claims but none fall within your focus, `status` is -`"no_match"` and `identified_claims` is empty. The unfocused list is never +`"no_match"` and `claims` is empty. The unfocused list is never substituted — widen the focus and call again. ```python @@ -838,27 +863,24 @@ to your text, and to learn where the text makes each one: ```python out = client.extract(text=draft, locate=True) -for loc in out.locations or []: - for pos in loc.positions or []: - print(loc.claim, "->", pos.text) +for c in out.claims: + for pos in c.positions or []: + print(c.claim, "->", pos.text) if pos.start is not None: assert draft[pos.start : pos.end] == pos.text ``` A claim found nowhere in the text, or found with a different figure, is left -out; if that leaves no claim, `status` is `"not_a_claim"`. `locations` has one -`ClaimLocation` per returned claim, in the order of `identified_claims` (one -entry for a single `claim`), each with its `positions` (every place the text -makes it, in text order, at least one and at most 10). Each is a `Position`: +out; if that leaves no claim, `status` is `"not_a_claim"`. Each entry of +`claims` has its `positions` (every place the text makes it, in text order, +at least one and at most 10). Each is a `Position`: `start` and `end` index the text you sent in Unicode code points, so `text[start:end]` works natively; `end` is exclusive. Both are `None` when the input was a URL, since the page is not returned; `pos.text` carries the passage. -`locations` is `[]` when every claim was left out (`status` is then -`"not_a_claim"`), and `None` when `locate` was not set, when the extraction -found no claims, or -when the claims could not be located — the list is then returned unfiltered. +`positions` is `None` when `locate` was not set, or when the claims could not +be located — the list is then returned unfiltered. Locating adds a few seconds. `locate` defaults to off; leave it `None` to use the server default, or pass `False` to turn it off explicitly. diff --git a/openapi.json b/openapi.json index f53bc7d..603db53 100644 --- a/openapi.json +++ b/openapi.json @@ -411,7 +411,7 @@ } } }, - "description": "Return the calling account's credit balance and what it can still buy.\n\n**``credits`` is the balance.** One pool funds every billable capability,\nat the weights in ``costs`` \u2014 today ``verify`` 10, ``assess`` 1, ``ask`` 1.\nIt has two buckets: the monthly allowance for the current ``plan``, which\nresets at ``resets_at``, and non-expiring ``extra`` credits from grants and\ntop-ups, spent only once the allowance is gone. ``remaining`` is the sum,\nand is what a call is actually checked against.\n\n``credits.bonus`` is the deprecated old name of ``credits.extra``, the same\nnumber, removed on **2026-11-29** with the fields below. Read ``extra``.\n\n``plan`` is the stable slug to branch on; ``plan_label`` is the same tier\nas display copy (\"Pro\"). Two fields rather than one humanised\nstring, so a reworded label cannot break a client comparing tiers.\nThe Pro plan's ``plan`` is ``pro``; it read ``developer`` before\n2026-09-15 (#664), while ``plan_label`` already read \"Pro\".\n\n**The per-capability blocks are deprecated.** ``verify`` / ``ask`` /\n``assess`` are **projections** of that one pool into each capability's own\nunit \u2014 \"how many of these could I still make\" \u2014 not separate allowances.\nSpending on one moves all of them, and they are floor divisions, so a\nverify block ticks once per 10 credits spent anywhere.\n\nThey go on **2026-11-29**, together with the per-block ``credits`` alias.\nDerive them instead::\n\n remaining = credits.remaining // costs[capability]\n total = credits.total // costs[capability]\n used = total - remaining\n\nTwo capabilities at the same price emit identical blocks \u2014 ``ask`` and\n``assess`` are both 1 credit \u2014 which is the clearest sign the shape\ndescribes an allowance that no longer exists.\n\n``bonus`` in each block is ``credits.extra`` in that capability's unit. The\nolder key ``credits`` is its deprecated alias, on the same date.\n\n``costs`` is one entry per capability at its DEFAULT price. Prices that\ndepend on a request parameter live in ``cost_options``, nested capability\n\u2192 parameter \u2192 value \u2014 ``{\"verify\": {\"depth\": {\"standard\": 10, \"low\": 5}}}``.\nTwo maps rather than a flat one with a ``verify_low`` key, so a future\ntuning parameter nests instead of adding an entry that reads like a fifth\ncapability. Every capability in ``cost_options`` also appears in ``costs``\nat its default, so reading only ``costs`` is always correct.\n\n``extract`` is free at the pool (``costs.extract`` is 0) and is bounded by\na per-account daily fair-use cap instead, reported separately here and\nrejected with 429 rather than 402.", + "description": "Return the calling account's credit balance and what it can still buy.\n\n**``credits`` is the balance.** One pool funds every billable capability,\nat the weights in ``costs`` \u2014 today ``verify`` 10, ``assess`` 1, ``ask`` 1.\nIt has two buckets: the monthly allowance for the current ``plan``, which\nresets at ``resets_at``, and non-expiring ``extra`` credits from grants and\ntop-ups, spent only once the allowance is gone. ``remaining`` is the sum,\nand is what a call is actually checked against.\n\n``credits.bonus`` is the deprecated old name of ``credits.extra``, the same\nnumber, kept for existing callers with the fields below. Read ``extra``.\n\n``plan`` is the stable slug to branch on; ``plan_label`` is the same tier\nas display copy (\"Pro\"). Two fields rather than one humanised\nstring, so a reworded label cannot break a client comparing tiers.\nThe Pro plan's ``plan`` is ``pro``; it read ``developer`` before\n2026-09-15 (#664), while ``plan_label`` already read \"Pro\".\n\n**The per-capability blocks are deprecated.** ``verify`` / ``ask`` /\n``assess`` are **projections** of that one pool into each capability's own\nunit \u2014 \"how many of these could I still make\" \u2014 not separate allowances.\nSpending on one moves all of them, and they are floor divisions, so a\nverify block ticks once per 10 credits spent anywhere.\n\nThey are kept for existing callers, with the per-block ``credits`` alias.\nNew code derives them instead::\n\n remaining = credits.remaining // costs[capability]\n total = credits.total // costs[capability]\n used = total - remaining\n\nTwo capabilities at the same price emit identical blocks \u2014 ``ask`` and\n``assess`` are both 1 credit \u2014 which is the clearest sign the shape\ndescribes an allowance that no longer exists.\n\n``bonus`` in each block is ``credits.extra`` in that capability's unit. The\nolder key ``credits`` is its deprecated alias.\n\n``costs`` is one entry per capability at its DEFAULT price. Prices that\ndepend on a request parameter live in ``cost_options``, nested capability\n\u2192 parameter \u2192 value \u2014 ``{\"verify\": {\"depth\": {\"standard\": 10, \"low\": 5}}}``.\nTwo maps rather than a flat one with a ``verify_low`` key, so a future\ntuning parameter nests instead of adding an entry that reads like a fifth\ncapability. Every capability in ``cost_options`` also appears in ``costs``\nat its default, so reading only ``costs`` is always correct.\n\n``extract`` is free at the pool (``costs.extract`` is 0) and is bounded by\na per-account daily fair-use cap instead, reported separately here and\nrejected with 429 rather than 402.", "tags": [ "Account" ], @@ -2510,7 +2510,7 @@ "type": "object" }, "MeUsageCreditsOut": { - "description": "The account's credit balance \u2014 the one pool every capability spends.\n\nTwo buckets: the monthly allowance for the current plan (resets at\n``resets_at``) and non-expiring ``extra`` credits from grants and top-ups,\nwhich are spent only once the allowance is gone. ``remaining`` is the sum\nand is what a call is checked against.\n\n``bonus`` is a DEPRECATED alias of ``extra`` (the balance's name until\n2026-09-15), removed on 2026-11-29 with the other deprecated fields on this\nendpoint. It was renamed because the balance holds top-ups you paid for as\nwell as grants.", + "description": "The account's credit balance \u2014 the one pool every capability spends.\n\nTwo buckets: the monthly allowance for the current plan (resets at\n``resets_at``) and non-expiring ``extra`` credits from grants and top-ups,\nwhich are spent only once the allowance is gone. ``remaining`` is the sum\nand is what a call is checked against.\n\n``bonus`` is a DEPRECATED alias of ``extra`` (the balance's name until\n2026-09-15), kept for existing callers with the other deprecated fields on\nthis endpoint. It was renamed because the balance holds top-ups you paid for as\nwell as grants.", "properties": { "total": { "default": 0, @@ -2576,7 +2576,7 @@ "type": "object" }, "MeUsageOut": { - "description": "The calling account's credit balance, and what it can still buy.\n\n``credits`` is the balance and ``costs`` is the price list. Those two,\nplus ``cost_options``, are the whole contract for a new integration.\n\nThe ``verify`` / ``ask`` / ``assess`` blocks are DEPRECATED projections of\nthat same pool into each capability's unit, kept until 2026-11-29 for\nclients already reading them.\n\n``extract`` is free at the pool (``costs.extract`` is 0) and carries a\nper-account daily fair-use cap instead; it rejects with 429, not 402.\n\nThe Pro plan's ``plan`` is ``pro`` since 2026-09-15; it was ``developer``\nbefore (#664). ``plan_label`` reads \"Pro\" either way.", + "description": "The calling account's credit balance, and what it can still buy.\n\n``credits`` is the balance and ``costs`` is the price list. Those two,\nplus ``cost_options``, are the whole contract for a new integration.\n\nThe ``verify`` / ``ask`` / ``assess`` blocks are DEPRECATED projections of\nthat same pool into each capability's unit, kept for\nclients already reading them.\n\n``extract`` is free at the pool (``costs.extract`` is 0) and carries a\nper-account daily fair-use cap instead; it rejects with 429, not 402.\n\nThe Pro plan's ``plan`` is ``pro`` since 2026-09-15; it was ``developer``\nbefore (#664). ``plan_label`` reads \"Pro\" either way.", "properties": { "plan": { "default": "free", @@ -2653,7 +2653,7 @@ "type": "object" }, "MeUsageQuotaOut": { - "description": "DEPRECATED. One capability's share of the pool, projected into its unit.\n\n**Removed 2026-11-29**, with the per-block ``credits`` alias below. Read\n``MeUsageOut.credits`` and ``MeUsageOut.costs`` instead and do the\ndivision \u2014 it is one line, and it is the same one this block does::\n\n remaining = credits.remaining // costs[capability]\n total = credits.total // costs[capability]\n used = total - remaining\n\nThese are **projections, not allowances**. Every billable capability draws\non the single balance in ``MeUsageOut.credits``, at the weight in\n``MeUsageOut.costs``; this block answers \"how many ``/verify`` calls could\nI still make if I spent everything on them\". Spending on any capability\nmoves every block, and the division floors \u2014 a ``verify`` block whose\nweight is 10 ticks once per 10 credits spent anywhere.\n\nThey predate the pool, when each really was its own allowance, and that is\nthe reason to retire them: two capabilities at the same price emit\nbyte-identical objects (``ask`` and ``assess`` are both 1 credit today),\nso the shape suggests a per-capability allowance that no longer exists.\n\n``bonus`` is ``MeUsageOut.credits.extra``, the non-expiring balance, in\nthis capability's unit.\n``quota_used`` is derived as ``quota_total - quota_remaining``, so\n``used + remaining == total`` always holds.\n\n``credits`` is a DEPRECATED alias of ``bonus``, kept for compatibility\nuntil 2026-11-29. It never meant the pool \u2014 before the pool existed it\nmeant this capability's one-off top-up balance, which is exactly what\n``bonus`` now reports.", + "description": "DEPRECATED. One capability's share of the pool, projected into its unit.\n\nKept for existing callers, with the per-block ``credits`` alias below. Read\n``MeUsageOut.credits`` and ``MeUsageOut.costs`` instead and do the\ndivision \u2014 it is one line, and it is the same one this block does::\n\n remaining = credits.remaining // costs[capability]\n total = credits.total // costs[capability]\n used = total - remaining\n\nThese are **projections, not allowances**. Every billable capability draws\non the single balance in ``MeUsageOut.credits``, at the weight in\n``MeUsageOut.costs``; this block answers \"how many ``/verify`` calls could\nI still make if I spent everything on them\". Spending on any capability\nmoves every block, and the division floors \u2014 a ``verify`` block whose\nweight is 10 ticks once per 10 credits spent anywhere.\n\nThey predate the pool, when each really was its own allowance, and that is\nthe reason to retire them: two capabilities at the same price emit\nbyte-identical objects (``ask`` and ``assess`` are both 1 credit today),\nso the shape suggests a per-capability allowance that no longer exists.\n\n``bonus`` is ``MeUsageOut.credits.extra``, the non-expiring balance, in\nthis capability's unit.\n``quota_used`` is derived as ``quota_total - quota_remaining``, so\n``used + remaining == total`` always holds.\n\n``credits`` is a DEPRECATED alias of ``bonus``, kept for compatibility\nwith existing callers. It never meant the pool \u2014 before the pool existed it\nmeant this capability's one-off top-up balance, which is exactly what\n``bonus`` now reports.", "properties": { "quota_used": { "default": 0, diff --git a/src/lenz_io/__init__.py b/src/lenz_io/__init__.py index 51c22e2..3fe51ec 100644 --- a/src/lenz_io/__init__.py +++ b/src/lenz_io/__init__.py @@ -18,16 +18,16 @@ # 1. /extract — pull verifiable claims out of text (free, 1000/day) out = client.extract(text=llm_output) - claims = out.identified_claims or [out.claim] + claims = [c.claim for c in out.claims] # 2. /assess — 20 claims a call (extract finds up to 100), one row per claim, same order (paid) quick = [row for i in range(0, len(claims), 20) for row in client.assess(claims=claims[i : i + 20]).claims] - # a row with verdict == "Error" got no verdict: see its error_code and hint; - # a compound item lists the claims it did not assess in identified_claims + # a row with status == "failed" got no verdict: see its failure.code and failure.hint; + # a compound item lists the claims it did not assess in more_claims # 3. /verify — escalate the low-confidence rows to the full pipeline (~90s, paid) # verify_batch_and_wait takes up to 20 claims a call: the first 20 here - doubtful = [{"claim": c.claim} for c in quick if c.verdict != "Error" and c.confidence == "low"][:20] + doubtful = [{"claim": c.claim} for c in quick if c.status == "completed" and c.confidence == "low"][:20] results = client.verify_batch_and_wait(claims=doubtful) if doubtful else [] # 4. /ask — follow-up questions grounded on a verification @@ -74,6 +74,7 @@ AssessClaim, Assessment, AssessResponse, + AssessStatus, Audit, BatchAccepted, BatchItemResult, @@ -89,6 +90,7 @@ EntityRef, Escalation, EscalationPolicy, + ExtractedClaim, ExtractedClaims, ExtractedEntity, ExtractStatus, @@ -144,6 +146,7 @@ "AskReply", "AssessClaim", "AssessResponse", + "AssessStatus", "Assessment", "Audit", "BatchAccepted", @@ -166,6 +169,7 @@ "Escalation", "EscalationPolicy", "ExtractStatus", + "ExtractedClaim", "ExtractedClaims", "ExtractedEntity", "FailureBlock", diff --git a/src/lenz_io/cli/verify.py b/src/lenz_io/cli/verify.py index 0deb9e3..8373375 100644 --- a/src/lenz_io/cli/verify.py +++ b/src/lenz_io/cli/verify.py @@ -393,8 +393,8 @@ def _emit_needs_input(out: Output, task_id: str, st: TaskStatus) -> None: "hint": st.hint, "task_id": task_id, "claims": [c.model_dump(mode="json") for c in st.claims], - # Deprecated compatibility keys, always empty; removal is planned - # for 2026-11-29 with the ``TaskStatus`` fields they mirrored. + # Deprecated compatibility keys, always empty; kept, like the + # ``TaskStatus`` fields they mirror. "candidates": [], "similar": [], } diff --git a/src/lenz_io/client.py b/src/lenz_io/client.py index b496e3b..999648f 100644 --- a/src/lenz_io/client.py +++ b/src/lenz_io/client.py @@ -201,8 +201,13 @@ def _batch_item_body(item: Any) -> Any: An item without ``claim`` is forwarded verbatim, so every existing caller keeps a byte-identical request body. An item with ``claim`` is sent as - ``text`` — the wire key the server has always accepted. + ``text`` — the wire key the server has always accepted. An empty + ``webhook_url`` is left out, as on the batch itself: it has always meant + the key's default, and leaving it out keeps that meaning on every API + version. """ + if isinstance(item, dict) and item.get("webhook_url") == "": + item = {k: v for k, v in item.items() if k != "webhook_url"} if "claim" not in item: return item body = {k: v for k, v in item.items() if k != "claim"} @@ -210,6 +215,18 @@ def _batch_item_body(item: Any) -> Any: return body +def _extracted(body: Any, *, locate: bool | None) -> ExtractedClaims: + """``/extract``'s answer. A newer-shape body (``claims``, no + ``identified_claims``) that located every claim away answers ``claims: + []``; the original field for that was ``locations=[]``, which only the + request (``locate=True``) can tell apart from "nothing found".""" + out = ExtractedClaims.model_validate(body) + newer = isinstance(body, dict) and "claims" in body and "identified_claims" not in body + if newer and locate and not body["claims"] and out.status == "not_a_claim" and out.locations is None: + out.locations = [] + return out + + #: An async job the poll loop waits on: a review or a citation check. _Job = TypeVar("_Job", ReviewFull, Citecheck) @@ -659,18 +676,18 @@ def extract( one an unfocused call would have returned too, verbatim. When the text has claims but none fall within the focus, ``status`` - is ``"no_match"`` and ``identified_claims`` is empty — the unfocused + is ``"no_match"`` and ``claims`` is empty — the unfocused list is never substituted. Widen the focus and call again. A focused call costs the same single unit of the daily cap. ``locate`` (optional): with ``True``, only the claims that could be - traced directly back to the text are returned, and ``locations`` - says where the text makes each one (``start``/``end`` index the + traced directly back to the text are returned, and each claim's + ``positions`` says where the text makes it (``start``/``end`` index the ``text`` you sent, in code points, so ``text[start:end]`` is the passage). A claim found nowhere in the text, or found with a different figure, is left out; if that leaves no claim, ``status`` is ``"not_a_claim"``. Locating adds a few seconds. If the claims - cannot be located, ``locations`` is ``None`` and the list is returned + cannot be located, ``positions`` is ``None`` and the list is returned unfiltered. Leave it ``None`` to use the server default (currently off); an explicit ``False`` is sent as such. @@ -720,7 +737,7 @@ def assess( ``extract`` in the ladder:: out = client.extract(text=llm_output) - claims = out.identified_claims or [out.claim] + claims = [c.claim for c in out.claims] quick = [row for i in range(0, len(claims), 20) # 20 a call for row in client.assess(claims=claims[i : i + 20]).claims] @@ -733,14 +750,16 @@ def assess( ``verification_url`` pointing at the deep ``Verification`` when /assess found a matching stored claim. - A row with ``verdict == "Error"`` could not be given a verdict. It - stays in position, is not charged, and says why: ``error_code`` is - ``no_claim`` / ``framing_failed`` / ``upstream_unavailable`` / - ``timeout`` (an open set; the last two are worth resending as-is), and - ``hint`` is one sentence on what to send next. A compound list item is assessed on its main - claim; the other claims found in it are listed on that row in - ``identified_claims`` (with a ``hint``) — send them as their own - items to check the rest. ``hint`` is ``None`` on a plain verdict row. + A row with ``status == "failed"`` could not be given a verdict (its + ``verdict`` reads ``"Error"``). It stays in position, is not charged, + and says why: ``failure.code`` is ``no_checkable_claim`` / + ``framing_failed`` / ``upstream_unavailable`` / ``timeout`` (an open + set; the last two are worth resending as-is), and ``failure.hint`` is + one sentence on what to send next. A compound list item is assessed on + its main claim; the other claims found in it are listed on that row in + ``more_claims`` — send them as their own items to check the rest. + (The deprecated ``error_code``, ``hint`` and ``identified_claims`` keep + their original meaning.) Use ``confidence`` to decide when to escalate: ``"low"`` rows are worth re-running through ``verify_batch_and_wait`` for the deep @@ -1564,8 +1583,12 @@ def _verify_submit( payload: dict[str, Any] = { "text": claim or text, "source_url": source_url, - "webhook_url": webhook_url, } + # Omit-when-empty: no ``webhook_url`` means the key's default webhook. + # An empty string is never sent, so a request keeps that meaning on + # every API version (a newer one reads ``""`` as "no webhook"). + if webhook_url: + payload["webhook_url"] = webhook_url # Omit-when-empty so existing English callers keep byte-identical # request bodies (no extra "language": "" key). if language: @@ -1598,7 +1621,10 @@ def _verify_batch( # ``VerifyBatchItem`` TypedDict is purely for IDE autocompletion # (revised SDK plan decision 1C — no Pydantic coercion, keep the # runtime contract a plain dict). - payload: dict[str, Any] = {"claims": [_batch_item_body(c) for c in claims], "webhook_url": webhook_url} + payload: dict[str, Any] = {"claims": [_batch_item_body(c) for c in claims]} + # Omit-when-empty, as on ``verify``: no ``webhook_url`` means the key's default. + if webhook_url: + payload["webhook_url"] = webhook_url if language: payload["language"] = language if visibility: @@ -1652,7 +1678,7 @@ def _extract( if idempotency_key: headers["Idempotency-Key"] = idempotency_key body = self._request("POST", "/extract", json=payload, timeout=timeout, headers=headers) - return ExtractedClaims.model_validate(body) + return _extracted(body, locate=locate) def _assess( self, diff --git a/src/lenz_io/errors.py b/src/lenz_io/errors.py index 07662e4..2f6579e 100644 --- a/src/lenz_io/errors.py +++ b/src/lenz_io/errors.py @@ -192,7 +192,9 @@ class LenzValidationError(LenzError): """422 — request body failed schema validation. ``errors`` is a list of per-field error dicts as returned by Ninja: - ``[{"loc": [...], "msg": "...", "type": "..."}]``. + ``[{"loc": [...], "msg": "...", "type": "..."}]``, read from the body's + ``detail`` list (the original response shape) or its ``errors`` list + (the newer one, where ``detail`` is a sentence and becomes the message). """ errors: list[dict[str, Any]] = [] # noqa: RUF012 — overridden per-instance @@ -202,7 +204,8 @@ class LenzRateLimitError(LenzError): """429 — rate limited. * ``retry_after`` — seconds until the next allowed call, resolved - from the ``Retry-After`` header or the body's ``reset_in_seconds``. + from the ``Retry-After`` header or the body's ``reset_in_seconds`` / + ``retry_after``. * ``limit`` — the cap that was hit, when the server states it. * ``reset_in_seconds`` — the body's raw echo of the same wait. @@ -431,6 +434,10 @@ class LenzWebhookSignatureError(LenzError): # inside a submit would block the caller, most likely into the same answer. NO_RETRY_429_CODES = ("review_in_flight",) +# The 429s that refuse a submit while the account's earlier ones run. They +# stated their wait as ``retry_after_seconds``, never ``reset_in_seconds``. +_IN_FLIGHT_429_CODES = ("review_in_flight", "citecheck_in_flight") + _STATUS_MAP: dict[int, tuple[type[LenzError], str, str]] = { 401: ( LenzAuthError, @@ -561,18 +568,30 @@ def map_response_to_error( if status_code == 409 and isinstance(err, (LenzVerificationNotReadyError, LenzPipelineError)): # The generic 4xx advice ("retry; file an issue") is wrong for both: # the server's own hint says what to do, with a class default behind it. + # A failed run states its cause flat in the original response shape + # and in one ``failure`` block in the newer one. The block is read only + # for a newer-shape body, and only where the flat key is absent. + raw_failure = parsed.get("failure") + newer = isinstance(raw_failure, dict) and "failure_reason" not in parsed + failure: dict[str, Any] = raw_failure if newer and isinstance(raw_failure, dict) else {} + + def _read(key: str, block_key: str) -> Any: + return parsed[key] if key in parsed else failure.get(block_key) + err.task_id = _opt_str(parsed.get("task_id")) - err.hint = _opt_str(parsed.get("hint")) + err.hint = _opt_str(_read("hint", "hint")) if isinstance(err, LenzVerificationNotReadyError): err.status = _opt_str(parsed.get("status")) err.fix = err.hint or "Wait for the run with client.wait(task_id), then read its result." else: - err.failure_reason = _opt_str(parsed.get("failure_reason")) - err.failure_class = _opt_str(parsed.get("failure_class")) + reason = _opt_str(_read("failure_reason", "code")) + # The original spelling of "nothing checkable" on a verification. + err.failure_reason = "not_a_claim" if newer and reason == "no_checkable_claim" else reason + err.failure_class = _opt_str(_read("failure_class", "failure_class")) # Only a real boolean is a retry signal, as in the wait path. - retryable = parsed.get("retryable") + retryable = _read("retryable", "retryable") err.retryable = retryable if isinstance(retryable, bool) else None - err.doc_url = _opt_str(parsed.get("docs_url")) or err.doc_url + err.doc_url = _opt_str(_read("docs_url", "docs_url")) or err.doc_url if err.hint: err.fix = err.hint elif err.retryable: @@ -609,6 +628,12 @@ def map_response_to_error( # sending null precisely so "unknown" stays distinguishable from # "zero". Collapsing that here would throw the distinction away. err.remaining = _opt_int(parsed.get("remaining")) + if "remaining" not in parsed and "requested" not in parsed and "doc_url" not in parsed and "docs_url" in parsed: + # A newer-shape body (``docs_url``) without the capability figure: + # the pool divided by this one call's price. + pool, price = _opt_int(parsed.get("credits_remaining")), _opt_int(parsed.get("cost")) + if pool is not None and price: + err.remaining = pool // price err.requested = _opt_int(parsed.get("requested")) # The pool behind the capability figure above, and this call's price in # credits. The body's ``credits_remaining`` lands on ``credit_balance``, @@ -630,6 +655,18 @@ def map_response_to_error( elif isinstance(err, LenzRateLimitError): err.limit = _opt_int(parsed.get("limit")) err.reset_in_seconds = _opt_int(parsed.get("reset_in_seconds")) + if ( + "reset_in_seconds" not in parsed + and "retry_after_seconds" not in parsed + and "retry_after" in parsed + and "docs_url" in parsed + and "doc_url" not in parsed + and code not in _IN_FLIGHT_429_CODES + ): + # A newer-shape body (``docs_url``) names every wait + # ``retry_after``. The in-flight refusals never carried + # ``reset_in_seconds``. + err.reset_in_seconds = _opt_int(parsed.get("retry_after")) rl_upgrade_url = parsed.get("upgrade_url") err.upgrade_url = rl_upgrade_url if isinstance(rl_upgrade_url, str) else "" # Header first, then the body. `reset_in_seconds` is what the server diff --git a/src/lenz_io/models.py b/src/lenz_io/models.py index 335d52f..c9fc1a9 100644 --- a/src/lenz_io/models.py +++ b/src/lenz_io/models.py @@ -19,6 +19,7 @@ from __future__ import annotations from collections.abc import ItemsView, KeysView, ValuesView +from datetime import datetime, timezone from typing import Any, Literal from pydantic import BaseModel, ConfigDict, Field, model_validator @@ -36,6 +37,90 @@ class _Lax(BaseModel): model_config = ConfigDict(extra="allow") +# ── Reading both response shapes ───────────────────────────────────────── +# +# The API is gaining a second, dated response shape that renames a handful of +# fields (``claim_text`` -> ``claim``, ``modified_at`` -> ``completed_at``, a +# failed item's ``error`` / ``error_code`` / ``failure_reason`` -> one +# ``failure`` block, ...). This release still asks for the original shape. +# +# Two rules keep existing code exactly as it was: +# +# * A body is treated as the newer shape only when it carries something only +# that shape has. Every other body is parsed exactly as before: same fields, +# same values, same dump, same ``exclude_unset``. +# * A newer-shape body gets the original fields filled in, with their original +# meaning, from the newer ones (only where the body does not carry them). +# +# The newer names are read-only properties, computed from either shape: they +# are not model fields, so ``repr``, ``model_dump()``, equality and pickling of +# an original-shape object are unchanged. + +#: The one code for "the input holds nothing that can be checked", in the +#: newer response shape. The original shape spells it per endpoint: +#: ``not_a_claim`` (/extract, /verify) and ``no_claim`` (/assess, /review). +NO_CHECKABLE_CLAIM = "no_checkable_claim" +_OLD_NO_CLAIM_CODES = ("not_a_claim", "no_claim") + + +def _new_code(code: Any) -> Any: + """An old per-endpoint spelling of "nothing checkable" -> the one new code.""" + return NO_CHECKABLE_CLAIM if code in _OLD_NO_CLAIM_CODES else code + + +def _old_code(code: Any, old: str) -> Any: + """The new code -> the spelling ``old`` this field always carried.""" + return old if code in (NO_CHECKABLE_CLAIM, *_OLD_NO_CLAIM_CODES) else code + + +def _is_newer(data: Any, has: str, lacks: str) -> bool: + """A dict carrying ``has`` (a key only the newer shape sends) and not + ``lacks`` (its original-shape counterpart).""" + return isinstance(data, dict) and has in data and lacks not in data + + +def _utc_day(iso: Any) -> Any: + """The UTC calendar day of an ISO-8601 string, or ``None``.""" + if not isinstance(iso, str) or not iso: + return None + try: + when = datetime.fromisoformat(iso.replace("Z", "+00:00")) + except ValueError: + return None + if when.tzinfo is None: + when = when.replace(tzinfo=timezone.utc) + return when.astimezone(timezone.utc).date() + + +def _modified_at_from(created_at: Any, completed_at: Any) -> str | None: + """The original ``modified_at`` rule: the completion time when it falls on a + later UTC calendar day than the creation time, else ``None``.""" + created, completed = _utc_day(created_at), _utc_day(completed_at) + if created is None or completed is None or completed <= created: + return None + return str(completed_at) + + +def _fill_modified_at(data: Any) -> Any: + """A newer-shape verification (``completed_at``, no ``modified_at``): + add the original ``modified_at``.""" + if _is_newer(data, "completed_at", "modified_at"): + return {**data, "modified_at": _modified_at_from(data.get("created_at"), data.get("completed_at"))} + return data + + +def _fill(data: dict[str, Any], **values: Any) -> dict[str, Any]: + """``data`` with each of ``values`` added where the key is missing.""" + return {**{k: v for k, v in values.items() if k not in data}, **data} + + +def _sent(model: BaseModel, key: str) -> Any: + """The value the server sent under ``key`` when it is not a field of this + release's model (a newer-shape key), else ``None``.""" + extra = model.__pydantic_extra__ or {} + return extra.get(key) + + #: Closed set of failure causes on a ``failed`` verification, mirroring the #: Node SDK's ``FailureClass`` union. Exported for callers who want exhaustive #: matching: @@ -117,6 +202,19 @@ class CandidateClaim(_Lax): text: str = "" domain: str = "" + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + if _is_newer(data, "claim", "text"): + return _fill(data, text=data["claim"]) + return data + + @property + def claim(self) -> str: + """The option's claim (``text`` is its older name, the same string).""" + sent = _sent(self, "claim") + return sent if isinstance(sent, str) else self.text + class EntityRef(_Lax): """An entity referenced in the claim. @@ -301,6 +399,19 @@ class Verification(_Lax): #: reasons why. coverage: Coverage | None = None + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + return _fill_modified_at(data) + + @property + def completed_at(self) -> str | None: + """When the verification completed. From the original response shape it + is known only through ``modified_at``: set when that is, ``None`` on a + same-day completion.""" + sent = _sent(self, "completed_at") + return sent if isinstance(sent, str) else self.modified_at + class VerificationListItem(_Lax): """Compact item for the verifications list endpoint and the public @@ -325,6 +436,19 @@ class VerificationListItem(_Lax): # Output language (ISO 639-1). See ``Verification.language``. language: str = "en" + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + return _fill_modified_at(data) + + @property + def completed_at(self) -> str | None: + """When the verification completed. From the original response shape it + is known only through ``modified_at``: set when that is, ``None`` on a + same-day completion.""" + sent = _sent(self, "completed_at") + return sent if isinstance(sent, str) else self.modified_at + class VerificationList(_Lax): items: list[VerificationListItem] = Field(default_factory=list) @@ -415,6 +539,12 @@ class ClaimLocation(_Lax): ] +class ExtractedClaim(ClaimLocation): + """One claim ``/extract`` found: ``claim``, and with ``locate=True`` its + ``positions`` in the text (``None`` when the call did not locate, or the + claims could not be located). Returned by ``ExtractedClaims.claims``.""" + + class ExtractedClaims(_Lax): """Output of ``POST /extract``. @@ -445,6 +575,42 @@ class ExtractedClaims(_Lax): original_input: str = "" locations: list[ClaimLocation] | None = None + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + if not (_is_newer(data, "claims", "identified_claims") and isinstance(data["claims"], list)): + return data + items = [c for c in data["claims"] if isinstance(c, dict)] + names = [c.get("claim") if isinstance(c.get("claim"), str) else "" for c in items] + located = bool(items) and all(c.get("positions") is not None for c in items) + out = _fill( + data, + claim=names[0] if names else "", + identified_claims=names if len(names) > 1 else [], + locations=[{"claim": n, "positions": c.get("positions")} for n, c in zip(names, items, strict=True)] + if located + else None, + ) + if out.get("status") == NO_CHECKABLE_CLAIM: + out["status"] = "not_a_claim" + return out + + @property + def claims(self) -> list[ExtractedClaim]: + """Every claim found, most check-worthy first: always a list (one entry + for one claim, ``[]`` for none), each with its ``positions`` when the + call located them. Read from either response shape.""" + sent = _sent(self, "claims") + if isinstance(sent, list): + return [ExtractedClaim.model_validate(c) for c in sent if isinstance(c, dict)] + names = list(self.identified_claims) or ([self.claim] if self.claim else []) + if self.claim and self.claim not in names: + names.insert(0, self.claim) + positions: dict[str, Any] = {} + for loc in self.locations or []: + positions.setdefault(loc.claim, loc.positions) + return [ExtractedClaim(claim=n, positions=positions.get(n)) for n in names] + class AssessClaim(_Lax): """Per-claim entry in an ``AssessResponse.claims`` list. @@ -512,6 +678,64 @@ class AssessClaim(_Lax): # with a non-empty ``identified_claims``; ``None`` on a plain verdict row. hint: str | None = None + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + if not _is_newer(data, "failure", "error_code"): + return data + out = dict(data) + failed = out.get("status") == "failed" + if out.get("verdict") is None: + out["verdict"] = "Error" if failed else "" + if out.get("confidence") is None: + out["confidence"] = "low" + failure = out.get("failure") if isinstance(out.get("failure"), dict) else {} + return _fill( + out, + error_code=_old_code(failure.get("code"), "no_claim") if failure else None, + hint=failure.get("hint") if failure else None, + identified_claims=out.get("more_claims") or [], + ) + + @property + def status(self) -> str: + """``"completed"`` (a verdict) or ``"failed"`` (none; see ``failure``).""" + sent = _sent(self, "status") + if isinstance(sent, str): + return sent + if self.verdict == "Error": + return "failed" + return "completed" if self.verdict else "" + + @property + def failure(self) -> FailureBlock | None: + """Why a failed row has no verdict (``None`` on a completed row): + ``code`` (``no_checkable_claim`` | ``framing_failed`` | + ``upstream_unavailable`` | ``timeout`` today, an open set) and ``hint``, + one sentence on what to send next.""" + sent = _sent(self, "failure") + if isinstance(sent, dict): + return FailureBlock.model_validate(sent) + if self.status != "failed": + return None + return FailureBlock(failure_reason=self.error_code or "", hint=self.hint) + + @property + def more_claims(self) -> list[str]: + """Other claims found in the input that were not assessed.""" + sent = _sent(self, "more_claims") + return list(sent) if isinstance(sent, list) else list(self.identified_claims) + + +#: The ``AssessResponse.status`` values this release knows about. A +#: documentation constant, like ``ExtractStatus``: the attribute is a ``str``. +#: +#: - ``ok`` — at least one row has a verdict (a list may mix in failed rows). +#: - ``no_checkable_claim`` — the input, or every item, holds nothing that +#: can be checked. +#: - ``error`` — no row has a verdict, for another reason (see the rows). +AssessStatus = Literal["ok", "no_checkable_claim", "error"] + class AssessResponse(_Lax): """Output of ``POST /assess``. @@ -544,6 +768,46 @@ class AssessResponse(_Lax): # first; ``[]`` otherwise, on the list form, and from older servers. more_claims: list[str] = Field(default_factory=list) + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + if not _is_newer(data, "failure", "error"): + return data + failure = data.get("failure") if isinstance(data.get("failure"), dict) else None + if failure is None: + return data + return _fill( + data, + error=failure.get("detail"), + error_code=_old_code(failure.get("code"), "no_claim") or "", + ) + + @property + def status(self) -> str: + """``ok`` (some row has a verdict), ``no_checkable_claim`` (the input, + or every item, holds nothing checkable) or ``error``. See + ``AssessStatus``; computed from the rows when a server does not send it.""" + sent = _sent(self, "status") + if isinstance(sent, str): + return sent + rows = self.claims + if any(r.status == "completed" for r in rows): + return "ok" + if not rows: + return NO_CHECKABLE_CLAIM if _new_code(self.error_code) == NO_CHECKABLE_CLAIM else "error" + codes = {r.failure.code if r.failure else None for r in rows} + return NO_CHECKABLE_CLAIM if codes == {NO_CHECKABLE_CLAIM} else "error" + + @property + def failure(self) -> FailureBlock | None: + """Why the single form has no rows; ``None`` otherwise.""" + sent = _sent(self, "failure") + if isinstance(sent, dict): + return FailureBlock.model_validate(sent) + if not (self.error or self.error_code): + return None + return FailureBlock.model_validate({"failure_reason": self.error_code, "detail": self.error}) + class TaskAccepted(_Lax): """Returned by ``POST /verify`` and per item of ``POST /verify/batch``.""" @@ -551,6 +815,20 @@ class TaskAccepted(_Lax): task_id: str = "" claim_text: str = "" + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + if _is_newer(data, "claim", "claim_text"): + return _fill(data, claim_text=data["claim"]) + return data + + @property + def claim(self) -> str: + """The item's claim on a batch or select receipt (``""`` on a single + ``verify`` receipt); ``claim_text`` is its older name.""" + sent = _sent(self, "claim") + return sent if isinstance(sent, str) else self.claim_text + class BatchAccepted(_Lax): batch_id: str = "" @@ -639,7 +917,7 @@ class TaskStatus(_Lax): claims: list[CandidateClaim] = Field(default_factory=list) # Deprecated, both always empty: the API no longer sends them, and # ``reason`` is only ever ``multi_claim``. Kept so code that reads them - # keeps working; removal is planned for 2026-11-29. Marked deprecated in + # keeps working; they are deprecated and kept. Marked deprecated in # the JSON schema only, so reading them does not warn. candidates: list[str] = Field(default_factory=list, json_schema_extra={"deprecated": True}) similar_claims: list[SimilarVerification] = Field(default_factory=list, json_schema_extra={"deprecated": True}) @@ -662,6 +940,45 @@ class TaskStatus(_Lax): # Where this ``failure_class`` is explained. ``""`` from older servers. docs_url: str = "" + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + if not _is_newer(data, "failure", "failure_reason") or not isinstance(data["failure"], dict): + return data + failure = data["failure"] + values = { + "error": failure.get("detail"), + "failure_reason": _old_code(failure.get("code"), "not_a_claim"), + "failure_class": failure.get("failure_class"), + "retryable": failure.get("retryable"), + "docs_url": failure.get("docs_url"), + "hint": failure.get("hint"), + } + # ``None`` reads as the original field's empty value. + return _fill(data, **{k: ("" if v is None and k != "retryable" else v) for k, v in values.items()}) + + @property + def failure(self) -> FailureBlock | None: + """On ``failed``: why. ``code`` is the cause (an open set, e.g. + ``research_empty``, ``no_checkable_claim``), ``detail`` one sentence on + what happened, ``failure_class`` / ``retryable`` / ``hint`` / + ``docs_url`` as on the original fields. ``None`` on other statuses.""" + sent = _sent(self, "failure") + if isinstance(sent, dict): + return FailureBlock.model_validate(sent) + if self.status != "failed": + return None + return FailureBlock.model_validate( + { + "failure_reason": self.failure_reason, + "detail": self.error or self.failure_detail or None, + "failure_class": self.failure_class, + "retryable": self.retryable, + "hint": self.hint or None, + "docs_url": self.docs_url, + } + ) + class BatchItemResult(_Lax): """Per-item outcome from :meth:`Lenz.verify_batch_and_wait`. @@ -685,6 +1002,11 @@ class BatchItemResult(_Lax): verification: Verification | None = None status_detail: TaskStatus | None = None + @property + def claim(self) -> str: + """The item's claim (``claim_text`` is its older name).""" + return self.claim_text + class UsageCredits(_Lax): """The account's credit balance — the one pool every capability spends. @@ -696,7 +1018,7 @@ class UsageCredits(_Lax): resets at ``resets_at``, and non-expiring ``extra`` credits from grants and top-ups, spent only once the allowance is gone. ``remaining`` covers both and is what a call is checked against. ``bonus`` is the deprecated old - name of ``extra``, the same number, removed on 2026-11-29. + name of ``extra``, the same number, kept for existing code. Servers predating the credit pool (before 2026-08-29) don't send this block at all, and it then reads as all-zero — check ``usage.credits.total`` @@ -709,14 +1031,13 @@ class UsageCredits(_Lax): #: The non-expiring part of ``remaining``: credits from grants and top-ups, #: spent only once the monthly allowance is gone. extra: int = 0 - #: **Deprecated** old name of :attr:`extra`, the same number, removed on - #: 2026-11-29. Reading it emits a ``DeprecationWarning``; it stays in + #: **Deprecated** old name of :attr:`extra`, the same number, kept for + #: existing code. Reading it emits a ``DeprecationWarning``; it stays in #: ``model_dump()`` output (unwarned) for as long as the server sends it. bonus: int = Field( default=0, deprecated=( - "UsageCredits.bonus is deprecated and will be removed on 2026-11-29; " - "use `extra` — the same number, the non-expiring part of the balance." + "UsageCredits.bonus is deprecated; use `extra` — the same number, the non-expiring part of the balance." ), ) resets_at: str | None = None @@ -727,7 +1048,7 @@ def _mirror_extra_and_bonus(cls, data: Any) -> Any: """Keep ``extra`` and its deprecated old name in step, in both directions. A server that has not started sending ``extra`` sends only ``bonus``; - a server after the 2026-11-29 removal sends only ``extra``. Mirroring + the newer response shape sends only ``extra``. Mirroring here means both attributes read correctly either way. """ if not isinstance(data, dict): @@ -743,8 +1064,9 @@ def _mirror_extra_and_bonus(cls, data: Any) -> Any: class UsageCapacity(_Lax): """DEPRECATED. One capability's share of the pool, in that capability's unit. - **Removed 2026-11-29**, together with the per-block ``credits`` alias. - Read :attr:`Usage.credits` and :attr:`Usage.costs` and do the division — + Deprecated, together with the per-block ``credits`` alias, and kept for + existing code (computed from the pool when a response leaves the block + out). Read :attr:`Usage.credits` and :attr:`Usage.costs` and do the division — it is the same one this block does:: remaining = u.credits.remaining // u.costs[capability] @@ -778,7 +1100,7 @@ class UsageCapacity(_Lax): quota_total: int = 0 quota_remaining: int = 0 bonus: int = 0 - #: **Deprecated** alias of :attr:`bonus`, removed on 2026-11-29. It never + #: **Deprecated** alias of :attr:`bonus`, kept for existing code. It never #: meant the credit pool — before the pool existed it meant this #: capability's one-off top-up balance, which is exactly what ``bonus`` #: reports. Reading it emits a ``DeprecationWarning``; it stays in @@ -786,7 +1108,7 @@ class UsageCapacity(_Lax): credits: int = Field( default=0, deprecated=( - "UsageCapacity.credits is deprecated and will be removed on 2026-11-29; " + "UsageCapacity.credits is deprecated; " "use `bonus` — the same number, this capability's non-expiring top-up " "balance. The credit pool itself is `Usage.credits`." ), @@ -798,8 +1120,8 @@ class UsageCapacity(_Lax): def _mirror_bonus_and_credits(cls, data: Any) -> Any: """Keep ``bonus`` and its deprecated alias in step, in both directions. - A server predating the credit pool sends only ``credits``; a server - after the 2026-11-29 removal sends only ``bonus``. Mirroring here means + A server predating the credit pool sends only ``credits``; a block + computed from the pool has only ``bonus``. Mirroring here means both attributes read correctly either way, so the SDK never depends on which side of an API deploy it is talking to. """ @@ -886,14 +1208,14 @@ class Usage(_Lax): #: read ``standard`` on a ``low`` request — the echo describes the #: evidence, the charge follows the request. cost_options: dict[str, dict[str, dict[str, int]]] = Field(default_factory=dict) - #: DEPRECATED — removed 2026-11-29. Derive from :attr:`credits` and + #: DEPRECATED, kept for existing code. Derive from :attr:`credits` and #: :attr:`costs` instead:: #: #: left = u.credits.remaining // u.costs["verify"] verify: UsageCapacity = Field(default_factory=UsageCapacity) - #: DEPRECATED — removed 2026-11-29. See :attr:`verify`. + #: DEPRECATED, kept for existing code. See :attr:`verify`. ask: UsageCapacity = Field(default_factory=UsageCapacity) - #: DEPRECATED — removed 2026-11-29. See :attr:`verify`. + #: DEPRECATED, kept for existing code. See :attr:`verify`. assess: UsageCapacity = Field(default_factory=UsageCapacity) extract: UsageExtract = Field(default_factory=UsageExtract) # Whether this key has a webhook signing secret provisioned. ``POST /verify`` @@ -903,6 +1225,39 @@ class Usage(_Lax): # Defaults to ``False`` on servers predating this field. has_webhook_secret: bool = False + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + """The newer shape sends the pool and the prices but not the + deprecated per-capability blocks: compute them exactly as the server + did, and ``quota_resets_at`` from ``credits.resets_at``.""" + if not (isinstance(data, dict) and isinstance(data.get("credits"), dict)): + return data + if any(k in data for k in ("verify", "ask", "assess", "quota_resets_at")): + return data + credits, costs = data["credits"], data.get("costs") + + def _int(value: Any) -> int: + return value if isinstance(value, int) and not isinstance(value, bool) else 0 + + out = _fill(data, quota_resets_at=credits.get("resets_at")) + if not isinstance(costs, dict): + return out + total, remaining = _int(credits.get("total")), _int(credits.get("remaining")) + extra = _int(credits.get("extra", credits.get("bonus"))) + for capability in ("verify", "ask", "assess"): + cost = _int(costs.get(capability)) + if cost > 0: + quota_total, left = total // cost, remaining // cost + out[capability] = { + "quota_used": quota_total - left, + "quota_total": quota_total, + "quota_remaining": left, + "bonus": extra // cost, + "remaining": left, + } + return out + class AskMessage(_Lax): """One message in an ``/ask`` conversation thread.""" @@ -987,6 +1342,27 @@ class is explained. hint: str | None = None docs_url: str | None = "" + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + if _is_newer(data, "code", "failure_reason"): + return _fill(data, failure_reason=_old_code(data["code"], "no_claim")) + return data + + @property + def code(self) -> str | None: + """The cause, an open set (``no_checkable_claim``, ``timeout``, ...). + ``failure_reason`` is its older name, spelling "nothing checkable" + ``no_claim``.""" + sent = _sent(self, "code") + return sent if isinstance(sent, str) else _new_code(self.failure_reason) + + @property + def detail(self) -> str | None: + """One sentence on what happened; ``None`` from the original shape.""" + sent = _sent(self, "detail") + return sent if isinstance(sent, str) else None + class EscalationPolicy(_Lax): """Which quick-checked claims get a deep check, as the review RESOLVED it. @@ -1081,6 +1457,36 @@ class ReviewSummary(_Lax): #: An open set. citations_skipped: str | None = None + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + if not _is_newer(data, "claim_limit_exceeded", "claim_limit_reached"): + return data + found, limit = data.get("claims_found"), data.get("claim_limit", 20) + reached = found >= limit if isinstance(found, int) and isinstance(limit, int) else None + return _fill(data, claim_limit_reached=reached, citation_limit_reached=data.get("citation_limit_exceeded")) + + @property + def claims_found(self) -> int | None: + """How many claims the draft holds; ``None`` until read, and from the + original response shape, which does not send it.""" + sent = _sent(self, "claims_found") + return sent if isinstance(sent, int) else None + + @property + def claim_limit_exceeded(self) -> bool | None: + """Some of the draft's claims were left out (they are in + ``more_claims``). ``None`` from the original response shape, which + says only that the limit was reached: read ``more_claims`` there.""" + sent = _sent(self, "claim_limit_exceeded") + return sent if isinstance(sent, bool) else None + + @property + def citation_limit_exceeded(self) -> bool | None: + """``citations_found`` is over ``citation_limit``: some were left out.""" + sent = _sent(self, "citation_limit_exceeded") + return sent if isinstance(sent, bool) else self.citation_limit_reached + class ReviewCredits(_Lax): """``charged`` is the net credits the review cost the account, its @@ -1124,6 +1530,24 @@ class ReviewAssessment(_Lax): suggested_rewrite: str | None = None failure: FailureBlock | None = None + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + if not _is_newer(data, "more_claims", "identified_claims"): + return data + failure = data.get("failure") if isinstance(data.get("failure"), dict) else {} + return _fill( + data, + identified_claims=data.get("more_claims") or [], + error_code=_old_code(failure.get("code"), "no_claim") if failure else None, + ) + + @property + def more_claims(self) -> list[str]: + """Other claims found in the passage that were not checked.""" + sent = _sent(self, "more_claims") + return list(sent) if isinstance(sent, list) else list(self.identified_claims) + class ReviewEntity(_Lax): """An entity the deep check found in the claim. ``qid`` is its Wikidata @@ -1169,6 +1593,19 @@ class ReviewVerification(_Lax): url: str | None = None failure: FailureBlock | None = None + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + return _fill_modified_at(data) + + @property + def completed_at(self) -> str | None: + """When the verification completed. From the original response shape it + is known only through ``modified_at``: set when that is, ``None`` on a + same-day completion.""" + sent = _sent(self, "completed_at") + return sent if isinstance(sent, str) else self.modified_at + class SuggestedEdit(_Lax): """One replacement in the draft: the span ``start``..``end`` of the @@ -1473,6 +1910,19 @@ class CitecheckSummary(_Lax): citation_checks: ReviewCitationCheckCounts | None = None citation_issues: int = 0 + @model_validator(mode="before") + @classmethod + def _read_newer_shape(cls, data: Any) -> Any: + if _is_newer(data, "citation_limit_exceeded", "citation_limit_reached"): + return _fill(data, citation_limit_reached=data["citation_limit_exceeded"]) + return data + + @property + def citation_limit_exceeded(self) -> bool | None: + """``citations_found`` is over ``citation_limit``: some were left out.""" + sent = _sent(self, "citation_limit_exceeded") + return sent if isinstance(sent, bool) else self.citation_limit_reached + class Citecheck(_Lax): """``GET /citechecks/{citecheck_id}``: a citation check as it stands. @@ -1564,11 +2014,13 @@ class ReviewIssues(ReviewEnvelope): __all__ = [ + "NO_CHECKABLE_CLAIM", "AskHistory", "AskMessage", "AskReply", "AssessClaim", "AssessResponse", + "AssessStatus", "Assessment", "Audit", "BatchAccepted", @@ -1584,6 +2036,7 @@ class ReviewIssues(ReviewEnvelope): "Escalation", "EscalationPolicy", "ExtractStatus", + "ExtractedClaim", "ExtractedClaims", "ExtractedEntity", "FailureBlock", diff --git a/src/lenz_io/webhooks.py b/src/lenz_io/webhooks.py index 89eb1d9..8d6bb54 100644 --- a/src/lenz_io/webhooks.py +++ b/src/lenz_io/webhooks.py @@ -34,8 +34,17 @@ from datetime import datetime, timezone from typing import Any +from pydantic import ValidationError + from .errors import LenzWebhookSignatureError -from .models import Citecheck, ReviewFull +from .models import ( + CandidateClaim, + Citecheck, + FailureBlock, + ReviewFull, + _fill_modified_at, + _old_code, +) SIGNATURE_HEADER = "X-Lenz-Signature" SIGNATURE_PREFIX = "sha256=" @@ -102,6 +111,14 @@ class WebhookEvent: status: str = "" raw: dict[str, Any] = field(default_factory=dict, repr=False) + @property + def event_id(self) -> str: + """The same on every delivery attempt of one event: deduplicate on it. + ``""`` when the payload carries none (the original ``verification.*`` + and ``certificate.*`` payloads).""" + value = self.raw.get("event_id") + return value if isinstance(value, str) else "" + @dataclass class VerificationCompleted(WebhookEvent): @@ -124,6 +141,24 @@ class VerificationFailed(WebhookEvent): failure_class: str = "" retryable: bool | None = None + @property + def failure(self) -> FailureBlock | None: + """Why the run failed, from either payload shape: ``code`` (the cause, + ``no_checkable_claim`` where ``error`` reads ``not_a_claim``), + ``detail`` (one sentence, newer payloads only), ``failure_class``, + ``retryable``, ``hint`` and ``docs_url``. ``None`` when the payload + names no cause.""" + body = self.raw.get("verification") + block = body.get("failure") if isinstance(body, dict) else None + if not isinstance(block, dict): + if not (self.error or self.failure_class): + return None + block = {"failure_reason": self.error, "failure_class": self.failure_class, "retryable": self.retryable} + try: + return FailureBlock.model_validate(block) + except ValidationError: + return None + @dataclass class VerificationNeedsInput(WebhookEvent): @@ -141,6 +176,27 @@ class VerificationNeedsInput(WebhookEvent): needs_input: dict[str, Any] = field(default_factory=dict) hint: str = "" + @property + def reason(self) -> str: + """Why the run paused (``multi_claim``).""" + value = self.needs_input.get("reason") if isinstance(self.needs_input, dict) else None + return value if isinstance(value, str) else "" + + @property + def claims(self) -> list[CandidateClaim]: + """The options to pick from, each with ``claim`` and ``domain``. An + option that cannot be read is left out, never raised on.""" + options = self.needs_input.get("claims") if isinstance(self.needs_input, dict) else None + out = [] + for option in options or []: + if not isinstance(option, dict): + continue + try: + out.append(CandidateClaim.model_validate({k: v for k, v in option.items() if v is not None})) + except ValidationError: + continue + return out + @dataclass class CertificateTimestamped(WebhookEvent): @@ -172,7 +228,8 @@ class ReviewEvent(WebhookEvent): Deduplicate on ``event_id``: it is the same on every delivery attempt of one event, while ``attempt`` counts up. ``task_id`` identifies the - delivery and cannot be polled on ``/verify/status``. The deep checks a + delivery and cannot be polled on ``/verify/status``; the newer payload + shape leaves it out (it then reads ``review_id``). The deep checks a review runs send no ``verification.*`` events of their own. """ @@ -190,7 +247,8 @@ class CitecheckEvent(WebhookEvent): returns), or ``None`` if it could not be parsed (``raw["citecheck"]`` still has it). Deduplicate on ``event_id``: it is the same on every delivery attempt of one event. ``task_id`` identifies the delivery and - cannot be polled on ``/verify/status``. + cannot be polled on ``/verify/status``; the newer payload shape leaves it + out (it then reads ``citecheck_id``). """ event_id: str = "" @@ -198,8 +256,40 @@ class CitecheckEvent(WebhookEvent): citecheck: Citecheck | None = None -def _build_event(payload: dict[str, Any]) -> WebhookEvent: +def _original_view(payload: dict[str, Any]) -> dict[str, Any]: + """The original flat ``verification.*`` fields, for a payload in the newer + envelope (the polled body nested under ``verification``). Any other + payload is returned as it is.""" + body = payload.get("verification") + if not isinstance(body, dict): + return payload + view = dict(payload) + view.setdefault("task_id", body.get("task_id")) + result = body.get("result") + if isinstance(result, dict): + view.setdefault("result", _fill_modified_at(result)) + view.setdefault("verification_id", result.get("verification_id")) + failure = body.get("failure") + if isinstance(failure, dict): + view.setdefault("error", _old_code(failure.get("code"), "not_a_claim")) + view.setdefault("failure_class", failure.get("failure_class")) + view.setdefault("retryable", failure.get("retryable")) + if body.get("status") == "needs_input": + options = [ + {"text": o.get("claim", o.get("text")), "domain": o.get("domain", "")} + for o in body.get("claims") or [] + if isinstance(o, dict) + ] + view.setdefault( + "needs_input", {"reason": body.get("reason", ""), "claims": options, "hint": body.get("hint", "")} + ) + view.setdefault("coverage", body.get("coverage") or (result or {}).get("coverage")) + return view + + +def _build_event(raw: dict[str, Any]) -> WebhookEvent: """Discriminate on ``event`` and return the right typed dataclass.""" + payload = _original_view(raw) event = str(payload.get("event") or "") task_id = str(payload.get("task_id") or "") try: @@ -219,7 +309,7 @@ def _build_event(payload: dict[str, Any]) -> WebhookEvent: verification_id=verification_id, batch_id=batch_id, status=status, - raw=payload, + raw=raw, result=payload.get("result") or {}, ) if event == "verification.failed": @@ -231,7 +321,7 @@ def _build_event(payload: dict[str, Any]) -> WebhookEvent: verification_id=verification_id, batch_id=batch_id, status=status, - raw=payload, + raw=raw, error=str(payload.get("error") or ""), failure_class=str(payload.get("failure_class") or ""), retryable=payload.get("retryable") if isinstance(payload.get("retryable"), bool) else None, @@ -246,7 +336,7 @@ def _build_event(payload: dict[str, Any]) -> WebhookEvent: verification_id=verification_id, batch_id=batch_id, status=status, - raw=payload, + raw=raw, needs_input=needs_input, hint=str(needs_input.get("hint") or "") if isinstance(needs_input, dict) else "", ) @@ -259,7 +349,7 @@ def _build_event(payload: dict[str, Any]) -> WebhookEvent: verification_id=verification_id, batch_id=batch_id, status=status, - raw=payload, + raw=raw, coverage=payload.get("coverage") or {}, ) if event in ("review.completed", "review.failed"): @@ -270,13 +360,15 @@ def _build_event(payload: dict[str, Any]) -> WebhookEvent: review = None return ReviewEvent( event=event, - task_id=task_id, + # The newer payload carries no delivery ``task_id``: the review's + # id stands in, so code keyed on ``task_id`` keeps one key per review. + task_id=task_id if "task_id" in raw else str(payload.get("review_id") or ""), attempt=attempt, delivered_at=delivered_at, verification_id=verification_id, batch_id=batch_id, status=status, - raw=payload, + raw=raw, event_id=str(payload.get("event_id") or ""), review_id=str(payload.get("review_id") or ""), review=review, @@ -289,13 +381,14 @@ def _build_event(payload: dict[str, Any]) -> WebhookEvent: check = None return CitecheckEvent( event=event, - task_id=task_id, + # As on a review: the check's id stands in for the missing ``task_id``. + task_id=task_id if "task_id" in raw else str(payload.get("citecheck_id") or ""), attempt=attempt, delivered_at=delivered_at, verification_id=verification_id, batch_id=batch_id, status=status, - raw=payload, + raw=raw, event_id=str(payload.get("event_id") or ""), citecheck_id=str(payload.get("citecheck_id") or ""), citecheck=check, @@ -310,7 +403,7 @@ def _build_event(payload: dict[str, Any]) -> WebhookEvent: verification_id=verification_id, batch_id=batch_id, status=status, - raw=payload, + raw=raw, ) diff --git a/tests/fixtures/parity/canonical/account__api_root.json b/tests/fixtures/parity/canonical/account__api_root.json new file mode 100644 index 0000000..592cd14 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__api_root.json @@ -0,0 +1,43 @@ +{ + "status": 200, + "body": { + "name": "Lenz Public API", + "version": "v1", + "docs_url": "https://lenz.io/api/v1/docs/", + "openapi_url": "https://lenz.io/api/v1/openapi.json", + "quickstart_url": "https://lenz.io/docs/quickstart", + "developer_portal_url": "https://lenz.io/developers", + "endpoints": { + "extract": "https://lenz.io/api/v1/extract", + "assess": "https://lenz.io/api/v1/assess", + "verify": "https://lenz.io/api/v1/verify", + "ask": "https://lenz.io/api/v1/ask/{verification_id}", + "verify_status": "https://lenz.io/api/v1/verify/status/{task_id}", + "verifications": "https://lenz.io/api/v1/verifications/{verification_id}", + "library": "https://lenz.io/api/v1/library", + "usage": "https://lenz.io/api/v1/me/usage" + }, + "sdks": { + "python": { + "repository": "https://github.com/lenzhq/lenz-io-python", + "package": "https://pypi.org/project/lenz-io/", + "install": "pip install lenz-io" + }, + "node": { + "repository": "https://github.com/lenzhq/lenz-io-node", + "package": "https://www.npmjs.com/package/lenz-io", + "install": "npm install lenz-io" + } + }, + "mcp": { + "url": "https://lenz.io/mcp", + "transport": "streamable-http", + "repository": "https://github.com/lenzhq/lenz-mcp" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__ask_history_after_reset.json b/tests/fixtures/parity/canonical/account__ask_history_after_reset.json new file mode 100644 index 0000000..e9962b2 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__ask_history_after_reset.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "messages": [], + "exchanges_used": 0, + "exchange_limit": 100, + "can_send": true + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__ask_history_after_send.json b/tests/fixtures/parity/canonical/account__ask_history_after_send.json new file mode 100644 index 0000000..ded388d --- /dev/null +++ b/tests/fixtures/parity/canonical/account__ask_history_after_send.json @@ -0,0 +1,25 @@ +{ + "status": 200, + "body": { + "messages": [ + { + "role": "user", + "content": "Why?", + "created_at": "2026-10-01T09:07:00.123456+00:00" + }, + { + "role": "expert", + "content": "Because **evidence**.", + "created_at": "2026-10-01T09:14:00.123456+00:00" + } + ], + "exchanges_used": 1, + "exchange_limit": 100, + "can_send": true + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__ask_history_empty.json b/tests/fixtures/parity/canonical/account__ask_history_empty.json new file mode 100644 index 0000000..e9962b2 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__ask_history_empty.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "messages": [], + "exchanges_used": 0, + "exchange_limit": 100, + "can_send": true + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__ask_history_messages.json b/tests/fixtures/parity/canonical/account__ask_history_messages.json new file mode 100644 index 0000000..efc4809 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__ask_history_messages.json @@ -0,0 +1,25 @@ +{ + "status": 200, + "body": { + "messages": [ + { + "role": "user", + "content": "Hello", + "created_at": "2026-10-01T09:07:00.123456+00:00" + }, + { + "role": "expert", + "content": "Hi there!", + "created_at": "2026-10-01T09:14:00.123456+00:00" + } + ], + "exchanges_used": 0, + "exchange_limit": 100, + "can_send": true + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__ask_reset.json b/tests/fixtures/parity/canonical/account__ask_reset.json new file mode 100644 index 0000000..cddadae --- /dev/null +++ b/tests/fixtures/parity/canonical/account__ask_reset.json @@ -0,0 +1,11 @@ +{ + "status": 200, + "body": { + "ok": true + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__ask_send.json b/tests/fixtures/parity/canonical/account__ask_send.json new file mode 100644 index 0000000..d07ac92 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__ask_send.json @@ -0,0 +1,13 @@ +{ + "status": 200, + "body": { + "role": "expert", + "content": "Because **evidence**.", + "created_at": "2026-10-01T09:07:00.123456+00:00" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__ask_send_language.json b/tests/fixtures/parity/canonical/account__ask_send_language.json new file mode 100644 index 0000000..37c151c --- /dev/null +++ b/tests/fixtures/parity/canonical/account__ask_send_language.json @@ -0,0 +1,13 @@ +{ + "status": 200, + "body": { + "role": "expert", + "content": "Porque.", + "created_at": "2026-10-01T09:07:00.123456+00:00" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__library_empty.json b/tests/fixtures/parity/canonical/account__library_empty.json new file mode 100644 index 0000000..406be8e --- /dev/null +++ b/tests/fixtures/parity/canonical/account__library_empty.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "items": [], + "total": 0, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__library_item_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/canonical/account__library_item_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..b9e2003 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__library_item_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "A library claim.", + "domain": "", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "completed_at": "2026-10-02T00:03:00.123456+00:00", + "language": "en" + } + ], + "total": 1, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__library_item_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/canonical/account__library_item_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..cd1c5f3 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__library_item_modified_at_same_day_hours_apart.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "A library claim.", + "domain": "", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "completed_at": "2026-10-01T20:00:00.123456+00:00", + "language": "en" + } + ], + "total": 1, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__library_items.json b/tests/fixtures/parity/canonical/account__library_items.json new file mode 100644 index 0000000..7939f55 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__library_items.json @@ -0,0 +1,60 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "Library claim 0.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "language": "en" + }, + { + "verification_id": "4d44dfaf", + "claim": "Library claim 1.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:14:00.123456+00:00", + "completed_at": "2026-10-01T09:14:00.123456+00:00", + "language": "en" + }, + { + "verification_id": "7c83247c", + "claim": "Library claim 2.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:21:00.123456+00:00", + "completed_at": "2026-10-01T09:21:00.123456+00:00", + "language": "en" + } + ], + "total": 3, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__library_no_match.json b/tests/fixtures/parity/canonical/account__library_no_match.json new file mode 100644 index 0000000..406be8e --- /dev/null +++ b/tests/fixtures/parity/canonical/account__library_no_match.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "items": [], + "total": 0, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__library_page_past_end.json b/tests/fixtures/parity/canonical/account__library_page_past_end.json new file mode 100644 index 0000000..575d59b --- /dev/null +++ b/tests/fixtures/parity/canonical/account__library_page_past_end.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "items": [], + "total": 1, + "page": 2, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__library_paginated_second_page.json b/tests/fixtures/parity/canonical/account__library_paginated_second_page.json new file mode 100644 index 0000000..e19a6d7 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__library_paginated_second_page.json @@ -0,0 +1,45 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "Paged claim 020.", + "domain": "", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "language": "en" + }, + { + "verification_id": "4d44dfaf", + "claim": "Paged claim 021.", + "domain": "", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:14:00.123456+00:00", + "completed_at": "2026-10-01T09:14:00.123456+00:00", + "language": "en" + } + ], + "total": 22, + "page": 2, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__me_usage_extra_credits.json b/tests/fixtures/parity/canonical/account__me_usage_extra_credits.json new file mode 100644 index 0000000..0bd9f0a --- /dev/null +++ b/tests/fixtures/parity/canonical/account__me_usage_extra_credits.json @@ -0,0 +1,40 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "credits": { + "total": 350, + "used": 0, + "remaining": 350, + "extra": 250, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__me_usage_extra_only.json b/tests/fixtures/parity/canonical/account__me_usage_extra_only.json new file mode 100644 index 0000000..553553f --- /dev/null +++ b/tests/fixtures/parity/canonical/account__me_usage_extra_only.json @@ -0,0 +1,40 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "credits": { + "total": 137, + "used": 100, + "remaining": 37, + "extra": 37, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__me_usage_extract_calls.json b/tests/fixtures/parity/canonical/account__me_usage_extract_calls.json new file mode 100644 index 0000000..0f0a7e3 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__me_usage_extract_calls.json @@ -0,0 +1,40 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "credits": { + "total": 100, + "used": 0, + "remaining": 100, + "extra": 0, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "extract": { + "calls_today": 7, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__me_usage_free.json b/tests/fixtures/parity/canonical/account__me_usage_free.json new file mode 100644 index 0000000..49d68a6 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__me_usage_free.json @@ -0,0 +1,40 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "credits": { + "total": 100, + "used": 0, + "remaining": 100, + "extra": 0, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__me_usage_free_partly_spent.json b/tests/fixtures/parity/canonical/account__me_usage_free_partly_spent.json new file mode 100644 index 0000000..4ef2fed --- /dev/null +++ b/tests/fixtures/parity/canonical/account__me_usage_free_partly_spent.json @@ -0,0 +1,40 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "credits": { + "total": 100, + "used": 17, + "remaining": 83, + "extra": 0, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__me_usage_oauth.json b/tests/fixtures/parity/canonical/account__me_usage_oauth.json new file mode 100644 index 0000000..49d68a6 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__me_usage_oauth.json @@ -0,0 +1,40 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "credits": { + "total": 100, + "used": 0, + "remaining": 100, + "extra": 0, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__me_usage_plus.json b/tests/fixtures/parity/canonical/account__me_usage_plus.json new file mode 100644 index 0000000..d1c06bf --- /dev/null +++ b/tests/fixtures/parity/canonical/account__me_usage_plus.json @@ -0,0 +1,40 @@ +{ + "status": 200, + "body": { + "plan": "plus", + "plan_label": "Plus", + "credits": { + "total": 500, + "used": 0, + "remaining": 500, + "extra": 0, + "resets_at": "2026-10-01T14:07:00.123456+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__me_usage_pro.json b/tests/fixtures/parity/canonical/account__me_usage_pro.json new file mode 100644 index 0000000..0a9924e --- /dev/null +++ b/tests/fixtures/parity/canonical/account__me_usage_pro.json @@ -0,0 +1,40 @@ +{ + "status": 200, + "body": { + "plan": "pro", + "plan_label": "Pro", + "credits": { + "total": 5000, + "used": 0, + "remaining": 5000, + "extra": 0, + "resets_at": "2026-10-01T14:07:00.123456+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__me_usage_pro_extra.json b/tests/fixtures/parity/canonical/account__me_usage_pro_extra.json new file mode 100644 index 0000000..20a91fa --- /dev/null +++ b/tests/fixtures/parity/canonical/account__me_usage_pro_extra.json @@ -0,0 +1,40 @@ +{ + "status": 200, + "body": { + "plan": "pro", + "plan_label": "Pro", + "credits": { + "total": 6000, + "used": 0, + "remaining": 6000, + "extra": 1000, + "resets_at": "2026-10-01T14:07:00.123456+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__me_usage_stale_quota_row.json b/tests/fixtures/parity/canonical/account__me_usage_stale_quota_row.json new file mode 100644 index 0000000..49d68a6 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__me_usage_stale_quota_row.json @@ -0,0 +1,40 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "credits": { + "total": 100, + "used": 0, + "remaining": 100, + "extra": 0, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__oauth_register_success.json b/tests/fixtures/parity/canonical/account__oauth_register_success.json new file mode 100644 index 0000000..15e9752 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__oauth_register_success.json @@ -0,0 +1,25 @@ +{ + "status": 201, + "body": { + "client_id": "lzc_0a1db81dbba84d2d473826d8", + "client_id_issued_at": "", + "client_name": "n8n", + "redirect_uris": [ + "https://acme.app.n8n.cloud/rest/oauth2-credential/callback" + ], + "grant_types": [ + "authorization_code", + "refresh_token" + ], + "response_types": [ + "code" + ], + "token_endpoint_auth_method": "none", + "scope": "assess verify ask ask:read extract history:read history:write usage:read webhooks:manage" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__oauth_revoke.json b/tests/fixtures/parity/canonical/account__oauth_revoke.json new file mode 100644 index 0000000..f0ea1e6 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__oauth_revoke.json @@ -0,0 +1,9 @@ +{ + "status": 200, + "body": {}, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__oauth_revoke_token.json b/tests/fixtures/parity/canonical/account__oauth_revoke_token.json new file mode 100644 index 0000000..f0ea1e6 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__oauth_revoke_token.json @@ -0,0 +1,9 @@ +{ + "status": 200, + "body": {}, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__webhook_secret_api_key.json b/tests/fixtures/parity/canonical/account__webhook_secret_api_key.json new file mode 100644 index 0000000..4fdb761 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__webhook_secret_api_key.json @@ -0,0 +1,12 @@ +{ + "status": 403, + "body": { + "detail": "An API key's webhook secret is managed on the API credentials page (https://lenz.io/api-credentials). This endpoint is for OAuth connections.", + "code": "oauth_only" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__webhook_secret_insufficient_scope.json b/tests/fixtures/parity/canonical/account__webhook_secret_insufficient_scope.json new file mode 100644 index 0000000..6e2d697 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__webhook_secret_insufficient_scope.json @@ -0,0 +1,14 @@ +{ + "status": 403, + "body": { + "detail": "The access token does not allow this call.", + "code": "insufficient_scope", + "scope": "webhooks:manage" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "WWW-Authenticate": "Bearer error=\"insufficient_scope\", scope=\"webhooks:manage\", resource_metadata=\"https://lenz.io/.well-known/oauth-protected-resource/api/v1\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/account__webhook_secret_oauth.json b/tests/fixtures/parity/canonical/account__webhook_secret_oauth.json new file mode 100644 index 0000000..65ec897 --- /dev/null +++ b/tests/fixtures/parity/canonical/account__webhook_secret_oauth.json @@ -0,0 +1,11 @@ +{ + "status": 200, + "body": { + "webhook_secret": "dc06a4fb5512d77eb96f64eedf3ce77dff58de30e17140fbb229a3e048c3bb93" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__401_no_key.json b/tests/fixtures/parity/canonical/assess__401_no_key.json new file mode 100644 index 0000000..dcdaad0 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__401_no_key.json @@ -0,0 +1,12 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized", + "code": "not_authenticated" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__402_no_credits.json b/tests/fixtures/parity/canonical/assess__402_no_credits.json new file mode 100644 index 0000000..c64d322 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__402_no_credits.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining /assess units.", + "code": "no_credits", + "docs_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__422_blank_item.json b/tests/fixtures/parity/canonical/assess__422_blank_item.json new file mode 100644 index 0000000..f5dbd88 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__422_blank_item.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "claims[1] is blank.", + "code": "blank_input", + "errors": [ + { + "loc": [ + "body", + "claims", + 1 + ], + "msg": "claims[1] is blank.", + "type": "blank_input" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__422_blank_text.json b/tests/fixtures/parity/canonical/assess__422_blank_text.json new file mode 100644 index 0000000..bfcc575 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__422_blank_text.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "claim is required.", + "code": "blank_input", + "errors": [ + { + "loc": [ + "body", + "claim" + ], + "msg": "claim is required.", + "type": "blank_input" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__422_input_conflict.json b/tests/fixtures/parity/canonical/assess__422_input_conflict.json new file mode 100644 index 0000000..1746713 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__422_input_conflict.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "Send either `claim` (one text) or `claims` (a list of claims), not both.", + "code": "input_conflict", + "errors": [ + { + "loc": [ + "body", + "claims" + ], + "msg": "Send either `claim` (one text) or `claims` (a list of claims), not both.", + "type": "input_conflict" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__422_item_too_long.json b/tests/fixtures/parity/canonical/assess__422_item_too_long.json new file mode 100644 index 0000000..1408fdd --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__422_item_too_long.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "claims[1] is 2001 characters; each claim may be at most 2000. Send a document to /extract first, then assess its claims.", + "code": "item_too_long", + "errors": [ + { + "loc": [ + "body", + "claims", + 1 + ], + "msg": "claims[1] is 2001 characters; each claim may be at most 2000. Send a document to /extract first, then assess its claims.", + "type": "item_too_long" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__422_no_input_field.json b/tests/fixtures/parity/canonical/assess__422_no_input_field.json new file mode 100644 index 0000000..f5b9868 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__422_no_input_field.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "claim: Field required", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required", + "type": "missing" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__422_too_many_items.json b/tests/fixtures/parity/canonical/assess__422_too_many_items.json new file mode 100644 index 0000000..1c4170f --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__422_too_many_items.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "At most 20 claims per call; got 21. Split the list.", + "code": "too_many_items", + "errors": [ + { + "loc": [ + "body", + "claims" + ], + "msg": "At most 20 claims per call; got 21. Split the list.", + "type": "too_many_items" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__422_wrong_type_claim.json b/tests/fixtures/parity/canonical/assess__422_wrong_type_claim.json new file mode 100644 index 0000000..78a4682 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__422_wrong_type_claim.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "claim: Input should be a valid string", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "claim" + ], + "msg": "Input should be a valid string", + "type": "string_type" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__422_wrong_type_claims.json b/tests/fixtures/parity/canonical/assess__422_wrong_type_claims.json new file mode 100644 index 0000000..479b4ca --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__422_wrong_type_claims.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "claims: Input should be a valid list", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "claims" + ], + "msg": "Input should be a valid list", + "type": "list_type" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__502_framing_failed.json b/tests/fixtures/parity/canonical/assess__502_framing_failed.json new file mode 100644 index 0000000..3e9296d --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__502_framing_failed.json @@ -0,0 +1,12 @@ +{ + "status": 502, + "body": { + "detail": "Framing failed", + "code": "framing_failed" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__503_capacity.json b/tests/fixtures/parity/canonical/assess__503_capacity.json new file mode 100644 index 0000000..b10c32e --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__503_capacity.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": 100, + "docs_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "100", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__503_list_all_upstream_unavailable.json b/tests/fixtures/parity/canonical/assess__503_list_all_upstream_unavailable.json new file mode 100644 index 0000000..f4be3f0 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__503_list_all_upstream_unavailable.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Our model providers are temporarily unavailable. Please retry shortly. Nothing was charged.", + "code": "upstream_unavailable", + "retry_after": 90, + "docs_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__503_upstream_unavailable.json b/tests/fixtures/parity/canonical/assess__503_upstream_unavailable.json new file mode 100644 index 0000000..be8c7a9 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__503_upstream_unavailable.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Our model providers are temporarily unavailable. Please retry shortly.", + "code": "upstream_unavailable", + "retry_after": 90, + "docs_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__deep_tier_hit.json b/tests/fixtures/parity/canonical/assess__deep_tier_hit.json new file mode 100644 index 0000000..e988914 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__deep_tier_hit.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "status": "ok", + "claims": [ + { + "claim": "Water boils at 100C.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": "https://lenz.io/api/v1/verifications/f3436f50", + "rationale": "The claim is verified.", + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + } + ], + "failure": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__idempotency_body_mismatch.json b/tests/fixtures/parity/canonical/assess__idempotency_body_mismatch.json new file mode 100644 index 0000000..8cdd4be --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__idempotency_body_mismatch.json @@ -0,0 +1,12 @@ +{ + "status": 422, + "body": { + "detail": "Idempotency-Key reused with a different request body.", + "code": "idempotency_body_mismatch" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__idempotency_first.json b/tests/fixtures/parity/canonical/assess__idempotency_first.json new file mode 100644 index 0000000..72c4d4a --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__idempotency_first.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "status": "ok", + "claims": [ + { + "claim": "The Earth orbits the Sun.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + } + ], + "failure": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__idempotency_replay.json b/tests/fixtures/parity/canonical/assess__idempotency_replay.json new file mode 100644 index 0000000..72c4d4a --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__idempotency_replay.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "status": "ok", + "claims": [ + { + "claim": "The Earth orbits the Sun.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + } + ], + "failure": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__list_all_error_rows.json b/tests/fixtures/parity/canonical/assess__list_all_error_rows.json new file mode 100644 index 0000000..f0fc834 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__list_all_error_rows.json @@ -0,0 +1,55 @@ +{ + "status": 200, + "body": { + "status": "no_checkable_claim", + "claims": [ + { + "claim": "hi", + "language": "en", + "status": "failed", + "verdict": null, + "confidence": null, + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": { + "code": "no_checkable_claim", + "detail": "No claim in the input could be checked against public evidence.", + "hint": "The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + } + }, + { + "claim": "hello", + "language": "en", + "status": "failed", + "verdict": null, + "confidence": null, + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": { + "code": "no_checkable_claim", + "detail": "No claim in the input could be checked against public evidence.", + "hint": "The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + } + } + ], + "failure": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__list_compound_item.json b/tests/fixtures/parity/canonical/assess__list_compound_item.json new file mode 100644 index 0000000..ed32e13 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__list_compound_item.json @@ -0,0 +1,44 @@ +{ + "status": 200, + "body": { + "status": "ok", + "claims": [ + { + "claim": "Primary claim.", + "language": "en", + "status": "completed", + "verdict": "Mostly False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [ + "Second claim.", + "Third claim." + ], + "failure": null + }, + { + "claim": "A plain claim.", + "language": "en", + "status": "completed", + "verdict": "Mostly False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + } + ], + "failure": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__list_mixed_rows.json b/tests/fixtures/parity/canonical/assess__list_mixed_rows.json new file mode 100644 index 0000000..7b5a292 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__list_mixed_rows.json @@ -0,0 +1,88 @@ +{ + "status": 200, + "body": { + "status": "ok", + "claims": [ + { + "claim": "Water boils at 100 C at sea level.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "hello there", + "language": "en", + "status": "failed", + "verdict": null, + "confidence": null, + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": { + "code": "no_checkable_claim", + "detail": "No claim in the input could be checked against public evidence.", + "hint": "The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + } + }, + { + "claim": "vendor is down", + "language": "en", + "status": "failed", + "verdict": null, + "confidence": null, + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + { + "claim": "cannot frame", + "language": "en", + "status": "failed", + "verdict": null, + "confidence": null, + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": { + "code": "framing_failed", + "detail": "The input could not be read as a claim.", + "hint": "This item could not be processed; retrying it as-is will not help. Send it rephrased as one factual statement; nothing was charged.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + } + } + ], + "failure": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__memo_hit.json b/tests/fixtures/parity/canonical/assess__memo_hit.json new file mode 100644 index 0000000..5484c2e --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__memo_hit.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "status": "ok", + "claims": [ + { + "claim": "The Danube flows through Vienna.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": "The river runs through the city.", + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + } + ], + "failure": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__replay_later_200.json b/tests/fixtures/parity/canonical/assess__replay_later_200.json new file mode 100644 index 0000000..fedc9c5 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__replay_later_200.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "claims": [ + { + "claim": "The Earth orbits the Sun.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + } + ], + "error": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__single_no_claim.json b/tests/fixtures/parity/canonical/assess__single_no_claim.json new file mode 100644 index 0000000..aea089f --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__single_no_claim.json @@ -0,0 +1,21 @@ +{ + "status": 200, + "body": { + "status": "no_checkable_claim", + "claims": [], + "failure": { + "code": "no_checkable_claim", + "detail": "No claim in the input could be checked against public evidence.", + "hint": "The input is a greeting, not a statement that can be checked. Send one factual claim, or run the text through /extract to enumerate its claims.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__single_one_claim.json b/tests/fixtures/parity/canonical/assess__single_one_claim.json new file mode 100644 index 0000000..2c30b26 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__single_one_claim.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "status": "ok", + "claims": [ + { + "claim": "The registry reported 4,200 filings in 2024.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": "The registry lists 4,200 filings for 2024 and has not revised the figure.", + "dissent": "The registry figure is provisional, so the 2024 total cannot yet be confirmed.", + "suggested_rewrite": null, + "more_claims": [], + "failure": null + } + ], + "failure": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__single_text_over_wave_more_claims.json b/tests/fixtures/parity/canonical/assess__single_text_over_wave_more_claims.json new file mode 100644 index 0000000..224f888 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__single_text_over_wave_more_claims.json @@ -0,0 +1,278 @@ +{ + "status": 200, + "body": { + "status": "ok", + "claims": [ + { + "claim": "Claim number 0 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 1 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 2 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 3 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 4 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 5 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 6 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 7 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 8 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 9 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 10 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 11 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 12 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 13 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 14 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 15 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 16 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 17 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 18 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "Claim number 19 is documented.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + } + ], + "failure": null, + "more_claims": [ + "Claim number 20 is documented.", + "Claim number 21 is documented." + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__single_text_several_claims.json b/tests/fixtures/parity/canonical/assess__single_text_several_claims.json new file mode 100644 index 0000000..e2e6e8c --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__single_text_several_claims.json @@ -0,0 +1,54 @@ +{ + "status": 200, + "body": { + "status": "ok", + "claims": [ + { + "claim": "Water boils at 100 C at sea level.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "The Moon is made of cheese.", + "language": "en", + "status": "completed", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + { + "claim": "The Pacific is the deepest ocean.", + "language": "en", + "status": "completed", + "verdict": "Mostly True", + "confidence": "medium", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + } + ], + "failure": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/assess__suggest_rewrite.json b/tests/fixtures/parity/canonical/assess__suggest_rewrite.json new file mode 100644 index 0000000..3df8c25 --- /dev/null +++ b/tests/fixtures/parity/canonical/assess__suggest_rewrite.json @@ -0,0 +1,41 @@ +{ + "status": 200, + "body": { + "status": "ok", + "claims": [ + { + "claim": "Venus is the closest planet to the Sun.", + "language": "en", + "status": "completed", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": "Mercury, not Venus, is the closest planet to the Sun.", + "dissent": null, + "suggested_rewrite": "Mercury is the closest planet to the Sun.", + "more_claims": [], + "failure": null + }, + { + "claim": "Mercury is the closest planet to the Sun.", + "language": "en", + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": "Mercury is the innermost planet.", + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + } + ], + "failure": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__402_no_credits.json b/tests/fixtures/parity/canonical/citecheck__402_no_credits.json new file mode 100644 index 0000000..5d36059 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__402_no_credits.json @@ -0,0 +1,18 @@ +{ + "status": 402, + "body": { + "detail": "No remaining credits for citation checks.", + "code": "no_credits", + "docs_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 100, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_empty_body.json b/tests/fixtures/parity/canonical/citecheck__422_empty_body.json new file mode 100644 index 0000000..8e95f6b --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_empty_body.json @@ -0,0 +1,25 @@ +{ + "status": 422, + "body": { + "detail": "payload: Value error, send exactly one of text and pairs", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload" + ], + "msg": "Value error, send exactly one of text and pairs", + "type": "value_error", + "ctx": { + "error": "send exactly one of text and pairs" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_invalid_doi.json b/tests/fixtures/parity/canonical/citecheck__422_invalid_doi.json new file mode 100644 index 0000000..def6efd --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_invalid_doi.json @@ -0,0 +1,25 @@ +{ + "status": 422, + "body": { + "detail": "pairs[0].doi: Send the DOI alone, like 10.1038/nature12373.", + "code": "invalid_doi", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0, + "doi" + ], + "msg": "Send the DOI alone, like 10.1038/nature12373.", + "type": "invalid_doi" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_max_citations_over_20.json b/tests/fixtures/parity/canonical/citecheck__422_max_citations_over_20.json new file mode 100644 index 0000000..bbc3599 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_max_citations_over_20.json @@ -0,0 +1,26 @@ +{ + "status": 422, + "body": { + "detail": "max_citations: Input should be less than or equal to 20", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "max_citations" + ], + "msg": "Input should be less than or equal to 20", + "type": "less_than_equal", + "ctx": { + "le": 20 + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_max_citations_with_pairs.json b/tests/fixtures/parity/canonical/citecheck__422_max_citations_with_pairs.json new file mode 100644 index 0000000..5fb4268 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_max_citations_with_pairs.json @@ -0,0 +1,25 @@ +{ + "status": 422, + "body": { + "detail": "payload: Value error, max_citations goes with text: every pair is checked", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload" + ], + "msg": "Value error, max_citations goes with text: every pair is checked", + "type": "value_error", + "ctx": { + "error": "max_citations goes with text: every pair is checked" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_pair_bad_url_scheme.json b/tests/fixtures/parity/canonical/citecheck__422_pair_bad_url_scheme.json new file mode 100644 index 0000000..10bcd15 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_pair_bad_url_scheme.json @@ -0,0 +1,28 @@ +{ + "status": 422, + "body": { + "detail": "pairs[0].url: Value error, url: an http or https link", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0, + "url" + ], + "msg": "Value error, url: an http or https link", + "type": "value_error", + "ctx": { + "error": "url: an http or https link" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_pair_no_source.json b/tests/fixtures/parity/canonical/citecheck__422_pair_no_source.json new file mode 100644 index 0000000..038c0b4 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_pair_no_source.json @@ -0,0 +1,27 @@ +{ + "status": 422, + "body": { + "detail": "pairs[0]: Value error, send exactly one of url and doi", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0 + ], + "msg": "Value error, send exactly one of url and doi", + "type": "value_error", + "ctx": { + "error": "send exactly one of url and doi" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_pair_url_and_doi.json b/tests/fixtures/parity/canonical/citecheck__422_pair_url_and_doi.json new file mode 100644 index 0000000..038c0b4 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_pair_url_and_doi.json @@ -0,0 +1,27 @@ +{ + "status": 422, + "body": { + "detail": "pairs[0]: Value error, send exactly one of url and doi", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0 + ], + "msg": "Value error, send exactly one of url and doi", + "type": "value_error", + "ctx": { + "error": "send exactly one of url and doi" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_pairs_empty.json b/tests/fixtures/parity/canonical/citecheck__422_pairs_empty.json new file mode 100644 index 0000000..33dbd42 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_pairs_empty.json @@ -0,0 +1,26 @@ +{ + "status": 422, + "body": { + "detail": "pairs: Value error, pairs: 1 to 20 items", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs" + ], + "msg": "Value error, pairs: 1 to 20 items", + "type": "value_error", + "ctx": { + "error": "pairs: 1 to 20 items" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_pairs_over_20.json b/tests/fixtures/parity/canonical/citecheck__422_pairs_over_20.json new file mode 100644 index 0000000..33dbd42 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_pairs_over_20.json @@ -0,0 +1,26 @@ +{ + "status": 422, + "body": { + "detail": "pairs: Value error, pairs: 1 to 20 items", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs" + ], + "msg": "Value error, pairs: 1 to 20 items", + "type": "value_error", + "ctx": { + "error": "pairs: 1 to 20 items" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_quote_not_in_statement.json b/tests/fixtures/parity/canonical/citecheck__422_quote_not_in_statement.json new file mode 100644 index 0000000..543ee02 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_quote_not_in_statement.json @@ -0,0 +1,24 @@ +{ + "status": 422, + "body": { + "detail": "pairs[0]: Each quote must be words of its statement.", + "code": "quote_not_in_statement", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0 + ], + "msg": "Each quote must be words of its statement.", + "type": "quote_not_in_statement" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_text_and_pairs.json b/tests/fixtures/parity/canonical/citecheck__422_text_and_pairs.json new file mode 100644 index 0000000..8e95f6b --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_text_and_pairs.json @@ -0,0 +1,25 @@ +{ + "status": 422, + "body": { + "detail": "payload: Value error, send exactly one of text and pairs", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload" + ], + "msg": "Value error, send exactly one of text and pairs", + "type": "value_error", + "ctx": { + "error": "send exactly one of text and pairs" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_unknown_field.json b/tests/fixtures/parity/canonical/citecheck__422_unknown_field.json new file mode 100644 index 0000000..0823167 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_unknown_field.json @@ -0,0 +1,25 @@ +{ + "status": 422, + "body": { + "detail": "pairs[0].extra: Extra inputs are not permitted", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0, + "extra" + ], + "msg": "Extra inputs are not permitted", + "type": "extra_forbidden" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_url_input.json b/tests/fixtures/parity/canonical/citecheck__422_url_input.json new file mode 100644 index 0000000..68e0bdf --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_url_input.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "Send the page's text, with its links, to check the sources it cites.", + "code": "url_input", + "errors": [ + { + "loc": [ + "body", + "text" + ], + "msg": "Send the page's text, with its links, to check the sources it cites.", + "type": "url_input" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__422_webhook_secret_missing.json b/tests/fixtures/parity/canonical/citecheck__422_webhook_secret_missing.json new file mode 100644 index 0000000..3286c6c --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__422_webhook_secret_missing.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.", + "code": "webhook_secret_missing", + "errors": [ + { + "loc": [ + "body", + "webhook_url" + ], + "msg": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.", + "type": "webhook_secret_missing" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__429_citecheck_in_flight.json b/tests/fixtures/parity/canonical/citecheck__429_citecheck_in_flight.json new file mode 100644 index 0000000..ec8db9b --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__429_citecheck_in_flight.json @@ -0,0 +1,14 @@ +{ + "status": 429, + "body": { + "detail": "This account already has 3 citation checks running. Wait for one to finish.", + "code": "citecheck_in_flight", + "retry_after": 60 + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "60", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__503_capacity.json b/tests/fixtures/parity/canonical/citecheck__503_capacity.json new file mode 100644 index 0000000..63b5d1c --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__503_capacity.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": 90, + "docs_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__503_citations_unavailable.json b/tests/fixtures/parity/canonical/citecheck__503_citations_unavailable.json new file mode 100644 index 0000000..6f3c66e --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__503_citations_unavailable.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Citation checking is switched off right now. Retry later; nothing was charged.", + "code": "citations_unavailable", + "retry_after": 300, + "docs_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "300", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_404_not_found.json b/tests/fixtures/parity/canonical/citecheck__get_404_not_found.json new file mode 100644 index 0000000..5aa3709 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_404_not_found.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Citation check not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_404_review_id.json b/tests/fixtures/parity/canonical/citecheck__get_404_review_id.json new file mode 100644 index 0000000..5aa3709 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_404_review_id.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Citation check not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_410_purged.json b/tests/fixtures/parity/canonical/citecheck__get_410_purged.json new file mode 100644 index 0000000..08b9585 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_410_purged.json @@ -0,0 +1,13 @@ +{ + "status": 410, + "body": { + "detail": "This check is no longer available: its account removes content after a set period.", + "code": "purged", + "purged_at": "2026-10-01T09:07:00.123456Z" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_checking.json b/tests/fixtures/parity/canonical/citecheck__get_checking.json new file mode 100644 index 0000000..9205f4d --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_checking.json @@ -0,0 +1,103 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "checking", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "poll_after_seconds": 10, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 0, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 0 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "pending", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "pending", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_completed_clean.json b/tests/fixtures/parity/canonical/citecheck__get_completed_clean.json new file mode 100644 index 0000000..a80bfd4 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_completed_clean.json @@ -0,0 +1,111 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 2 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": null, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_completed_doi_pair.json b/tests/fixtures/parity/canonical/citecheck__get_completed_doi_pair.json new file mode 100644 index 0000000..c169837 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_completed_doi_pair.json @@ -0,0 +1,76 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 1 + }, + "summary": { + "citations_found": 1, + "citations_selected": 1, + "citation_limit": 1, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 1, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 1 + }, + "citations": [ + { + "index": 0, + "reference": "10.1038/nature12373", + "cited_url": "https://doi.org/10.1038/nature12373", + "doi": "10.1038/nature12373", + "statement": "Diamond sensors measure heat in cells.", + "quotes": [], + "position": null, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at None", + "page_published_date": null, + "page_language": "en", + "source_url": null, + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_completed_incomplete.json b/tests/fixtures/parity/canonical/citecheck__get_completed_incomplete.json new file mode 100644 index 0000000..02db48c --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_completed_incomplete.json @@ -0,0 +1,129 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "incomplete", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 1, + "unchecked": 0, + "failed": 1 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 1 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "failed", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": "The check failed on our side. Try again later.", + "failure": { + "code": "internal", + "detail": "The check failed on our side.", + "hint": "The check failed on our side. Try again later.", + "failure_class": "internal", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#internal" + }, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [ + { + "citation_index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "failure": { + "code": "internal", + "detail": "The check failed on our side.", + "hint": "The check failed on our side. Try again later.", + "failure_class": "internal", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#internal" + } + } + ], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_completed_issues_found.json b/tests/fixtures/parity/canonical/citecheck__get_completed_issues_found.json new file mode 100644 index 0000000..6be9e27 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_completed_issues_found.json @@ -0,0 +1,141 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 20 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 1 + }, + "credits": { + "charged": 2 + }, + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "contradicted", + "source": "support", + "is_issue": true + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "contradicted", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [ + { + "citation_index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "finding": "contradicted", + "source": "support", + "snippet": "The source says so.", + "rationale": "The page states it.", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "failure": null + } + ], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_completed_partly_supported.json b/tests/fixtures/parity/canonical/citecheck__get_completed_partly_supported.json new file mode 100644 index 0000000..dc8d58a --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_completed_partly_supported.json @@ -0,0 +1,111 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 2 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": { + "finding": "partly_supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "partly_supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": null, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_completed_unchecked.json b/tests/fixtures/parity/canonical/citecheck__get_completed_unchecked.json new file mode 100644 index 0000000..0eb98a2 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_completed_unchecked.json @@ -0,0 +1,111 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 0, + "unchecked": 2, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 0 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": { + "finding": "unchecked", + "source": null, + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "unchecked", + "snippet": null, + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": "no_text", + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": null, + "result": { + "finding": "unchecked", + "source": null, + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "unchecked", + "snippet": null, + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": "no_text", + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_failed_no_citations.json b/tests/fixtures/parity/canonical/citecheck__get_failed_no_citations.json new file mode 100644 index 0000000..29d977a --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_failed_no_citations.json @@ -0,0 +1,43 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 20 + }, + "summary": { + "citations_found": null, + "citations_selected": null, + "citation_limit": 20, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0 + }, + "credits": { + "charged": 0 + }, + "citations": [], + "citation_issues": [], + "citation_failures": [], + "failure": { + "code": "no_citations", + "detail": "The text holds no citation to check.", + "hint": "The text has no citation to check: no link, DOI or numbered reference with one.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "more_citations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_failed_upstream_unavailable.json b/tests/fixtures/parity/canonical/citecheck__get_failed_upstream_unavailable.json new file mode 100644 index 0000000..d5ee990 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_failed_upstream_unavailable.json @@ -0,0 +1,153 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 20 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 0, + "unchecked": 0, + "failed": 2 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 0 + }, + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": null, + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "failed", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": "Lenz could not reach this source just now. Try again later.", + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": "Lenz could not reach this source just now. Try again later.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + }, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": null, + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "failed", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": "Lenz could not reach this source just now. Try again later.", + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": "Lenz could not reach this source just now. Try again later.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + }, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [ + { + "citation_index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": "Lenz could not reach this source just now. Try again later.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + { + "citation_index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": "Lenz could not reach this source just now. Try again later.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + } + ], + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": null, + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + }, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_queued.json b/tests/fixtures/parity/canonical/citecheck__get_queued.json new file mode 100644 index 0000000..946e493 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_queued.json @@ -0,0 +1,72 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "queued", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "poll_after_seconds": 10, + "policy": { + "max_citations": 1 + }, + "summary": { + "citations_found": 1, + "citations_selected": 1, + "citation_limit": 1, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 0, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 0 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "pending", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_text_limit_exactly_at_limit.json b/tests/fixtures/parity/canonical/citecheck__get_text_limit_exactly_at_limit.json new file mode 100644 index 0000000..403ac29 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_text_limit_exactly_at_limit.json @@ -0,0 +1,119 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 2 + }, + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__get_text_limit_reached.json b/tests/fixtures/parity/canonical/citecheck__get_text_limit_reached.json new file mode 100644 index 0000000..279af9f --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__get_text_limit_reached.json @@ -0,0 +1,93 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 1 + }, + "summary": { + "citations_found": 2, + "citations_selected": 1, + "citation_limit": 1, + "citation_limit_exceeded": true, + "citation_checks": { + "checked": 1, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 1 + }, + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [ + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "sentence": "The agency said so in a statement.", + "position": { + "start": 111, + "end": 178, + "text": null + } + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__idempotency_body_mismatch_422.json b/tests/fixtures/parity/canonical/citecheck__idempotency_body_mismatch_422.json new file mode 100644 index 0000000..8cdd4be --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__idempotency_body_mismatch_422.json @@ -0,0 +1,12 @@ +{ + "status": 422, + "body": { + "detail": "Idempotency-Key reused with a different request body.", + "code": "idempotency_body_mismatch" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__idempotency_conflict_409.json b/tests/fixtures/parity/canonical/citecheck__idempotency_conflict_409.json new file mode 100644 index 0000000..c29d230 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__idempotency_conflict_409.json @@ -0,0 +1,13 @@ +{ + "status": 409, + "body": { + "detail": "A check with this Idempotency-Key is still being created. Retry shortly.", + "code": "idempotency_conflict", + "citecheck_id": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__idempotent_replay_202.json b/tests/fixtures/parity/canonical/citecheck__idempotent_replay_202.json new file mode 100644 index 0000000..43d3598 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__idempotent_replay_202.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "citecheck_id": "8eb49302", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/citechecks/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__receipt_202.json b/tests/fixtures/parity/canonical/citecheck__receipt_202.json new file mode 100644 index 0000000..43d3598 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__receipt_202.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "citecheck_id": "8eb49302", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/citechecks/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/citecheck__receipt_202_empty_webhook_url.json b/tests/fixtures/parity/canonical/citecheck__receipt_202_empty_webhook_url.json new file mode 100644 index 0000000..43d3598 --- /dev/null +++ b/tests/fixtures/parity/canonical/citecheck__receipt_202_empty_webhook_url.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "citecheck_id": "8eb49302", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/citechecks/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__ask_bad_language.json b/tests/fixtures/parity/canonical/errors__ask_bad_language.json new file mode 100644 index 0000000..cf9c91d --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__ask_bad_language.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "Unsupported language 'xx-nope'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "code": "unsupported_language", + "errors": [ + { + "loc": [ + "body", + "language" + ], + "msg": "Unsupported language 'xx-nope'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "type": "unsupported_language" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__ask_empty_message.json b/tests/fixtures/parity/canonical/errors__ask_empty_message.json new file mode 100644 index 0000000..1b1c071 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__ask_empty_message.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "Message cannot be empty.", + "code": "blank_input", + "errors": [ + { + "loc": [ + "body", + "message" + ], + "msg": "Message cannot be empty.", + "type": "blank_input" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__ask_failed.json b/tests/fixtures/parity/canonical/errors__ask_failed.json new file mode 100644 index 0000000..a3b433f --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__ask_failed.json @@ -0,0 +1,12 @@ +{ + "status": 502, + "body": { + "detail": "The chat model could not answer this question.", + "code": "ask_failed" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__ask_idempotency_key_reused.json b/tests/fixtures/parity/canonical/errors__ask_idempotency_key_reused.json new file mode 100644 index 0000000..8cdd4be --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__ask_idempotency_key_reused.json @@ -0,0 +1,12 @@ +{ + "status": 422, + "body": { + "detail": "Idempotency-Key reused with a different request body.", + "code": "idempotency_body_mismatch" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__ask_message_too_long.json b/tests/fixtures/parity/canonical/errors__ask_message_too_long.json new file mode 100644 index 0000000..e982806 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__ask_message_too_long.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "Message too long (max 500 characters).", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "message" + ], + "msg": "Message too long (max 500 characters).", + "type": "validation_error" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__ask_not_completed.json b/tests/fixtures/parity/canonical/errors__ask_not_completed.json new file mode 100644 index 0000000..ad4b430 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__ask_not_completed.json @@ -0,0 +1,12 @@ +{ + "status": 400, + "body": { + "detail": "Ask is only available for completed verifications.", + "code": "verification_not_ready" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__ask_reset_not_found.json b/tests/fixtures/parity/canonical/errors__ask_reset_not_found.json new file mode 100644 index 0000000..bccfc47 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__ask_reset_not_found.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Verification not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__ask_send_not_found.json b/tests/fixtures/parity/canonical/errors__ask_send_not_found.json new file mode 100644 index 0000000..bccfc47 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__ask_send_not_found.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Verification not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__auth_bad_key.json b/tests/fixtures/parity/canonical/errors__auth_bad_key.json new file mode 100644 index 0000000..dcdaad0 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__auth_bad_key.json @@ -0,0 +1,12 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized", + "code": "not_authenticated" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__auth_bad_oauth_token.json b/tests/fixtures/parity/canonical/errors__auth_bad_oauth_token.json new file mode 100644 index 0000000..cc8ef29 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__auth_bad_oauth_token.json @@ -0,0 +1,13 @@ +{ + "status": 401, + "body": { + "detail": "The access token is invalid, expired or revoked.", + "code": "invalid_token" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "WWW-Authenticate": "Bearer error=\"invalid_token\", resource_metadata=\"https://lenz.io/.well-known/oauth-protected-resource/api/v1\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__auth_basic_scheme.json b/tests/fixtures/parity/canonical/errors__auth_basic_scheme.json new file mode 100644 index 0000000..dcdaad0 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__auth_basic_scheme.json @@ -0,0 +1,12 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized", + "code": "not_authenticated" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__auth_expired_oauth_token.json b/tests/fixtures/parity/canonical/errors__auth_expired_oauth_token.json new file mode 100644 index 0000000..cc8ef29 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__auth_expired_oauth_token.json @@ -0,0 +1,13 @@ +{ + "status": 401, + "body": { + "detail": "The access token is invalid, expired or revoked.", + "code": "invalid_token" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "WWW-Authenticate": "Bearer error=\"invalid_token\", resource_metadata=\"https://lenz.io/.well-known/oauth-protected-resource/api/v1\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__auth_insufficient_scope.json b/tests/fixtures/parity/canonical/errors__auth_insufficient_scope.json new file mode 100644 index 0000000..4c2fcdd --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__auth_insufficient_scope.json @@ -0,0 +1,14 @@ +{ + "status": 403, + "body": { + "detail": "The access token does not allow this call.", + "code": "insufficient_scope", + "scope": "verify" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "WWW-Authenticate": "Bearer error=\"insufficient_scope\", scope=\"verify\", resource_metadata=\"https://lenz.io/.well-known/oauth-protected-resource/api/v1\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__auth_missing_bearer.json b/tests/fixtures/parity/canonical/errors__auth_missing_bearer.json new file mode 100644 index 0000000..dcdaad0 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__auth_missing_bearer.json @@ -0,0 +1,12 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized", + "code": "not_authenticated" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__auth_missing_bearer_post.json b/tests/fixtures/parity/canonical/errors__auth_missing_bearer_post.json new file mode 100644 index 0000000..dcdaad0 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__auth_missing_bearer_post.json @@ -0,0 +1,12 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized", + "code": "not_authenticated" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__auth_oauth_issuer_off.json b/tests/fixtures/parity/canonical/errors__auth_oauth_issuer_off.json new file mode 100644 index 0000000..dcdaad0 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__auth_oauth_issuer_off.json @@ -0,0 +1,12 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized", + "code": "not_authenticated" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__auth_oauth_only.json b/tests/fixtures/parity/canonical/errors__auth_oauth_only.json new file mode 100644 index 0000000..4fdb761 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__auth_oauth_only.json @@ -0,0 +1,12 @@ +{ + "status": 403, + "body": { + "detail": "An API key's webhook secret is managed on the API credentials page (https://lenz.io/api-credentials). This endpoint is for OAuth connections.", + "code": "oauth_only" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__auth_private_claim_ask_history.json b/tests/fixtures/parity/canonical/errors__auth_private_claim_ask_history.json new file mode 100644 index 0000000..07faa70 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__auth_private_claim_ask_history.json @@ -0,0 +1,12 @@ +{ + "status": 403, + "body": { + "detail": "This report is private.", + "code": "private_claim" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__auth_private_claim_ask_send.json b/tests/fixtures/parity/canonical/errors__auth_private_claim_ask_send.json new file mode 100644 index 0000000..07faa70 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__auth_private_claim_ask_send.json @@ -0,0 +1,12 @@ +{ + "status": 403, + "body": { + "detail": "This report is private.", + "code": "private_claim" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__auth_unrecognised_prefix.json b/tests/fixtures/parity/canonical/errors__auth_unrecognised_prefix.json new file mode 100644 index 0000000..dcdaad0 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__auth_unrecognised_prefix.json @@ -0,0 +1,12 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized", + "code": "not_authenticated" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__http_error_library_bad_curated.json b/tests/fixtures/parity/canonical/errors__http_error_library_bad_curated.json new file mode 100644 index 0000000..30b9871 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__http_error_library_bad_curated.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "Invalid curated list(s). Allowed: trivia", + "code": "validation_error", + "errors": [ + { + "loc": [ + "query", + "curated" + ], + "msg": "Invalid curated list(s). Allowed: trivia", + "type": "validation_error" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__http_error_library_bad_verdict.json b/tests/fixtures/parity/canonical/errors__http_error_library_bad_verdict.json new file mode 100644 index 0000000..c77d681 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__http_error_library_bad_verdict.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "Invalid verdict label(s). Allowed: False, Mostly False, Mixed, Mostly True, True", + "code": "validation_error", + "errors": [ + { + "loc": [ + "query", + "verdict" + ], + "msg": "Invalid verdict label(s). Allowed: False, Mostly False, Mixed, Mostly True, True", + "type": "validation_error" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__method_not_allowed_get_verify.json b/tests/fixtures/parity/canonical/errors__method_not_allowed_get_verify.json new file mode 100644 index 0000000..7b3ec88 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__method_not_allowed_get_verify.json @@ -0,0 +1,12 @@ +{ + "status": 405, + "body": { + "detail": "Method not allowed.", + "code": "method_not_allowed" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__method_not_allowed_post_library.json b/tests/fixtures/parity/canonical/errors__method_not_allowed_post_library.json new file mode 100644 index 0000000..7b3ec88 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__method_not_allowed_post_library.json @@ -0,0 +1,12 @@ +{ + "status": 405, + "body": { + "detail": "Method not allowed.", + "code": "method_not_allowed" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__not_found_ask.json b/tests/fixtures/parity/canonical/errors__not_found_ask.json new file mode 100644 index 0000000..bccfc47 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__not_found_ask.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Verification not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__not_found_route.json b/tests/fixtures/parity/canonical/errors__not_found_route.json new file mode 100644 index 0000000..775d847 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__not_found_route.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__not_found_verification.json b/tests/fixtures/parity/canonical/errors__not_found_verification.json new file mode 100644 index 0000000..775d847 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__not_found_verification.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__not_found_verify_status.json b/tests/fixtures/parity/canonical/errors__not_found_verify_status.json new file mode 100644 index 0000000..8c0eaee --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__not_found_verify_status.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Task not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__oauth_register_disabled.json b/tests/fixtures/parity/canonical/errors__oauth_register_disabled.json new file mode 100644 index 0000000..a16648d --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__oauth_register_disabled.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "": "" + }, + "headers": { + "Content-Type": "text/html; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__oauth_register_invalid_client_metadata.json b/tests/fixtures/parity/canonical/errors__oauth_register_invalid_client_metadata.json new file mode 100644 index 0000000..461c91d --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__oauth_register_invalid_client_metadata.json @@ -0,0 +1,12 @@ +{ + "status": 400, + "body": { + "error": "invalid_client_metadata", + "error_description": "token_endpoint_auth_method must be none: Lenz registers public clients that use PKCE." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__oauth_register_invalid_redirect_uri.json b/tests/fixtures/parity/canonical/errors__oauth_register_invalid_redirect_uri.json new file mode 100644 index 0000000..63e62ba --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__oauth_register_invalid_redirect_uri.json @@ -0,0 +1,12 @@ +{ + "status": 400, + "body": { + "error": "invalid_redirect_uri", + "error_description": "Each redirect URI must be https, or http on localhost, 127.0.0.1 or [::1], without a fragment." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__oauth_revoke_invalid_client.json b/tests/fixtures/parity/canonical/errors__oauth_revoke_invalid_client.json new file mode 100644 index 0000000..a7a70ef --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__oauth_revoke_invalid_client.json @@ -0,0 +1,13 @@ +{ + "status": 401, + "body": { + "error": "invalid_client", + "error_description": "Client authentication failed." + }, + "headers": { + "Content-Type": "application/json", + "WWW-Authenticate": "Basic realm=\"lenz\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__oauth_token_invalid_client.json b/tests/fixtures/parity/canonical/errors__oauth_token_invalid_client.json new file mode 100644 index 0000000..a7a70ef --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__oauth_token_invalid_client.json @@ -0,0 +1,13 @@ +{ + "status": 401, + "body": { + "error": "invalid_client", + "error_description": "Client authentication failed." + }, + "headers": { + "Content-Type": "application/json", + "WWW-Authenticate": "Basic realm=\"lenz\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__oauth_token_invalid_grant.json b/tests/fixtures/parity/canonical/errors__oauth_token_invalid_grant.json new file mode 100644 index 0000000..88c6f64 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__oauth_token_invalid_grant.json @@ -0,0 +1,12 @@ +{ + "status": 400, + "body": { + "error": "invalid_grant", + "error_description": "The authorization is invalid or has expired." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__oauth_token_missing_grant_type.json b/tests/fixtures/parity/canonical/errors__oauth_token_missing_grant_type.json new file mode 100644 index 0000000..f989e00 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__oauth_token_missing_grant_type.json @@ -0,0 +1,11 @@ +{ + "status": 400, + "body": { + "error": "unsupported_grant_type" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__oauth_token_refresh_invalid_grant.json b/tests/fixtures/parity/canonical/errors__oauth_token_refresh_invalid_grant.json new file mode 100644 index 0000000..88c6f64 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__oauth_token_refresh_invalid_grant.json @@ -0,0 +1,12 @@ +{ + "status": 400, + "body": { + "error": "invalid_grant", + "error_description": "The authorization is invalid or has expired." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__oauth_token_unsupported_grant_type.json b/tests/fixtures/parity/canonical/errors__oauth_token_unsupported_grant_type.json new file mode 100644 index 0000000..f989e00 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__oauth_token_unsupported_grant_type.json @@ -0,0 +1,11 @@ +{ + "status": 400, + "body": { + "error": "unsupported_grant_type" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__payment_required_ask.json b/tests/fixtures/parity/canonical/errors__payment_required_ask.json new file mode 100644 index 0000000..72c49cc --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__payment_required_ask.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining ask credits.", + "code": "no_credits", + "docs_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__payment_required_assess.json b/tests/fixtures/parity/canonical/errors__payment_required_assess.json new file mode 100644 index 0000000..c64d322 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__payment_required_assess.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining /assess units.", + "code": "no_credits", + "docs_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__payment_required_verify.json b/tests/fixtures/parity/canonical/errors__payment_required_verify.json new file mode 100644 index 0000000..d93b382 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__payment_required_verify.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining claim checks.", + "code": "no_credits", + "docs_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 10 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__payment_required_verify_batch_short.json b/tests/fixtures/parity/canonical/errors__payment_required_verify_batch_short.json new file mode 100644 index 0000000..45ee9f8 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__payment_required_verify_batch_short.json @@ -0,0 +1,20 @@ +{ + "status": 402, + "body": { + "detail": "Insufficient credits for batch.", + "code": "no_credits", + "docs_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "requested": 5, + "remaining": 3, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 30, + "cost": 50 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__rate_limited_extract.json b/tests/fixtures/parity/canonical/errors__rate_limited_extract.json new file mode 100644 index 0000000..35f093a --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__rate_limited_extract.json @@ -0,0 +1,17 @@ +{ + "status": 429, + "body": { + "detail": "Daily /extract limit of 1000 reached for this account. The allowance is shared by every key on the account and by extractions run from the Lenz website.", + "code": "extract_daily_limit", + "limit": 1000, + "retry_after": 900, + "docs_url": "https://lenz.io/docs/errors#rate-limits", + "upgrade_url": "https://lenz.io/plans" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "900", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__service_unavailable_ask.json b/tests/fixtures/parity/canonical/errors__service_unavailable_ask.json new file mode 100644 index 0000000..baaa646 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__service_unavailable_ask.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "The chat model is unavailable right now. Retry shortly.", + "code": "upstream_unavailable", + "retry_after": 90, + "docs_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__service_unavailable_capacity.json b/tests/fixtures/parity/canonical/errors__service_unavailable_capacity.json new file mode 100644 index 0000000..036bd5a --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__service_unavailable_capacity.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": 60, + "docs_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "60", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__validation_malformed_json.json b/tests/fixtures/parity/canonical/errors__validation_malformed_json.json new file mode 100644 index 0000000..23ac8ec --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__validation_malformed_json.json @@ -0,0 +1,12 @@ +{ + "status": 400, + "body": { + "detail": "The request body is not valid JSON.", + "code": "malformed_body" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__validation_missing_field_hint.json b/tests/fixtures/parity/canonical/errors__validation_missing_field_hint.json new file mode 100644 index 0000000..a4831ce --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__validation_missing_field_hint.json @@ -0,0 +1,29 @@ +{ + "status": 422, + "body": { + "detail": "text: Field required", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required", + "type": "missing" + } + ], + "hint": "Required field 'text' is missing. Unrecognised fields: content, bogus.", + "docs_url": "https://lenz.io/docs/errors#validation", + "unrecognized_fields": [ + "content", + "bogus" + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__validation_unknown_field_only.json b/tests/fixtures/parity/canonical/errors__validation_unknown_field_only.json new file mode 100644 index 0000000..381ab3e --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__validation_unknown_field_only.json @@ -0,0 +1,28 @@ +{ + "status": 422, + "body": { + "detail": "claim: Field required", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required", + "type": "missing" + } + ], + "hint": "Required field 'claim' is missing. Unrecognised fields: statement.", + "docs_url": "https://lenz.io/docs/errors#validation", + "unrecognized_fields": [ + "statement" + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__validation_unknown_field_wrong_type.json b/tests/fixtures/parity/canonical/errors__validation_unknown_field_wrong_type.json new file mode 100644 index 0000000..751ca61 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__validation_unknown_field_wrong_type.json @@ -0,0 +1,27 @@ +{ + "status": 422, + "body": { + "detail": "claims: Input should be a valid list", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "claims" + ], + "msg": "Input should be a valid list", + "type": "list_type" + } + ], + "unrecognized_fields": [ + "bogus_field", + "another" + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__validation_wrong_type.json b/tests/fixtures/parity/canonical/errors__validation_wrong_type.json new file mode 100644 index 0000000..7f77b76 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__validation_wrong_type.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "text: Input should be a valid string", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Input should be a valid string", + "type": "string_type" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/errors__web_assess_payment_required.json b/tests/fixtures/parity/canonical/errors__web_assess_payment_required.json new file mode 100644 index 0000000..5e8991b --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__web_assess_payment_required.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No assessments left this month.", + "code": "no_credits", + "doc_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "Cookie" + } +} diff --git a/tests/fixtures/parity/canonical/errors__web_assess_signup_required.json b/tests/fixtures/parity/canonical/errors__web_assess_signup_required.json new file mode 100644 index 0000000..7621cf2 --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__web_assess_signup_required.json @@ -0,0 +1,14 @@ +{ + "status": 403, + "body": { + "detail": "Sign up to check this — it’s free.", + "code": "signup_required", + "signup_claim_stashed": false, + "attempt": "e2fffcdbaf5c6cfc1939f3eaec689a87" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "Cookie" + } +} diff --git a/tests/fixtures/parity/canonical/errors__web_review_rate_limited.json b/tests/fixtures/parity/canonical/errors__web_review_rate_limited.json new file mode 100644 index 0000000..0e7609f --- /dev/null +++ b/tests/fixtures/parity/canonical/errors__web_review_rate_limited.json @@ -0,0 +1,17 @@ +{ + "status": 429, + "body": { + "detail": "This account has used its extractions for today. The daily allowance is shared with the Lenz API. It resets at 00:00 UTC.", + "code": "extract_daily_limit", + "limit": 1000, + "reset_in_seconds": 777, + "doc_url": "https://lenz.io/docs/errors#rate-limits", + "upgrade_url": "https://lenz.io/plans" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "777", + "Cache-Control": "no-store", + "Vary": "Cookie" + } +} diff --git a/tests/fixtures/parity/canonical/extract__401_no_key.json b/tests/fixtures/parity/canonical/extract__401_no_key.json new file mode 100644 index 0000000..dcdaad0 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__401_no_key.json @@ -0,0 +1,12 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized", + "code": "not_authenticated" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__422_blank_text.json b/tests/fixtures/parity/canonical/extract__422_blank_text.json new file mode 100644 index 0000000..9111f0b --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__422_blank_text.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "Text is required.", + "code": "blank_input", + "errors": [ + { + "loc": [ + "body", + "text" + ], + "msg": "Text is required.", + "type": "blank_input" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__422_focus_too_long.json b/tests/fixtures/parity/canonical/extract__422_focus_too_long.json new file mode 100644 index 0000000..228a79f --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__422_focus_too_long.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "focus must be at most 300 characters of plain text.", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "focus" + ], + "msg": "focus must be at most 300 characters of plain text.", + "type": "validation_error" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__422_missing_text.json b/tests/fixtures/parity/canonical/extract__422_missing_text.json new file mode 100644 index 0000000..9ce0a7d --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__422_missing_text.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "text: Field required", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required", + "type": "missing" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__429_daily_limit.json b/tests/fixtures/parity/canonical/extract__429_daily_limit.json new file mode 100644 index 0000000..7ed31f0 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__429_daily_limit.json @@ -0,0 +1,17 @@ +{ + "status": 429, + "body": { + "detail": "Daily /extract limit of 1000 reached for this account. The allowance is shared by every key on the account and by extractions run from the Lenz website.", + "code": "extract_daily_limit", + "limit": 1000, + "retry_after": 3600, + "docs_url": "https://lenz.io/docs/errors#rate-limits", + "upgrade_url": "https://lenz.io/plans" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "3600", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__502_extraction_failed.json b/tests/fixtures/parity/canonical/extract__502_extraction_failed.json new file mode 100644 index 0000000..645e6f6 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__502_extraction_failed.json @@ -0,0 +1,12 @@ +{ + "status": 502, + "body": { + "detail": "Extraction failed", + "code": "extraction_failed" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__503_upstream_unavailable.json b/tests/fixtures/parity/canonical/extract__503_upstream_unavailable.json new file mode 100644 index 0000000..be8c7a9 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__503_upstream_unavailable.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Our model providers are temporarily unavailable. Please retry shortly.", + "code": "upstream_unavailable", + "retry_after": 90, + "docs_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__focus_ready.json b/tests/fixtures/parity/canonical/extract__focus_ready.json new file mode 100644 index 0000000..6229973 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__focus_ready.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claims": [ + { + "claim": "Beta fell 3% last year.", + "positions": null + } + ], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__idempotency_body_mismatch_422.json b/tests/fixtures/parity/canonical/extract__idempotency_body_mismatch_422.json new file mode 100644 index 0000000..8cdd4be --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__idempotency_body_mismatch_422.json @@ -0,0 +1,12 @@ +{ + "status": 422, + "body": { + "detail": "Idempotency-Key reused with a different request body.", + "code": "idempotency_body_mismatch" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__idempotency_replay.json b/tests/fixtures/parity/canonical/extract__idempotency_replay.json new file mode 100644 index 0000000..d1b6b07 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__idempotency_replay.json @@ -0,0 +1,34 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claims": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": null + }, + { + "claim": "Beta fell 3% last year.", + "positions": null + } + ], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__locate_all_dropped.json b/tests/fixtures/parity/canonical/extract__locate_all_dropped.json new file mode 100644 index 0000000..2886061 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__locate_all_dropped.json @@ -0,0 +1,25 @@ +{ + "status": 200, + "body": { + "status": "no_checkable_claim", + "claims": [], + "domain": "", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__locate_failed.json b/tests/fixtures/parity/canonical/extract__locate_failed.json new file mode 100644 index 0000000..a4ce206 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__locate_failed.json @@ -0,0 +1,34 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claims": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": null + }, + { + "claim": "Beta fell 3% last year.", + "positions": null + } + ], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__locate_leading_whitespace.json b/tests/fixtures/parity/canonical/extract__locate_leading_whitespace.json new file mode 100644 index 0000000..a84de40 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__locate_leading_whitespace.json @@ -0,0 +1,36 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claims": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "start": 3, + "end": 25, + "text": "Alpha rose 5% in 2024." + } + ] + } + ], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__locate_some_dropped.json b/tests/fixtures/parity/canonical/extract__locate_some_dropped.json new file mode 100644 index 0000000..15e296a --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__locate_some_dropped.json @@ -0,0 +1,46 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claims": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "start": 0, + "end": 22, + "text": "Alpha rose 5% in 2024." + } + ] + }, + { + "claim": "Beta fell 3% last year.", + "positions": [ + { + "start": 23, + "end": 46, + "text": "Beta fell 3% last year." + } + ] + } + ], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__locate_true.json b/tests/fixtures/parity/canonical/extract__locate_true.json new file mode 100644 index 0000000..15e296a --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__locate_true.json @@ -0,0 +1,46 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claims": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "start": 0, + "end": 22, + "text": "Alpha rose 5% in 2024." + } + ] + }, + { + "claim": "Beta fell 3% last year.", + "positions": [ + { + "start": 23, + "end": 46, + "text": "Beta fell 3% last year." + } + ] + } + ], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__no_match_with_focus.json b/tests/fixtures/parity/canonical/extract__no_match_with_focus.json new file mode 100644 index 0000000..b3a7571 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__no_match_with_focus.json @@ -0,0 +1,16 @@ +{ + "status": 200, + "body": { + "status": "no_match", + "claims": [], + "domain": "", + "key_entities": [], + "presumed_intent": "", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__not_a_claim.json b/tests/fixtures/parity/canonical/extract__not_a_claim.json new file mode 100644 index 0000000..25e526b --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__not_a_claim.json @@ -0,0 +1,16 @@ +{ + "status": 200, + "body": { + "status": "no_checkable_claim", + "claims": [], + "domain": "", + "key_entities": [], + "presumed_intent": "", + "original_input": "What a lovely day." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__not_a_claim_beside_claims.json b/tests/fixtures/parity/canonical/extract__not_a_claim_beside_claims.json new file mode 100644 index 0000000..a0569d2 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__not_a_claim_beside_claims.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claims": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": null + } + ], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__ready_one_claim.json b/tests/fixtures/parity/canonical/extract__ready_one_claim.json new file mode 100644 index 0000000..a0569d2 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__ready_one_claim.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claims": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": null + } + ], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__ready_several_claims.json b/tests/fixtures/parity/canonical/extract__ready_several_claims.json new file mode 100644 index 0000000..a4ce206 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__ready_several_claims.json @@ -0,0 +1,34 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claims": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": null + }, + { + "claim": "Beta fell 3% last year.", + "positions": null + } + ], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__replay_later_200.json b/tests/fixtures/parity/canonical/extract__replay_later_200.json new file mode 100644 index 0000000..8f23ae8 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__replay_later_200.json @@ -0,0 +1,31 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claim": "Alpha rose 5% in 2024.", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "candidate_claims": [], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "locations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__url_fetch_502_unreadable.json b/tests/fixtures/parity/canonical/extract__url_fetch_502_unreadable.json new file mode 100644 index 0000000..645e6f6 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__url_fetch_502_unreadable.json @@ -0,0 +1,12 @@ +{ + "status": 502, + "body": { + "detail": "Extraction failed", + "code": "extraction_failed" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__url_fetch_503_upstream.json b/tests/fixtures/parity/canonical/extract__url_fetch_503_upstream.json new file mode 100644 index 0000000..182b135 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__url_fetch_503_upstream.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "The page could not be read right now. Please retry shortly.", + "code": "upstream_unavailable", + "retry_after": 90, + "docs_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/extract__url_input_located.json b/tests/fixtures/parity/canonical/extract__url_input_located.json new file mode 100644 index 0000000..dbed678 --- /dev/null +++ b/tests/fixtures/parity/canonical/extract__url_input_located.json @@ -0,0 +1,36 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claims": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "start": null, + "end": null, + "text": "Alpha rose 5% in 2024." + } + ] + } + ], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "https://example.com/an-article" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__401_no_credentials.json b/tests/fixtures/parity/canonical/review__401_no_credentials.json new file mode 100644 index 0000000..dcdaad0 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__401_no_credentials.json @@ -0,0 +1,12 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized", + "code": "not_authenticated" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__402_no_credits.json b/tests/fixtures/parity/canonical/review__402_no_credits.json new file mode 100644 index 0000000..7185c43 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__402_no_credits.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining credits to assess the draft.", + "code": "no_credits", + "docs_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 100, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 100, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__402_no_credits_exhausted.json b/tests/fixtures/parity/canonical/review__402_no_credits_exhausted.json new file mode 100644 index 0000000..543c798 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__402_no_credits_exhausted.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining credits to assess the draft.", + "code": "no_credits", + "docs_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_blank_text.json b/tests/fixtures/parity/canonical/review__422_blank_text.json new file mode 100644 index 0000000..784e798 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_blank_text.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "text: send the draft, or one public http(s) URL.", + "code": "blank_input", + "errors": [ + { + "loc": [ + "body", + "text" + ], + "msg": "text: send the draft, or one public http(s) URL.", + "type": "blank_input" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_citations_options_object.json b/tests/fixtures/parity/canonical/review__422_citations_options_object.json new file mode 100644 index 0000000..010e256 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_citations_options_object.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "citations: Extra inputs are not permitted", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "citations" + ], + "msg": "Extra inputs are not permitted", + "type": "extra_forbidden" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_depth_unknown.json b/tests/fixtures/parity/canonical/review__422_depth_unknown.json new file mode 100644 index 0000000..1bb9ce0 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_depth_unknown.json @@ -0,0 +1,27 @@ +{ + "status": 422, + "body": { + "detail": "escalate.depth: Input should be 'standard' or 'low'", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "depth" + ], + "msg": "Input should be 'standard' or 'low'", + "type": "literal_error", + "ctx": { + "expected": "'standard' or 'low'" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_invalid_confidence_band.json b/tests/fixtures/parity/canonical/review__422_invalid_confidence_band.json new file mode 100644 index 0000000..41fcbb5 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_invalid_confidence_band.json @@ -0,0 +1,27 @@ +{ + "status": 422, + "body": { + "detail": "escalate.confidence: Unknown confidence band 'certain'; use low, medium or high.", + "code": "invalid_confidence_band", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "confidence" + ], + "msg": "Unknown confidence band 'certain'; use low, medium or high.", + "type": "invalid_confidence_band", + "ctx": { + "band": "certain" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_invalid_verdict_label.json b/tests/fixtures/parity/canonical/review__422_invalid_verdict_label.json new file mode 100644 index 0000000..bb12352 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_invalid_verdict_label.json @@ -0,0 +1,28 @@ +{ + "status": 422, + "body": { + "detail": "escalate.verdicts: Unknown verdict label 'Misleading'; use one of: False, Mostly False, Mixed, Mostly True, True.", + "code": "invalid_verdict_label", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "verdicts" + ], + "msg": "Unknown verdict label 'Misleading'; use one of: False, Mostly False, Mixed, Mostly True, True.", + "type": "invalid_verdict_label", + "ctx": { + "label": "Misleading", + "labels": "False, Mostly False, Mixed, Mostly True, True" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_max_assessments_negative.json b/tests/fixtures/parity/canonical/review__422_max_assessments_negative.json new file mode 100644 index 0000000..401ea72 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_max_assessments_negative.json @@ -0,0 +1,27 @@ +{ + "status": 422, + "body": { + "detail": "escalate.max_assessments: Input should be greater than or equal to 0", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "max_assessments" + ], + "msg": "Input should be greater than or equal to 0", + "type": "greater_than_equal", + "ctx": { + "ge": 0 + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_max_citations_negative.json b/tests/fixtures/parity/canonical/review__422_max_citations_negative.json new file mode 100644 index 0000000..ff211d2 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_max_citations_negative.json @@ -0,0 +1,27 @@ +{ + "status": 422, + "body": { + "detail": "escalate.max_citations: Input should be greater than or equal to 0", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "max_citations" + ], + "msg": "Input should be greater than or equal to 0", + "type": "greater_than_equal", + "ctx": { + "ge": 0 + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_max_citations_too_big.json b/tests/fixtures/parity/canonical/review__422_max_citations_too_big.json new file mode 100644 index 0000000..4f44152 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_max_citations_too_big.json @@ -0,0 +1,27 @@ +{ + "status": 422, + "body": { + "detail": "escalate.max_citations: Input should be less than or equal to 20", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "max_citations" + ], + "msg": "Input should be less than or equal to 20", + "type": "less_than_equal", + "ctx": { + "le": 20 + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_max_verifications_too_big.json b/tests/fixtures/parity/canonical/review__422_max_verifications_too_big.json new file mode 100644 index 0000000..aabee59 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_max_verifications_too_big.json @@ -0,0 +1,27 @@ +{ + "status": 422, + "body": { + "detail": "escalate.max_verifications: Input should be less than or equal to 20", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "max_verifications" + ], + "msg": "Input should be less than or equal to 20", + "type": "less_than_equal", + "ctx": { + "le": 20 + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_text_missing.json b/tests/fixtures/parity/canonical/review__422_text_missing.json new file mode 100644 index 0000000..9ce0a7d --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_text_missing.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "text: Field required", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required", + "type": "missing" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_text_wrong_type.json b/tests/fixtures/parity/canonical/review__422_text_wrong_type.json new file mode 100644 index 0000000..7f77b76 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_text_wrong_type.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "text: Input should be a valid string", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Input should be a valid string", + "type": "string_type" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_unknown_escalate_field.json b/tests/fixtures/parity/canonical/review__422_unknown_escalate_field.json new file mode 100644 index 0000000..68067d4 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_unknown_escalate_field.json @@ -0,0 +1,24 @@ +{ + "status": 422, + "body": { + "detail": "escalate.nope: Extra inputs are not permitted", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "nope" + ], + "msg": "Extra inputs are not permitted", + "type": "extra_forbidden" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_unknown_top_level_field.json b/tests/fixtures/parity/canonical/review__422_unknown_top_level_field.json new file mode 100644 index 0000000..50ccb4b --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_unknown_top_level_field.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "max_verifications: Extra inputs are not permitted", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "max_verifications" + ], + "msg": "Extra inputs are not permitted", + "type": "extra_forbidden" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_unsupported_language.json b/tests/fixtures/parity/canonical/review__422_unsupported_language.json new file mode 100644 index 0000000..8a0ee14 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_unsupported_language.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "Unsupported language 'xx'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "code": "unsupported_language", + "errors": [ + { + "loc": [ + "body", + "language" + ], + "msg": "Unsupported language 'xx'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "type": "unsupported_language" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_visibility_public.json b/tests/fixtures/parity/canonical/review__422_visibility_public.json new file mode 100644 index 0000000..f266df2 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_visibility_public.json @@ -0,0 +1,26 @@ +{ + "status": 422, + "body": { + "detail": "visibility: Input should be 'private' or 'unlisted'", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "visibility" + ], + "msg": "Input should be 'private' or 'unlisted'", + "type": "literal_error", + "ctx": { + "expected": "'private' or 'unlisted'" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__422_webhook_secret_missing.json b/tests/fixtures/parity/canonical/review__422_webhook_secret_missing.json new file mode 100644 index 0000000..3286c6c --- /dev/null +++ b/tests/fixtures/parity/canonical/review__422_webhook_secret_missing.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.", + "code": "webhook_secret_missing", + "errors": [ + { + "loc": [ + "body", + "webhook_url" + ], + "msg": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.", + "type": "webhook_secret_missing" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__429_extract_daily_limit.json b/tests/fixtures/parity/canonical/review__429_extract_daily_limit.json new file mode 100644 index 0000000..7ea7dc9 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__429_extract_daily_limit.json @@ -0,0 +1,17 @@ +{ + "status": 429, + "body": { + "detail": "Daily /extract limit of 1000 reached for this account. A review of a URL reads the page like /extract and counts as one /extract call.", + "code": "extract_daily_limit", + "limit": 1000, + "retry_after": 60, + "docs_url": "https://lenz.io/docs/errors#rate-limits", + "upgrade_url": "https://lenz.io/plans" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "60", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__429_review_in_flight.json b/tests/fixtures/parity/canonical/review__429_review_in_flight.json new file mode 100644 index 0000000..906f29c --- /dev/null +++ b/tests/fixtures/parity/canonical/review__429_review_in_flight.json @@ -0,0 +1,14 @@ +{ + "status": 429, + "body": { + "detail": "This account already has 3 reviews running. Retry when one completes.", + "code": "review_in_flight", + "retry_after": 60 + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "60", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__503_capacity.json b/tests/fixtures/parity/canonical/review__503_capacity.json new file mode 100644 index 0000000..63b5d1c --- /dev/null +++ b/tests/fixtures/parity/canonical/review__503_capacity.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": 90, + "docs_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__503_citations_capacity.json b/tests/fixtures/parity/canonical/review__503_citations_capacity.json new file mode 100644 index 0000000..63b5d1c --- /dev/null +++ b/tests/fixtures/parity/canonical/review__503_citations_capacity.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": 90, + "docs_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__delete_not_a_route.json b/tests/fixtures/parity/canonical/review__delete_not_a_route.json new file mode 100644 index 0000000..7b3ec88 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__delete_not_a_route.json @@ -0,0 +1,12 @@ +{ + "status": 405, + "body": { + "detail": "Method not allowed.", + "code": "method_not_allowed" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_403_insufficient_scope.json b/tests/fixtures/parity/canonical/review__get_403_insufficient_scope.json new file mode 100644 index 0000000..b6b8f4f --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_403_insufficient_scope.json @@ -0,0 +1,14 @@ +{ + "status": 403, + "body": { + "detail": "The access token does not allow this call.", + "code": "insufficient_scope", + "scope": "history:read" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "WWW-Authenticate": "Bearer error=\"insufficient_scope\", scope=\"history:read\", resource_metadata=\"https://lenz.io/.well-known/oauth-protected-resource/api/v1\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_404_not_found.json b/tests/fixtures/parity/canonical/review__get_404_not_found.json new file mode 100644 index 0000000..e73d347 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_404_not_found.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Review not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_404_other_account.json b/tests/fixtures/parity/canonical/review__get_404_other_account.json new file mode 100644 index 0000000..e73d347 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_404_other_account.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Review not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_410_purged.json b/tests/fixtures/parity/canonical/review__get_410_purged.json new file mode 100644 index 0000000..396b15a --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_410_purged.json @@ -0,0 +1,13 @@ +{ + "status": 410, + "body": { + "detail": "This review is no longer available: its account removes content after a set period.", + "code": "purged", + "purged_at": "2026-10-01T09:07:00.123456Z" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_422_unknown_view.json b/tests/fixtures/parity/canonical/review__get_422_unknown_view.json new file mode 100644 index 0000000..70ef8e8 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_422_unknown_view.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "view: use full or issues.", + "code": "validation_error", + "errors": [ + { + "loc": [ + "query", + "view" + ], + "msg": "view: use full or issues.", + "type": "validation_error" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_assessing.json b/tests/fixtures/parity/canonical/review__get_assessing.json new file mode 100644 index 0000000..d43f14f --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_assessing.json @@ -0,0 +1,107 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "assessing", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 2, + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 0, + "failed": 0 + }, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": 10, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": null, + "assessment": { + "status": "running", + "verdict": null, + "confidence": null, + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": null, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": null, + "result": null, + "assessment": { + "status": "running", + "verdict": null, + "confidence": null, + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": null, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_assessment_rows_full_fields.json b/tests/fixtures/parity/canonical/review__get_assessment_rows_full_fields.json new file mode 100644 index 0000000..6b80bb6 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_assessment_rows_full_fields.json @@ -0,0 +1,169 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "incomplete", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 0, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 2, + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 1 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 1, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": null, + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "cap" + }, + "key_finding": null, + "rationale": "Two reviewers found the date wrong.", + "suggested_rewrite": "The EU AI Act entered into force in August 2024.", + "failure": null, + "suggested_edits": null + } + ], + "failures": [ + { + "claim_index": 1, + "claim": "The Eiffel Tower is in Berlin.", + "stage": "assessment", + "failure": { + "code": "timeout", + "detail": "The check did not finish inside its time budget.", + "hint": "The check ran out of time. Retry it; nothing was charged.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "assessment", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": "Two reviewers found the date wrong.", + "dissent": "One reviewer read the claim as about the entry into force.", + "suggested_rewrite": "The EU AI Act entered into force in August 2024.", + "more_claims": [ + "The EU AI Act took effect in 2024.", + "It took effect in March." + ], + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "cap" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": null, + "assessment": { + "status": "failed", + "verdict": null, + "confidence": null, + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": { + "code": "timeout", + "detail": "The check did not finish inside its time budget.", + "hint": "The check ran out of time. Retry it; nothing was charged.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": null + } + }, + "escalation": null, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_clean.json b/tests/fixtures/parity/canonical/review__get_citations_clean.json new file mode 100644 index 0000000..1b3c2fa --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_clean.json @@ -0,0 +1,182 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 3 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_failed_and_unchecked.json b/tests/fixtures/parity/canonical/review__get_citations_failed_and_unchecked.json new file mode 100644 index 0000000..37a0c3c --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_failed_and_unchecked.json @@ -0,0 +1,200 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "incomplete", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 0, + "unchecked": 1, + "failed": 1 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [ + { + "citation_index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": { + "code": "internal", + "detail": "The check failed on our side.", + "hint": "The check failed on our side. Try again later.", + "failure_class": "internal", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#internal" + } + } + ], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": null, + "check": { + "status": "failed", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": "The check failed on our side. Try again later.", + "failure": { + "code": "internal", + "detail": "The check failed on our side.", + "hint": "The check failed on our side. Try again later.", + "failure_class": "internal", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#internal" + }, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "unchecked", + "source": null, + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "unchecked", + "snippet": null, + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": "no_text", + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_issue_full.json b/tests/fixtures/parity/canonical/review__get_citations_issue_full.json new file mode 100644 index 0000000..a1f8a3d --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_issue_full.json @@ -0,0 +1,204 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 1, + "citations_skipped": null + }, + "credits": { + "charged": 3 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [ + { + "citation_index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "finding": "contradicted", + "source": "support", + "snippet": "The source says so.", + "rationale": "The page states it.", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "failure": null + } + ], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "contradicted", + "source": "support", + "is_issue": true + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "contradicted", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_issue_issues_view.json b/tests/fixtures/parity/canonical/review__get_citations_issue_issues_view.json new file mode 100644 index 0000000..a0c4e66 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_issue_issues_view.json @@ -0,0 +1,94 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "issues", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 1, + "citations_skipped": null + }, + "credits": { + "charged": 3 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [ + { + "citation_index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "finding": "contradicted", + "source": "support", + "snippet": "The source says so.", + "rationale": "The page states it.", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "failure": null + } + ], + "citation_failures": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_limit_exactly_at_limit.json b/tests/fixtures/parity/canonical/review__get_citations_limit_exactly_at_limit.json new file mode 100644 index 0000000..2ea4bba --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_limit_exactly_at_limit.json @@ -0,0 +1,182 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 2, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 3 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_limit_reached.json b/tests/fixtures/parity/canonical/review__get_citations_limit_reached.json new file mode 100644 index 0000000..2c9db6a --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_limit_reached.json @@ -0,0 +1,156 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 1, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 1, + "citation_limit": 1, + "citation_limit_exceeded": true, + "citation_checks": { + "checked": 1, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [ + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "sentence": "The agency said so in a statement.", + "position": { + "start": 111, + "end": 178, + "text": null + } + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_no_claim_but_citations.json b/tests/fixtures/parity/canonical/review__get_citations_no_claim_but_citations.json new file mode 100644 index 0000000..d0e9582 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_no_claim_but_citations.json @@ -0,0 +1,153 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_found": 0, + "claims_selected": 0, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 0, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_no_claim_no_citation.json b/tests/fixtures/parity/canonical/review__get_citations_no_claim_no_citation.json new file mode 100644 index 0000000..651f5ec --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_no_claim_no_citation.json @@ -0,0 +1,70 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_found": null, + "claims_selected": null, + "claim_limit": 20, + "claim_limit_exceeded": null, + "input_truncated": false, + "assessments": null, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": 20, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [], + "failure": { + "code": "no_checkable_claim", + "detail": "No claim in the input could be checked against public evidence.", + "hint": "No factual statement that can be checked against evidence was found in the input. Send one factual claim, or run the text through /extract to enumerate its claims.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "more_claims": null, + "more_claim_locations": null, + "more_citations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_not_asked.json b/tests/fixtures/parity/canonical/review__get_citations_not_asked.json new file mode 100644 index 0000000..4c5445d --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_not_asked.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_only.json b/tests/fixtures/parity/canonical/review__get_citations_only.json new file mode 100644 index 0000000..f642ad3 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_only.json @@ -0,0 +1,160 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 0, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 0, + "claim_limit": 0, + "claim_limit_exceeded": true, + "input_truncated": false, + "assessments": { + "completed": 0, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [ + "The EU AI Act took effect in March 2024." + ], + "more_claim_locations": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "positions": null + } + ], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_partly_supported.json b/tests/fixtures/parity/canonical/review__get_citations_partly_supported.json new file mode 100644 index 0000000..90d39af --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_partly_supported.json @@ -0,0 +1,182 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 3 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "partly_supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "partly_supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_running.json b/tests/fixtures/parity/canonical/review__get_citations_running.json new file mode 100644 index 0000000..65040d3 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_running.json @@ -0,0 +1,166 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "verifying", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 0, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": 15, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": null, + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "pending", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": null, + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "pending", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_skipped_switched_off.json b/tests/fixtures/parity/canonical/review__get_citations_skipped_switched_off.json new file mode 100644 index 0000000..d7c7c4a --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_skipped_switched_off.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": 20, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": "switched_off" + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_citations_skipped_url_input.json b/tests/fixtures/parity/canonical/review__get_citations_skipped_url_input.json new file mode 100644 index 0000000..4cd763c --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_citations_skipped_url_input.json @@ -0,0 +1,70 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_found": null, + "claims_selected": null, + "claim_limit": 20, + "claim_limit_exceeded": null, + "input_truncated": false, + "assessments": null, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": 20, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": "url_input" + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [], + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": null, + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + }, + "more_claims": null, + "more_claim_locations": null, + "more_citations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_claim_limit_not_reached.json b/tests/fixtures/parity/canonical/review__get_claim_limit_not_reached.json new file mode 100644 index 0000000..1e92f55 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_claim_limit_not_reached.json @@ -0,0 +1,127 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 3, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 2, + "claims_selected": 2, + "claim_limit": 3, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_claim_limit_reached_exact.json b/tests/fixtures/parity/canonical/review__get_claim_limit_reached_exact.json new file mode 100644 index 0000000..1d1c6fc --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_claim_limit_reached_exact.json @@ -0,0 +1,127 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 2, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 2, + "claims_selected": 2, + "claim_limit": 2, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_completed_assess_only.json b/tests/fixtures/parity/canonical/review__get_completed_assess_only.json new file mode 100644 index 0000000..2f25c1e --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_completed_assess_only.json @@ -0,0 +1,153 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 0, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 2, + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 1, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 1, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": null, + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "cap" + }, + "key_finding": null, + "rationale": null, + "suggested_rewrite": null, + "failure": null, + "suggested_edits": null + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "assessment", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "cap" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_completed_clean.json b/tests/fixtures/parity/canonical/review__get_completed_clean.json new file mode 100644 index 0000000..3bf1368 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_completed_clean.json @@ -0,0 +1,127 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 2, + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Paris is the capital of France.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_completed_issues_all_verified.json b/tests/fixtures/parity/canonical/review__get_completed_issues_all_verified.json new file mode 100644 index 0000000..015cbce --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_completed_issues_all_verified.json @@ -0,0 +1,256 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 3, + "claims_selected": 3, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 3, + "failed": 0 + }, + "verifications": { + "planned": 2, + "completed": 2, + "failed": 0 + }, + "issues": 2, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 23 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "rationale": null, + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "failure": null, + "suggested_edits": null + }, + { + "claim_index": 1, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "4d44dfaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/4d44dfaf", + "url": "https://lenz.io/c/the-earth-is-round-4d44dfaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "failure": null, + "suggested_edits": null + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "Mostly False", + "confidence": "medium", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "claim": "The EU AI Act took effect in March 2024.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "executive_summary": "Summary for The EU AI Act took effect in March 2024.", + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T09:14:00.123456+00:00", + "completed_at": "2026-10-01T09:14:00.123456+00:00", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "failure": null + }, + "suggested_edits": null + }, + { + "index": 1, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "verification_id": "4d44dfaf", + "claim": "The Eiffel Tower is in Berlin.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T09:14:00.123456+00:00", + "completed_at": "2026-10-01T09:14:00.123456+00:00", + "verification_url": "https://lenz.io/api/v1/verifications/4d44dfaf", + "url": "https://lenz.io/c/the-earth-is-round-4d44dfaf", + "failure": null + }, + "suggested_edits": null + }, + { + "index": 2, + "claim": "Paris is the capital of France.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_completed_issues_full.json b/tests/fixtures/parity/canonical/review__get_completed_issues_full.json new file mode 100644 index 0000000..4e497ee --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_completed_issues_full.json @@ -0,0 +1,309 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "incomplete", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 4, + "claims_selected": 4, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 3, + "failed": 1 + }, + "verifications": { + "planned": 2, + "completed": 1, + "failed": 1 + }, + "issues": 2, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 13 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "rationale": null, + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "failure": null, + "suggested_edits": null + }, + { + "claim_index": 2, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": "failed", + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": null, + "rationale": null, + "suggested_rewrite": null, + "failure": { + "code": "research_empty", + "detail": "No sources about the claim were found.", + "hint": null, + "failure_class": "insufficient_evidence", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence" + }, + "suggested_edits": null + } + ], + "failures": [ + { + "claim_index": 1, + "claim": "Water boils at 100 C at sea level.", + "stage": "assessment", + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + } + ], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "Mostly False", + "confidence": "medium", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "claim": "The EU AI Act took effect in March 2024.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "executive_summary": "Summary for The EU AI Act took effect in March 2024.", + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T09:14:00.123456+00:00", + "completed_at": "2026-10-01T09:14:00.123456+00:00", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "failure": null + }, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": null, + "result": null, + "assessment": { + "status": "failed", + "verdict": null, + "confidence": null, + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + "escalation": null, + "verification": null, + "suggested_edits": null + }, + { + "index": 2, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "assessment", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "verification_id": null, + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "claim": null, + "language": null, + "visibility": null, + "depth": null, + "domain": null, + "entities": [], + "verdict": null, + "confidence": null, + "lenz_score": null, + "key_finding": null, + "executive_summary": null, + "suggested_rewrite": null, + "warnings": [], + "created_at": null, + "completed_at": null, + "verification_url": null, + "url": null, + "failure": { + "code": "research_empty", + "detail": "No sources about the claim were found.", + "hint": null, + "failure_class": "insufficient_evidence", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence" + }, + "status": "failed", + "content_status": "available" + }, + "suggested_edits": null + }, + { + "index": 3, + "claim": "Paris is the capital of France.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_completed_issues_view_issues.json b/tests/fixtures/parity/canonical/review__get_completed_issues_view_issues.json new file mode 100644 index 0000000..73cb5d3 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_completed_issues_view_issues.json @@ -0,0 +1,136 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "issues", + "status": "completed", + "outcome": "incomplete", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 4, + "claims_selected": 4, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 3, + "failed": 1 + }, + "verifications": { + "planned": 2, + "completed": 1, + "failed": 1 + }, + "issues": 2, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 13 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "rationale": null, + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "failure": null, + "suggested_edits": null + }, + { + "claim_index": 2, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": "failed", + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": null, + "rationale": null, + "suggested_rewrite": null, + "failure": { + "code": "research_empty", + "detail": "No sources about the claim were found.", + "hint": null, + "failure_class": "insufficient_evidence", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence" + }, + "suggested_edits": null + } + ], + "failures": [ + { + "claim_index": 1, + "claim": "Water boils at 100 C at sea level.", + "stage": "assessment", + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_completed_positions.json b/tests/fixtures/parity/canonical/review__get_completed_positions.json new file mode 100644 index 0000000..94542c7 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_completed_positions.json @@ -0,0 +1,139 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 2, + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": [ + { + "start": 0, + "end": 40, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": [ + { + "start": 55, + "end": 89, + "text": "Water boils at 100 C at sea level." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_completed_recovered_claim.json b/tests/fixtures/parity/canonical/review__get_completed_recovered_claim.json new file mode 100644 index 0000000..00ba6b6 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_completed_recovered_claim.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "Orbit Motors stock increased by 40% in 2022.", + "positions": [], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_completed_with_untraced_claim.json b/tests/fixtures/parity/canonical/review__get_completed_with_untraced_claim.json new file mode 100644 index 0000000..39a95cd --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_completed_with_untraced_claim.json @@ -0,0 +1,139 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 2, + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": [ + { + "start": 0, + "end": 40, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": [ + { + "start": 50, + "end": 84, + "text": "Water boils at 100 C at sea level." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_during_quick_check.json b/tests/fixtures/parity/canonical/review__get_during_quick_check.json new file mode 100644 index 0000000..ecff88a --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_during_quick_check.json @@ -0,0 +1,87 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "assessing", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 0, + "failed": 0 + }, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": 10, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": null, + "assessment": { + "status": "running", + "verdict": null, + "confidence": null, + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": null, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_failed_every_assessment_failed.json b/tests/fixtures/parity/canonical/review__get_failed_every_assessment_failed.json new file mode 100644 index 0000000..b66ecb1 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_failed_every_assessment_failed.json @@ -0,0 +1,159 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "failed", + "outcome": "incomplete", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 2, + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 0, + "failed": 2 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [ + { + "claim_index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "stage": "assessment", + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + { + "claim_index": 1, + "claim": "Water boils at 100 C at sea level.", + "stage": "assessment", + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + } + ], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": null, + "assessment": { + "status": "failed", + "verdict": null, + "confidence": null, + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + "escalation": null, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": null, + "result": null, + "assessment": { + "status": "failed", + "verdict": null, + "confidence": null, + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": { + "code": "upstream_unavailable", + "detail": "A service the check depends on was unavailable.", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + "escalation": null, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": { + "code": "assessment_failed", + "detail": "No claim could be assessed.", + "hint": "Retry the review with a new Idempotency-Key; nothing was charged.", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + }, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_failed_no_claim.json b/tests/fixtures/parity/canonical/review__get_failed_no_claim.json new file mode 100644 index 0000000..a21cf53 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_failed_no_claim.json @@ -0,0 +1,70 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": null, + "claims_selected": null, + "claim_limit": 20, + "claim_limit_exceeded": null, + "input_truncated": false, + "assessments": null, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [], + "failure": { + "code": "no_checkable_claim", + "detail": "No claim in the input could be checked against public evidence.", + "hint": "The text is a greeting, not a statement about the world. Send one factual claim, or run the text through /extract to enumerate its claims.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "more_claims": null, + "more_claim_locations": null, + "more_citations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_failed_no_claim_untraced.json b/tests/fixtures/parity/canonical/review__get_failed_no_claim_untraced.json new file mode 100644 index 0000000..776ba8a --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_failed_no_claim_untraced.json @@ -0,0 +1,70 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": null, + "claims_selected": null, + "claim_limit": 20, + "claim_limit_exceeded": null, + "input_truncated": false, + "assessments": null, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [], + "failure": { + "code": "no_checkable_claim", + "detail": "No claim in the input could be checked against public evidence.", + "hint": "None of the claims found in the text could be traced back to it. Send one factual claim, or run the text through /extract to enumerate its claims.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "more_claims": null, + "more_claim_locations": null, + "more_citations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_more_claims.json b/tests/fixtures/parity/canonical/review__get_more_claims.json new file mode 100644 index 0000000..798f568 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_more_claims.json @@ -0,0 +1,152 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 2, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 3, + "claims_selected": 2, + "claim_limit": 2, + "claim_limit_exceeded": true, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": [ + { + "start": 0, + "end": 40, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": [ + { + "start": 50, + "end": 84, + "text": "Water boils at 100 C at sea level." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [ + "The Eiffel Tower is in Berlin." + ], + "more_claim_locations": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "positions": [ + { + "start": 91, + "end": 121, + "text": "The Eiffel Tower is in Berlin." + } + ] + } + ], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_nested_verification_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/canonical/review__get_nested_verification_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..7f34405 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_nested_verification_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,150 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 1, + "completed": 1, + "failed": 0 + }, + "issues": 1, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 11 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "failure": null, + "suggested_edits": null + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T23:55:00.123456+00:00", + "completed_at": "2026-10-02T00:03:00.123456+00:00", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "failure": null + }, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_nested_verification_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/canonical/review__get_nested_verification_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..8295eb7 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_nested_verification_modified_at_same_day_hours_apart.json @@ -0,0 +1,150 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 1, + "completed": 1, + "failed": 0 + }, + "issues": 1, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 11 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "failure": null, + "suggested_edits": null + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T08:00:00.123456+00:00", + "completed_at": "2026-10-01T20:00:00.123456+00:00", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "failure": null + }, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_policy_resolved.json b/tests/fixtures/parity/canonical/review__get_policy_resolved.json new file mode 100644 index 0000000..7d2074b --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_policy_resolved.json @@ -0,0 +1,97 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 2, + "depth": "low", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_queued.json b/tests/fixtures/parity/canonical/review__get_queued.json new file mode 100644 index 0000000..70a4825 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_queued.json @@ -0,0 +1,63 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "queued", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": null, + "claims_selected": null, + "claim_limit": 20, + "claim_limit_exceeded": null, + "input_truncated": false, + "assessments": null, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": 10, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [], + "failure": null, + "more_claims": null, + "more_claim_locations": null, + "more_citations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_suggested_edits.json b/tests/fixtures/parity/canonical/review__get_suggested_edits.json new file mode 100644 index 0000000..0bfdfa3 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_suggested_edits.json @@ -0,0 +1,266 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "verifying", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "suggest_edits": true, + "max_citations": 0 + }, + "summary": { + "claims_found": 2, + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 2, + "completed": 1, + "failed": 0 + }, + "issues": 2, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 12 + }, + "poll_after_seconds": 15, + "issues": [ + { + "claim_index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "failure": null, + "suggested_edits": { + "status": "completed", + "edits": [ + { + "position": 0, + "start": 23, + "end": 29, + "text": "Berlin", + "replacement": "Paris" + } + ] + } + }, + { + "claim_index": 1, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": "processing", + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": null, + "rationale": null, + "suggested_rewrite": null, + "failure": null, + "suggested_edits": { + "status": "pending", + "edits": null + } + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "positions": [ + { + "start": 0, + "end": 30, + "text": "The Eiffel Tower is in Berlin." + } + ], + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T09:14:00.123456+00:00", + "completed_at": "2026-10-01T09:14:00.123456+00:00", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "failure": null + }, + "suggested_edits": { + "status": "completed", + "edits": [ + { + "position": 0, + "start": 23, + "end": 29, + "text": "Berlin", + "replacement": "Paris" + } + ] + } + }, + { + "index": 1, + "claim": "The EU AI Act took effect in March 2024.", + "positions": [ + { + "start": 45, + "end": 85, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "verdict": "False", + "confidence": "high", + "source": "assessment", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "processing", + "content_status": "available", + "verification_id": null, + "task_id": null, + "claim": null, + "language": null, + "visibility": null, + "depth": null, + "domain": null, + "entities": [], + "verdict": null, + "confidence": null, + "lenz_score": null, + "key_finding": null, + "executive_summary": null, + "suggested_rewrite": null, + "warnings": [], + "created_at": null, + "completed_at": null, + "verification_url": null, + "url": null, + "failure": null + }, + "suggested_edits": { + "status": "pending", + "edits": null + } + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_suggested_edits_issues_view.json b/tests/fixtures/parity/canonical/review__get_suggested_edits_issues_view.json new file mode 100644 index 0000000..5d39a66 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_suggested_edits_issues_view.json @@ -0,0 +1,129 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "issues", + "status": "verifying", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "suggest_edits": true, + "max_citations": 0 + }, + "summary": { + "claims_found": 2, + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 2, + "completed": 1, + "failed": 0 + }, + "issues": 2, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 12 + }, + "poll_after_seconds": 15, + "issues": [ + { + "claim_index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "failure": null, + "suggested_edits": { + "status": "completed", + "edits": [ + { + "position": 0, + "start": 23, + "end": 29, + "text": "Berlin", + "replacement": "Paris" + } + ] + } + }, + { + "claim_index": 1, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": "processing", + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": null, + "rationale": null, + "suggested_rewrite": null, + "failure": null, + "suggested_edits": { + "status": "pending", + "edits": null + } + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_url_review.json b/tests/fixtures/parity/canonical/review__get_url_review.json new file mode 100644 index 0000000..9dabe53 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_url_review.json @@ -0,0 +1,105 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": [ + { + "start": null, + "end": null, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__get_verifying.json b/tests/fixtures/parity/canonical/review__get_verifying.json new file mode 100644 index 0000000..f49c966 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__get_verifying.json @@ -0,0 +1,176 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "verifying", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 2, + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 1, + "completed": 0, + "failed": 0 + }, + "issues": 1, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": 15, + "issues": [ + { + "claim_index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": "processing", + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": null, + "rationale": null, + "suggested_rewrite": null, + "failure": null, + "suggested_edits": null + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "assessment", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "processing", + "content_status": "available", + "verification_id": null, + "task_id": null, + "claim": null, + "language": null, + "visibility": null, + "depth": null, + "domain": null, + "entities": [], + "verdict": null, + "confidence": null, + "lenz_score": null, + "key_finding": null, + "executive_summary": null, + "suggested_rewrite": null, + "warnings": [], + "created_at": null, + "completed_at": null, + "verification_url": null, + "url": null, + "failure": null + }, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__idempotency_body_mismatch_422.json b/tests/fixtures/parity/canonical/review__idempotency_body_mismatch_422.json new file mode 100644 index 0000000..8cdd4be --- /dev/null +++ b/tests/fixtures/parity/canonical/review__idempotency_body_mismatch_422.json @@ -0,0 +1,12 @@ +{ + "status": 422, + "body": { + "detail": "Idempotency-Key reused with a different request body.", + "code": "idempotency_body_mismatch" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__idempotency_conflict_409.json b/tests/fixtures/parity/canonical/review__idempotency_conflict_409.json new file mode 100644 index 0000000..e0a63b2 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__idempotency_conflict_409.json @@ -0,0 +1,13 @@ +{ + "status": 409, + "body": { + "detail": "A review with this Idempotency-Key is still being created. Retry shortly.", + "code": "idempotency_conflict", + "review_id": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__idempotency_conflict_409_existing_review.json b/tests/fixtures/parity/canonical/review__idempotency_conflict_409_existing_review.json new file mode 100644 index 0000000..e91fe17 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__idempotency_conflict_409_existing_review.json @@ -0,0 +1,13 @@ +{ + "status": 409, + "body": { + "detail": "A review with this Idempotency-Key is still being created. Retry shortly.", + "code": "idempotency_conflict", + "review_id": "d6b2bd72" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__idempotent_replay_202.json b/tests/fixtures/parity/canonical/review__idempotent_replay_202.json new file mode 100644 index 0000000..ea99cf8 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__idempotent_replay_202.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/reviews/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__receipt_202.json b/tests/fixtures/parity/canonical/review__receipt_202.json new file mode 100644 index 0000000..ea99cf8 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__receipt_202.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/reviews/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__receipt_202_empty_webhook_url.json b/tests/fixtures/parity/canonical/review__receipt_202_empty_webhook_url.json new file mode 100644 index 0000000..ea99cf8 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__receipt_202_empty_webhook_url.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/reviews/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__receipt_202_webhook_url.json b/tests/fixtures/parity/canonical/review__receipt_202_webhook_url.json new file mode 100644 index 0000000..ea99cf8 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__receipt_202_webhook_url.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/reviews/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/review__replay_later_202.json b/tests/fixtures/parity/canonical/review__replay_later_202.json new file mode 100644 index 0000000..ea99cf8 --- /dev/null +++ b/tests/fixtures/parity/canonical/review__replay_later_202.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/reviews/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__batch_202.json b/tests/fixtures/parity/canonical/verify__batch_202.json new file mode 100644 index 0000000..654ab00 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__batch_202.json @@ -0,0 +1,21 @@ +{ + "status": 202, + "body": { + "batch_id": "7ea9cdbd4064e3cf", + "items": [ + { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "claim": "The Earth is round." + }, + { + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "claim": "Water boils at 100C at sea level." + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__batch_capacity_503.json b/tests/fixtures/parity/canonical/verify__batch_capacity_503.json new file mode 100644 index 0000000..0994e62 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__batch_capacity_503.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": "", + "docs_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__batch_empty_422.json b/tests/fixtures/parity/canonical/verify__batch_empty_422.json new file mode 100644 index 0000000..59dd9ca --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__batch_empty_422.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "claims is required and must be non-empty.", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "claims" + ], + "msg": "claims is required and must be non-empty.", + "type": "validation_error" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__batch_idempotency_conflict_409.json b/tests/fixtures/parity/canonical/verify__batch_idempotency_conflict_409.json new file mode 100644 index 0000000..dc881a8 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__batch_idempotency_conflict_409.json @@ -0,0 +1,13 @@ +{ + "status": 409, + "body": { + "detail": "A request with this Idempotency-Key is already in progress.", + "code": "idempotency_conflict", + "task_id": "7cff18d" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__batch_item_missing_claim_422.json b/tests/fixtures/parity/canonical/verify__batch_item_missing_claim_422.json new file mode 100644 index 0000000..0e736d5 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__batch_item_missing_claim_422.json @@ -0,0 +1,25 @@ +{ + "status": 422, + "body": { + "detail": "claims[1].claim: Field required", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "claims", + 1, + "text" + ], + "msg": "Field required", + "type": "missing" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__batch_no_credits_402.json b/tests/fixtures/parity/canonical/verify__batch_no_credits_402.json new file mode 100644 index 0000000..216b4ba --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__batch_no_credits_402.json @@ -0,0 +1,20 @@ +{ + "status": 402, + "body": { + "detail": "Insufficient credits for batch.", + "code": "no_credits", + "docs_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "requested": 1, + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 10 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__batch_partial_202.json b/tests/fixtures/parity/canonical/verify__batch_partial_202.json new file mode 100644 index 0000000..f3bb45d --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__batch_partial_202.json @@ -0,0 +1,18 @@ +{ + "status": 202, + "body": { + "batch_id": "7ea9cdbd4064e3cf", + "items": [ + { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "claim": "First claim." + } + ], + "partial": true + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__batch_too_many_422.json b/tests/fixtures/parity/canonical/verify__batch_too_many_422.json new file mode 100644 index 0000000..b239559 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__batch_too_many_422.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "Batch size exceeds maximum of 20.", + "code": "too_many_items", + "errors": [ + { + "loc": [ + "body", + "claims" + ], + "msg": "Batch size exceeds maximum of 20.", + "type": "too_many_items" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__blank_claim_422.json b/tests/fixtures/parity/canonical/verify__blank_claim_422.json new file mode 100644 index 0000000..bfcc575 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__blank_claim_422.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "claim is required.", + "code": "blank_input", + "errors": [ + { + "loc": [ + "body", + "claim" + ], + "msg": "claim is required.", + "type": "blank_input" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__capacity_503.json b/tests/fixtures/parity/canonical/verify__capacity_503.json new file mode 100644 index 0000000..0994e62 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__capacity_503.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": "", + "docs_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__delete_200.json b/tests/fixtures/parity/canonical/verify__delete_200.json new file mode 100644 index 0000000..cddadae --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__delete_200.json @@ -0,0 +1,11 @@ +{ + "status": 200, + "body": { + "ok": true + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__delete_404.json b/tests/fixtures/parity/canonical/verify__delete_404.json new file mode 100644 index 0000000..775d847 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__delete_404.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__delete_not_yours_404.json b/tests/fixtures/parity/canonical/verify__delete_not_yours_404.json new file mode 100644 index 0000000..775d847 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__delete_not_yours_404.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__idempotency_body_mismatch_422.json b/tests/fixtures/parity/canonical/verify__idempotency_body_mismatch_422.json new file mode 100644 index 0000000..8cdd4be --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__idempotency_body_mismatch_422.json @@ -0,0 +1,12 @@ +{ + "status": 422, + "body": { + "detail": "Idempotency-Key reused with a different request body.", + "code": "idempotency_body_mismatch" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__idempotency_conflict_409.json b/tests/fixtures/parity/canonical/verify__idempotency_conflict_409.json new file mode 100644 index 0000000..87958d2 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__idempotency_conflict_409.json @@ -0,0 +1,13 @@ +{ + "status": 409, + "body": { + "detail": "A request with this Idempotency-Key is already in progress.", + "code": "idempotency_conflict", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__idempotency_key_replay.json b/tests/fixtures/parity/canonical/verify__idempotency_key_replay.json new file mode 100644 index 0000000..d47aeaf --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__idempotency_key_replay.json @@ -0,0 +1,12 @@ +{ + "status": 202, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__implicit_dedup_200.json b/tests/fixtures/parity/canonical/verify__implicit_dedup_200.json new file mode 100644 index 0000000..d47aeaf --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__implicit_dedup_200.json @@ -0,0 +1,12 @@ +{ + "status": 202, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__implicit_repeat_replay.json b/tests/fixtures/parity/canonical/verify__implicit_repeat_replay.json new file mode 100644 index 0000000..d47aeaf --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__implicit_repeat_replay.json @@ -0,0 +1,12 @@ +{ + "status": 202, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__invalid_depth_422.json b/tests/fixtures/parity/canonical/verify__invalid_depth_422.json new file mode 100644 index 0000000..3cf1746 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__invalid_depth_422.json @@ -0,0 +1,26 @@ +{ + "status": 422, + "body": { + "detail": "depth: Input should be 'standard' or 'low'", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "depth" + ], + "msg": "Input should be 'standard' or 'low'", + "type": "literal_error", + "ctx": { + "expected": "'standard' or 'low'" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__invalid_language_422.json b/tests/fixtures/parity/canonical/verify__invalid_language_422.json new file mode 100644 index 0000000..7025ff2 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__invalid_language_422.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "Unsupported language 'xx-not-a-language'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "code": "unsupported_language", + "errors": [ + { + "loc": [ + "body", + "language" + ], + "msg": "Unsupported language 'xx-not-a-language'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "type": "unsupported_language" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__list_200.json b/tests/fixtures/parity/canonical/verify__list_200.json new file mode 100644 index 0000000..335daa4 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__list_200.json @@ -0,0 +1,45 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "language": "en" + }, + { + "verification_id": "4d44dfaf", + "claim": "The Earth is round.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:14:00.123456+00:00", + "completed_at": "2026-10-01T09:14:00.123456+00:00", + "language": "en" + } + ], + "total": 2, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__list_200_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/canonical/verify__list_200_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..ed48dbb --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__list_200_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "completed_at": "2026-10-02T00:03:00.123456+00:00", + "language": "en" + } + ], + "total": 1, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__list_200_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/canonical/verify__list_200_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..0c50625 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__list_200_modified_at_same_day_hours_apart.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "completed_at": "2026-10-01T20:00:00.123456+00:00", + "language": "en" + } + ], + "total": 1, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__list_clamped_200.json b/tests/fixtures/parity/canonical/verify__list_clamped_200.json new file mode 100644 index 0000000..c208418 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__list_clamped_200.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "items": [], + "total": 0, + "page": 1, + "page_size": 100 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__list_empty_200.json b/tests/fixtures/parity/canonical/verify__list_empty_200.json new file mode 100644 index 0000000..406be8e --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__list_empty_200.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "items": [], + "total": 0, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__list_page2_200.json b/tests/fixtures/parity/canonical/verify__list_page2_200.json new file mode 100644 index 0000000..6008819 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__list_page2_200.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "language": "en" + } + ], + "total": 3, + "page": 2, + "page_size": 2 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__misnamed_field_422.json b/tests/fixtures/parity/canonical/verify__misnamed_field_422.json new file mode 100644 index 0000000..381ab3e --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__misnamed_field_422.json @@ -0,0 +1,28 @@ +{ + "status": 422, + "body": { + "detail": "claim: Field required", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required", + "type": "missing" + } + ], + "hint": "Required field 'claim' is missing. Unrecognised fields: statement.", + "docs_url": "https://lenz.io/docs/errors#validation", + "unrecognized_fields": [ + "statement" + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__missing_claim_422.json b/tests/fixtures/parity/canonical/verify__missing_claim_422.json new file mode 100644 index 0000000..f5b9868 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__missing_claim_422.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "claim: Field required", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required", + "type": "missing" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__no_credits_402.json b/tests/fixtures/parity/canonical/verify__no_credits_402.json new file mode 100644 index 0000000..d93b382 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__no_credits_402.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining claim checks.", + "code": "no_credits", + "docs_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 10 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__replay_later_202.json b/tests/fixtures/parity/canonical/verify__replay_later_202.json new file mode 100644 index 0000000..1991e8a --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__replay_later_202.json @@ -0,0 +1,13 @@ +{ + "status": 202, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued", + "chain_id": "99a0a9ca89e1e72c" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__select_202.json b/tests/fixtures/parity/canonical/verify__select_202.json new file mode 100644 index 0000000..654ab00 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__select_202.json @@ -0,0 +1,21 @@ +{ + "status": 202, + "body": { + "batch_id": "7ea9cdbd4064e3cf", + "items": [ + { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "claim": "The Earth is round." + }, + { + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "claim": "Water boils at 100C at sea level." + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__select_empty_422.json b/tests/fixtures/parity/canonical/verify__select_empty_422.json new file mode 100644 index 0000000..bab491b --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__select_empty_422.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "claims is required.", + "code": "blank_input", + "errors": [ + { + "loc": [ + "body", + "claims" + ], + "msg": "claims is required.", + "type": "blank_input" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__select_invalid_selection_422.json b/tests/fixtures/parity/canonical/verify__select_invalid_selection_422.json new file mode 100644 index 0000000..7099c4a --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__select_invalid_selection_422.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "Selected text was not one of the offered claims: 'The Moon is made of cheese.'", + "code": "invalid_selection", + "errors": [ + { + "loc": [ + "body", + "claims" + ], + "msg": "Selected text was not one of the offered claims: 'The Moon is made of cheese.'", + "type": "invalid_selection" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__select_no_selection_pending_409.json b/tests/fixtures/parity/canonical/verify__select_no_selection_pending_409.json new file mode 100644 index 0000000..47d776a --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__select_no_selection_pending_409.json @@ -0,0 +1,12 @@ +{ + "status": 409, + "body": { + "detail": "This task has no pending claim selection.", + "code": "no_selection_pending" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__select_too_many_422.json b/tests/fixtures/parity/canonical/verify__select_too_many_422.json new file mode 100644 index 0000000..cf16deb --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__select_too_many_422.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "Cannot select more than 20 claims.", + "code": "too_many_items", + "errors": [ + { + "loc": [ + "body", + "claims" + ], + "msg": "Cannot select more than 20 claims.", + "type": "too_many_items" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__select_unknown_task_404.json b/tests/fixtures/parity/canonical/verify__select_unknown_task_404.json new file mode 100644 index 0000000..8c0eaee --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__select_unknown_task_404.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Task not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_cancelled_after_a_while.json b/tests/fixtures/parity/canonical/verify__status_cancelled_after_a_while.json new file mode 100644 index 0000000..40ec53e --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_cancelled_after_a_while.json @@ -0,0 +1,20 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "cancelled", + "detail": "The check was cancelled.", + "hint": null, + "failure_class": "cancelled", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#cancelled" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_completed.json b/tests/fixtures/parity/canonical/verify__status_completed.json new file mode 100644 index 0000000..4cdad25 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_completed.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_completed_after_a_while.json b/tests/fixtures/parity/canonical/verify__status_completed_after_a_while.json new file mode 100644 index 0000000..4cdad25 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_completed_after_a_while.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_completed_after_a_while_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/canonical/verify__status_completed_after_a_while_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..df91232 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_completed_after_a_while_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "completed_at": "2026-10-02T00:03:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_completed_after_a_while_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/canonical/verify__status_completed_after_a_while_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..7d239be --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_completed_after_a_while_modified_at_same_day_hours_apart.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "completed_at": "2026-10-01T20:00:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_completed_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/canonical/verify__status_completed_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..df91232 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_completed_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "completed_at": "2026-10-02T00:03:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_completed_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/canonical/verify__status_completed_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..7d239be --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_completed_modified_at_same_day_hours_apart.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "completed_at": "2026-10-01T20:00:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_failed.json b/tests/fixtures/parity/canonical/verify__status_failed.json new file mode 100644 index 0000000..cc029a3 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_failed.json @@ -0,0 +1,20 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "research_empty", + "detail": "No sources about the claim were found.", + "hint": null, + "failure_class": "insufficient_evidence", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_failed_after_a_while.json b/tests/fixtures/parity/canonical/verify__status_failed_after_a_while.json new file mode 100644 index 0000000..c3694b4 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_failed_after_a_while.json @@ -0,0 +1,20 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "conclusion_failed", + "detail": "The check stopped while writing the conclusion.", + "hint": null, + "failure_class": "internal", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#internal" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_failed_after_a_while_framing.json b/tests/fixtures/parity/canonical/verify__status_failed_after_a_while_framing.json new file mode 100644 index 0000000..1774968 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_failed_after_a_while_framing.json @@ -0,0 +1,20 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "framing_failed", + "detail": "The input could not be read as a claim.", + "hint": null, + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_failed_retryable.json b/tests/fixtures/parity/canonical/verify__status_failed_retryable.json new file mode 100644 index 0000000..4fafcc9 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_failed_retryable.json @@ -0,0 +1,20 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "adjudication_failed", + "detail": "The check stopped while the reviewers scored the evidence.", + "hint": null, + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_needs_input.json b/tests/fixtures/parity/canonical/verify__status_needs_input.json new file mode 100644 index 0000000..59a23c4 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_needs_input.json @@ -0,0 +1,24 @@ +{ + "status": 200, + "body": { + "status": "needs_input", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "reason": "multi_claim", + "claims": [ + { + "claim": "The Earth is round.", + "domain": "Science" + }, + { + "claim": "Water boils at 100C at sea level.", + "domain": "Science" + } + ], + "hint": "The text holds several distinct claims. Send the ones to check to POST /verify/{task_id}/select." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_not_a_claim.json b/tests/fixtures/parity/canonical/verify__status_not_a_claim.json new file mode 100644 index 0000000..335bb1b --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_not_a_claim.json @@ -0,0 +1,20 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "no_checkable_claim", + "detail": "No claim in the input could be checked against public evidence.", + "hint": "The input is a greeting, not a statement that can be checked. Send one factual claim, or run the text through /extract to enumerate its claims.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_not_a_claim_after_a_while.json b/tests/fixtures/parity/canonical/verify__status_not_a_claim_after_a_while.json new file mode 100644 index 0000000..771ab68 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_not_a_claim_after_a_while.json @@ -0,0 +1,20 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "no_checkable_claim", + "detail": "No claim in the input could be checked against public evidence.", + "hint": "No factual statement that can be checked against evidence was found in the input. Send one factual claim, or run the text through /extract to enumerate its claims.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_not_yours_404.json b/tests/fixtures/parity/canonical/verify__status_not_yours_404.json new file mode 100644 index 0000000..8c0eaee --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_not_yours_404.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Task not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_older_run_completed.json b/tests/fixtures/parity/canonical/verify__status_older_run_completed.json new file mode 100644 index 0000000..4cdad25 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_older_run_completed.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_older_run_failed_crashed.json b/tests/fixtures/parity/canonical/verify__status_older_run_failed_crashed.json new file mode 100644 index 0000000..2899dcb --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_older_run_failed_crashed.json @@ -0,0 +1,20 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "task_error", + "detail": "The check stopped on an error on our side.", + "hint": null, + "failure_class": "internal", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#internal" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_older_run_failed_insufficient_evidence.json b/tests/fixtures/parity/canonical/verify__status_older_run_failed_insufficient_evidence.json new file mode 100644 index 0000000..cc029a3 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_older_run_failed_insufficient_evidence.json @@ -0,0 +1,20 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "research_empty", + "detail": "No sources about the claim were found.", + "hint": null, + "failure_class": "insufficient_evidence", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_older_run_in_progress.json b/tests/fixtures/parity/canonical/verify__status_older_run_in_progress.json new file mode 100644 index 0000000..5e5d47b --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_older_run_in_progress.json @@ -0,0 +1,19 @@ +{ + "status": 200, + "body": { + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "progress": { + "step": "research", + "index": 2, + "total": 5, + "elapsed_seconds": 1, + "poll_after_seconds": 5 + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_processing.json b/tests/fixtures/parity/canonical/verify__status_processing.json new file mode 100644 index 0000000..5e5d47b --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_processing.json @@ -0,0 +1,19 @@ +{ + "status": 200, + "body": { + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "progress": { + "step": "research", + "index": 2, + "total": 5, + "elapsed_seconds": 1, + "poll_after_seconds": 5 + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_processing_after_a_while.json b/tests/fixtures/parity/canonical/verify__status_processing_after_a_while.json new file mode 100644 index 0000000..e0638f1 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_processing_after_a_while.json @@ -0,0 +1,19 @@ +{ + "status": 200, + "body": { + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "progress": { + "step": "adjudication", + "index": 4, + "total": 5, + "elapsed_seconds": 1, + "poll_after_seconds": 5 + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_task_stuck.json b/tests/fixtures/parity/canonical/verify__status_task_stuck.json new file mode 100644 index 0000000..4ca4162 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_task_stuck.json @@ -0,0 +1,20 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "task_stuck", + "detail": "The check stopped responding before it finished.", + "hint": null, + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__status_unknown_404.json b/tests/fixtures/parity/canonical/verify__status_unknown_404.json new file mode 100644 index 0000000..8c0eaee --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__status_unknown_404.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Task not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__submit_202.json b/tests/fixtures/parity/canonical/verify__submit_202.json new file mode 100644 index 0000000..d47aeaf --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__submit_202.json @@ -0,0 +1,12 @@ +{ + "status": 202, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__submit_202_options.json b/tests/fixtures/parity/canonical/verify__submit_202_options.json new file mode 100644 index 0000000..d47aeaf --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__submit_202_options.json @@ -0,0 +1,12 @@ +{ + "status": 202, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__submit_202_text_alias.json b/tests/fixtures/parity/canonical/verify__submit_202_text_alias.json new file mode 100644 index 0000000..d47aeaf --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__submit_202_text_alias.json @@ -0,0 +1,12 @@ +{ + "status": 202, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__unauthenticated_401.json b/tests/fixtures/parity/canonical/verify__unauthenticated_401.json new file mode 100644 index 0000000..dcdaad0 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__unauthenticated_401.json @@ -0,0 +1,12 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized", + "code": "not_authenticated" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_200.json b/tests/fixtures/parity/canonical/verify__verification_200.json new file mode 100644 index 0000000..54fbdb7 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_200.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_200_covered.json b/tests/fixtures/parity/canonical/verify__verification_200_covered.json new file mode 100644 index 0000000..c9c3df6 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_200_covered.json @@ -0,0 +1,93 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "covered", + "reasons": [], + "certificate_id": "95b0f3dd008b46846b6dd6b15099e2b3", + "certificate_url": "https://lenz.io/certificate/95b0f3dd008b46846b6dd6b15099e2b3", + "as_of": "2026-03-10T12:01:30+00:00", + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_200_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/canonical/verify__verification_200_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..5c62918 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_200_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "completed_at": "2026-10-02T00:03:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_200_modified_at_null.json b/tests/fixtures/parity/canonical/verify__verification_200_modified_at_null.json new file mode 100644 index 0000000..54fbdb7 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_200_modified_at_null.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_200_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/canonical/verify__verification_200_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..cb9d0dd --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_200_modified_at_same_day_hours_apart.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "completed_at": "2026-10-01T20:00:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_200_modified_at_set.json b/tests/fixtures/parity/canonical/verify__verification_200_modified_at_set.json new file mode 100644 index 0000000..5c62918 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_200_modified_at_set.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "completed_at": "2026-10-02T00:03:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_200_result_json_conclusion_only.json b/tests/fixtures/parity/canonical/verify__verification_200_result_json_conclusion_only.json new file mode 100644 index 0000000..eb7471c --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_200_result_json_conclusion_only.json @@ -0,0 +1,56 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [], + "presumed_intent": "", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [], + "audit": { + "adjudication_summary": "", + "assessments": [], + "debate_pro": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "debate_con": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "panel_agreement": "split" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_200_result_json_empty.json b/tests/fixtures/parity/canonical/verify__verification_200_result_json_empty.json new file mode 100644 index 0000000..eb7471c --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_200_result_json_empty.json @@ -0,0 +1,56 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [], + "presumed_intent": "", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [], + "audit": { + "adjudication_summary": "", + "assessments": [], + "debate_pro": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "debate_con": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "panel_agreement": "split" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_200_result_json_old_shape_strings.json b/tests/fixtures/parity/canonical/verify__verification_200_result_json_old_shape_strings.json new file mode 100644 index 0000000..b2a825a --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_200_result_json_old_shape_strings.json @@ -0,0 +1,72 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [], + "presumed_intent": "", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [ + { + "source_name": "", + "title": "", + "url": "https://old.example/a", + "snippet": "Old row.", + "date": "" + } + ], + "audit": { + "adjudication_summary": "", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "", + "score": null, + "reasoning": "", + "warnings": [] + } + ], + "debate_pro": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "debate_con": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "panel_agreement": "split" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_404.json b/tests/fixtures/parity/canonical/verify__verification_404.json new file mode 100644 index 0000000..775d847 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_404.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_by_task_id_200.json b/tests/fixtures/parity/canonical/verify__verification_by_task_id_200.json new file mode 100644 index 0000000..54fbdb7 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_by_task_id_200.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_failed_409.json b/tests/fixtures/parity/canonical/verify__verification_failed_409.json new file mode 100644 index 0000000..1a8058b --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_failed_409.json @@ -0,0 +1,23 @@ +{ + "status": 409, + "body": { + "detail": "This check failed and has no result.", + "code": "verification_failed", + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "hint": "Resubmit to POST /verify if retryable is true. GET /verify/status/7cff18da2d979d6370e54a160be121ad has the full failure.", + "failure": { + "code": "research_empty", + "detail": "No sources about the claim were found.", + "hint": null, + "failure_class": "insufficient_evidence", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence" + } + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_failed_409_not_a_claim_after_a_while.json b/tests/fixtures/parity/canonical/verify__verification_failed_409_not_a_claim_after_a_while.json new file mode 100644 index 0000000..62a1cc6 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_failed_409_not_a_claim_after_a_while.json @@ -0,0 +1,23 @@ +{ + "status": 409, + "body": { + "detail": "This check failed and has no result.", + "code": "verification_failed", + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "hint": "No factual statement that can be checked against evidence was found in the input. Send one factual claim, or run the text through /extract to enumerate its claims.", + "failure": { + "code": "no_checkable_claim", + "detail": "No claim in the input could be checked against public evidence.", + "hint": "No factual statement that can be checked against evidence was found in the input. Send one factual claim, or run the text through /extract to enumerate its claims.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + } + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_not_ready_409.json b/tests/fixtures/parity/canonical/verify__verification_not_ready_409.json new file mode 100644 index 0000000..dae092f --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_not_ready_409.json @@ -0,0 +1,15 @@ +{ + "status": 409, + "body": { + "detail": "This check is still running.", + "code": "verification_not_ready", + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "hint": "Poll GET /verify/status/7cff18da2d979d6370e54a160be121ad until it completes, then read its result." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_not_yours_404.json b/tests/fixtures/parity/canonical/verify__verification_not_yours_404.json new file mode 100644 index 0000000..775d847 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_not_yours_404.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_public_anonymous.json b/tests/fixtures/parity/canonical/verify__verification_public_anonymous.json new file mode 100644 index 0000000..9b93c51 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_public_anonymous.json @@ -0,0 +1,83 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "public", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": null + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_public_of_another_user.json b/tests/fixtures/parity/canonical/verify__verification_public_of_another_user.json new file mode 100644 index 0000000..4727423 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_public_of_another_user.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "public", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_unknown_task_404.json b/tests/fixtures/parity/canonical/verify__verification_unknown_task_404.json new file mode 100644 index 0000000..2833a7f --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_unknown_task_404.json @@ -0,0 +1,13 @@ +{ + "status": 404, + "body": { + "detail": "Not found.", + "code": "not_found", + "hint": "Unknown id. If this is a task_id, poll GET /verify/status/dddddddddddddddddddddddddddddddd for its status." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_zero_retention_expired_410.json b/tests/fixtures/parity/canonical/verify__verification_zero_retention_expired_410.json new file mode 100644 index 0000000..924d468 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_zero_retention_expired_410.json @@ -0,0 +1,13 @@ +{ + "status": 410, + "body": { + "detail": "This verification is no longer available: its account removes verifications after a set period.", + "code": "purged", + "purged_at": "2026-10-01T09:07:00.123456+00:00" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__verification_zero_retention_served.json b/tests/fixtures/parity/canonical/verify__verification_zero_retention_served.json new file mode 100644 index 0000000..ec77f26 --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__verification_zero_retention_served.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical.", + "executive_summary": "The claim is well supported by evidence.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/verify__webhook_secret_missing_422.json b/tests/fixtures/parity/canonical/verify__webhook_secret_missing_422.json new file mode 100644 index 0000000..85482fc --- /dev/null +++ b/tests/fixtures/parity/canonical/verify__webhook_secret_missing_422.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "webhook_url was supplied but this API key has no HMAC secret. Generate one at https://lenz.io/api-credentials (Webhooks panel) before submitting webhook-delivered calls.", + "code": "webhook_secret_missing", + "errors": [ + { + "loc": [ + "body", + "webhook_url" + ], + "msg": "webhook_url was supplied but this API key has no HMAC secret. Generate one at https://lenz.io/api-credentials (Webhooks panel) before submitting webhook-delivered calls.", + "type": "webhook_secret_missing" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/canonical/webhook__certificate_timestamped.json b/tests/fixtures/parity/canonical/webhook__certificate_timestamped.json new file mode 100644 index 0000000..422b1ce --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__certificate_timestamped.json @@ -0,0 +1,24 @@ +{ + "status": 200, + "body": { + "event": "certificate.timestamped", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "status": "completed", + "coverage": { + "status": "covered", + "reasons": [], + "certificate_id": "95b0f3dd008b46846b6dd6b15099e2b3", + "certificate_url": "https://lenz.io/certificate/95b0f3dd008b46846b6dd6b15099e2b3", + "as_of": "2026-09-03T10:00:00+00:00", + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__certificate_timestamped_review_child.json b/tests/fixtures/parity/canonical/webhook__certificate_timestamped_review_child.json new file mode 100644 index 0000000..0a4075b --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__certificate_timestamped_review_child.json @@ -0,0 +1,25 @@ +{ + "status": 200, + "body": { + "event": "certificate.timestamped", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "review_id": "d6b2bd72", + "status": "completed", + "coverage": { + "status": "covered", + "reasons": [], + "certificate_id": "95b0f3dd008b46846b6dd6b15099e2b3", + "certificate_url": "https://lenz.io/certificate/95b0f3dd008b46846b6dd6b15099e2b3", + "as_of": "2026-09-03T10:00:00+00:00", + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__citecheck_completed.json b/tests/fixtures/parity/canonical/webhook__citecheck_completed.json new file mode 100644 index 0000000..e5c5a3d --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__citecheck_completed.json @@ -0,0 +1,133 @@ +{ + "status": 200, + "body": { + "event": "citecheck.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "citecheck_id": "8eb49302", + "status": "completed", + "citecheck": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_exceeded": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 1 + }, + "credits": { + "charged": 2 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": { + "finding": "contradicted", + "source": "support", + "is_issue": true + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "contradicted", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": null, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [ + { + "citation_index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "finding": "contradicted", + "source": "support", + "snippet": "The source says so.", + "rationale": "The page states it.", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "failure": null + } + ], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__citecheck_failed.json b/tests/fixtures/parity/canonical/webhook__citecheck_failed.json new file mode 100644 index 0000000..809b573 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__citecheck_failed.json @@ -0,0 +1,47 @@ +{ + "status": 200, + "body": { + "event": "citecheck.failed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "citecheck_id": "8eb49302", + "status": "failed", + "citecheck": { + "citecheck_id": "8eb49302", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 20 + }, + "summary": { + "citations_found": null, + "citations_selected": null, + "citation_limit": 20, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0 + }, + "credits": { + "charged": 0 + }, + "citations": [], + "citation_issues": [], + "citation_failures": [], + "failure": { + "code": "no_citations", + "detail": "The text holds no citation to check.", + "hint": "The text has no citation to check: no link, DOI or numbered reference with one.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "more_citations": null + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__review_completed.json b/tests/fixtures/parity/canonical/webhook__review_completed.json new file mode 100644 index 0000000..35b6ad5 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__review_completed.json @@ -0,0 +1,154 @@ +{ + "status": 200, + "body": { + "event": "review.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "review_id": "d6b2bd72", + "status": "completed", + "review": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 1, + "completed": 1, + "failed": 0 + }, + "issues": 1, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 11 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "failure": null, + "suggested_edits": null + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T09:14:00.123456+00:00", + "completed_at": "2026-10-01T09:14:00.123456+00:00", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "failure": null + }, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__review_completed_key_default_url.json b/tests/fixtures/parity/canonical/webhook__review_completed_key_default_url.json new file mode 100644 index 0000000..b1bd673 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__review_completed_key_default_url.json @@ -0,0 +1,103 @@ +{ + "status": 200, + "body": { + "event": "review.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "review_id": "d6b2bd72", + "status": "completed", + "review": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": 1, + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_exceeded": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "more_claims": [], + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__review_completed_oversized_rebuilt.json b/tests/fixtures/parity/canonical/webhook__review_completed_oversized_rebuilt.json new file mode 100644 index 0000000..3f18193 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__review_completed_oversized_rebuilt.json @@ -0,0 +1,10 @@ +{ + "status": 200, + "body": { + "event": "review.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "review_id": "d6b2bd72", + "status": "completed" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__review_failed.json b/tests/fixtures/parity/canonical/webhook__review_failed.json new file mode 100644 index 0000000..40f0ca5 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__review_failed.json @@ -0,0 +1,74 @@ +{ + "status": 200, + "body": { + "event": "review.failed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "review_id": "d6b2bd72", + "status": "failed", + "review": { + "review_id": "d6b2bd72", + "view": "full", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_found": null, + "claims_selected": null, + "claim_limit": 20, + "claim_limit_exceeded": null, + "input_truncated": false, + "assessments": null, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_exceeded": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [], + "failure": { + "code": "no_checkable_claim", + "detail": "No claim in the input could be checked against public evidence.", + "hint": "No factual statement that can be checked against evidence was found in the input. Send one factual claim, or run the text through /extract to enumerate its claims.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "more_claims": null, + "more_claim_locations": null, + "more_citations": null + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__test_fire.json b/tests/fixtures/parity/canonical/webhook__test_fire.json new file mode 100644 index 0000000..1d3d49b --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__test_fire.json @@ -0,0 +1,12 @@ +{ + "status": 200, + "body": { + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "webhook.test", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "status": "test", + "task_id": "test_7cff18da2d979d63" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__verification_completed.json b/tests/fixtures/parity/canonical/webhook__verification_completed.json new file mode 100644 index 0000000..71884cd --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__verification_completed.json @@ -0,0 +1,108 @@ +{ + "status": 200, + "body": { + "event": "verification.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "status": "completed", + "verification": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "visibility": "private", + "depth": "standard", + "domain": "Geography", + "entities": [ + { + "name": "Eiffel Tower", + "qid": null + }, + { + "name": "Berlin", + "qid": null + } + ], + "presumed_intent": "Check where a landmark is.", + "verdict": "False", + "confidence": "high", + "lenz_score": 1, + "key_finding": "The Eiffel Tower is in Paris.", + "executive_summary": "The Eiffel Tower stands in Paris, France, not in Berlin.", + "warnings": [ + "Only two sources were found." + ], + "suggested_rewrite": "The Eiffel Tower is in Paris.", + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [ + { + "source_name": "Example Encyclopedia", + "title": "Eiffel Tower", + "url": "https://example.org/eiffel-tower", + "snippet": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.", + "date": "2025-01-15" + }, + { + "source_name": "Example Travel", + "title": "Visiting Paris", + "url": "https://example.com/visit-paris", + "snippet": "Most visitors climb the tower on their first day in Paris.", + "date": "" + } + ], + "audit": { + "adjudication_summary": "Both reviewers found it false.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Evidence", + "score": 1.0, + "reasoning": "Both sources place the tower in Paris.", + "warnings": [ + "Example Travel is a travel blog." + ] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Evidence", + "score": 2.0, + "reasoning": "The encyclopedia entry is unambiguous.", + "warnings": [] + } + ], + "debate_pro": { + "role": "pro", + "argument": "Some guides place it in Berlin.", + "rebuttal": "None of them are reliable." + }, + "debate_con": { + "role": "con", + "argument": "Every source places it in Paris.", + "rebuttal": "The pro case cites no source." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__verification_completed_in_batch.json b/tests/fixtures/parity/canonical/webhook__verification_completed_in_batch.json new file mode 100644 index 0000000..507e63b --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__verification_completed_in_batch.json @@ -0,0 +1,109 @@ +{ + "status": 200, + "body": { + "event": "verification.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "batch_id": "7ea9cdbd4064e3cf", + "status": "completed", + "verification": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "visibility": "private", + "depth": "standard", + "domain": "Geography", + "entities": [ + { + "name": "Eiffel Tower", + "qid": null + }, + { + "name": "Berlin", + "qid": null + } + ], + "presumed_intent": "Check where a landmark is.", + "verdict": "False", + "confidence": "high", + "lenz_score": 1, + "key_finding": "The Eiffel Tower is in Paris.", + "executive_summary": "The Eiffel Tower stands in Paris, France, not in Berlin.", + "warnings": [ + "Only two sources were found." + ], + "suggested_rewrite": "The Eiffel Tower is in Paris.", + "created_at": "2026-10-01T09:07:00.123456+00:00", + "completed_at": "2026-10-01T09:07:00.123456+00:00", + "sources": [ + { + "source_name": "Example Encyclopedia", + "title": "Eiffel Tower", + "url": "https://example.org/eiffel-tower", + "snippet": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.", + "date": "2025-01-15" + }, + { + "source_name": "Example Travel", + "title": "Visiting Paris", + "url": "https://example.com/visit-paris", + "snippet": "Most visitors climb the tower on their first day in Paris.", + "date": "" + } + ], + "audit": { + "adjudication_summary": "Both reviewers found it false.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Evidence", + "score": 1.0, + "reasoning": "Both sources place the tower in Paris.", + "warnings": [ + "Example Travel is a travel blog." + ] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Evidence", + "score": 2.0, + "reasoning": "The encyclopedia entry is unambiguous.", + "warnings": [] + } + ], + "debate_pro": { + "role": "pro", + "argument": "Some guides place it in Berlin.", + "rebuttal": "None of them are reliable." + }, + "debate_con": { + "role": "con", + "argument": "Every source places it in Paris.", + "rebuttal": "The pro case cites no source." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__verification_completed_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/canonical/webhook__verification_completed_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..dc19418 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__verification_completed_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,108 @@ +{ + "status": 200, + "body": { + "event": "verification.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "status": "completed", + "verification": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "visibility": "private", + "depth": "standard", + "domain": "Geography", + "entities": [ + { + "name": "Eiffel Tower", + "qid": null + }, + { + "name": "Berlin", + "qid": null + } + ], + "presumed_intent": "Check where a landmark is.", + "verdict": "False", + "confidence": "high", + "lenz_score": 1, + "key_finding": "The Eiffel Tower is in Paris.", + "executive_summary": "The Eiffel Tower stands in Paris, France, not in Berlin.", + "warnings": [ + "Only two sources were found." + ], + "suggested_rewrite": "The Eiffel Tower is in Paris.", + "created_at": "2026-10-01T23:55:00.123456+00:00", + "completed_at": "2026-10-02T00:03:00.123456+00:00", + "sources": [ + { + "source_name": "Example Encyclopedia", + "title": "Eiffel Tower", + "url": "https://example.org/eiffel-tower", + "snippet": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.", + "date": "2025-01-15" + }, + { + "source_name": "Example Travel", + "title": "Visiting Paris", + "url": "https://example.com/visit-paris", + "snippet": "Most visitors climb the tower on their first day in Paris.", + "date": "" + } + ], + "audit": { + "adjudication_summary": "Both reviewers found it false.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Evidence", + "score": 1.0, + "reasoning": "Both sources place the tower in Paris.", + "warnings": [ + "Example Travel is a travel blog." + ] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Evidence", + "score": 2.0, + "reasoning": "The encyclopedia entry is unambiguous.", + "warnings": [] + } + ], + "debate_pro": { + "role": "pro", + "argument": "Some guides place it in Berlin.", + "rebuttal": "None of them are reliable." + }, + "debate_con": { + "role": "con", + "argument": "Every source places it in Paris.", + "rebuttal": "The pro case cites no source." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__verification_completed_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/canonical/webhook__verification_completed_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..189ca65 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__verification_completed_modified_at_same_day_hours_apart.json @@ -0,0 +1,108 @@ +{ + "status": 200, + "body": { + "event": "verification.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "status": "completed", + "verification": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "visibility": "private", + "depth": "standard", + "domain": "Geography", + "entities": [ + { + "name": "Eiffel Tower", + "qid": null + }, + { + "name": "Berlin", + "qid": null + } + ], + "presumed_intent": "Check where a landmark is.", + "verdict": "False", + "confidence": "high", + "lenz_score": 1, + "key_finding": "The Eiffel Tower is in Paris.", + "executive_summary": "The Eiffel Tower stands in Paris, France, not in Berlin.", + "warnings": [ + "Only two sources were found." + ], + "suggested_rewrite": "The Eiffel Tower is in Paris.", + "created_at": "2026-10-01T08:00:00.123456+00:00", + "completed_at": "2026-10-01T20:00:00.123456+00:00", + "sources": [ + { + "source_name": "Example Encyclopedia", + "title": "Eiffel Tower", + "url": "https://example.org/eiffel-tower", + "snippet": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.", + "date": "2025-01-15" + }, + { + "source_name": "Example Travel", + "title": "Visiting Paris", + "url": "https://example.com/visit-paris", + "snippet": "Most visitors climb the tower on their first day in Paris.", + "date": "" + } + ], + "audit": { + "adjudication_summary": "Both reviewers found it false.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Evidence", + "score": 1.0, + "reasoning": "Both sources place the tower in Paris.", + "warnings": [ + "Example Travel is a travel blog." + ] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Evidence", + "score": 2.0, + "reasoning": "The encyclopedia entry is unambiguous.", + "warnings": [] + } + ], + "debate_pro": { + "role": "pro", + "argument": "Some guides place it in Berlin.", + "rebuttal": "None of them are reliable." + }, + "debate_con": { + "role": "con", + "argument": "Every source places it in Paris.", + "rebuttal": "The pro case cites no source." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__verification_completed_sparse_result.json b/tests/fixtures/parity/canonical/webhook__verification_completed_sparse_result.json new file mode 100644 index 0000000..91f7632 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__verification_completed_sparse_result.json @@ -0,0 +1,22 @@ +{ + "status": 200, + "body": { + "event": "verification.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "status": "completed", + "verification": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "language": "en" + } + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__verification_failed_error_none.json b/tests/fixtures/parity/canonical/webhook__verification_failed_error_none.json new file mode 100644 index 0000000..e858af3 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__verification_failed_error_none.json @@ -0,0 +1,24 @@ +{ + "status": 200, + "body": { + "event": "verification.failed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "failed", + "verification": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "", + "detail": "The check stopped before it finished.", + "hint": null, + "failure_class": "internal", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#internal" + } + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__verification_failed_insufficient_evidence.json b/tests/fixtures/parity/canonical/webhook__verification_failed_insufficient_evidence.json new file mode 100644 index 0000000..7d3a875 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__verification_failed_insufficient_evidence.json @@ -0,0 +1,24 @@ +{ + "status": 200, + "body": { + "event": "verification.failed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "failed", + "verification": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "research_insufficient", + "detail": "Too few sources about the claim were found to judge it.", + "hint": null, + "failure_class": "insufficient_evidence", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence" + } + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__verification_failed_not_a_claim.json b/tests/fixtures/parity/canonical/webhook__verification_failed_not_a_claim.json new file mode 100644 index 0000000..e25ed20 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__verification_failed_not_a_claim.json @@ -0,0 +1,24 @@ +{ + "status": 200, + "body": { + "event": "verification.failed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "failed", + "verification": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "no_checkable_claim", + "detail": "No claim in the input could be checked against public evidence.", + "hint": "It is a request to write an essay. Send one factual claim, or run the text through /extract to enumerate its claims.", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + } + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__verification_failed_upstream_unavailable.json b/tests/fixtures/parity/canonical/webhook__verification_failed_upstream_unavailable.json new file mode 100644 index 0000000..926b1c1 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__verification_failed_upstream_unavailable.json @@ -0,0 +1,24 @@ +{ + "status": 200, + "body": { + "event": "verification.failed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "failed", + "verification": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "failure": { + "code": "framing_failed", + "detail": "The input could not be read as a claim.", + "hint": null, + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__verification_needs_input_hint_none.json b/tests/fixtures/parity/canonical/webhook__verification_needs_input_hint_none.json new file mode 100644 index 0000000..3377675 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__verification_needs_input_hint_none.json @@ -0,0 +1,24 @@ +{ + "status": 200, + "body": { + "event": "verification.needs_input", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "needs_input", + "verification": { + "status": "needs_input", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "reason": "multi_claim", + "claims": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "domain": "" + } + ], + "hint": null + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/canonical/webhook__verification_needs_input_multi_claim.json b/tests/fixtures/parity/canonical/webhook__verification_needs_input_multi_claim.json new file mode 100644 index 0000000..3e04f93 --- /dev/null +++ b/tests/fixtures/parity/canonical/webhook__verification_needs_input_multi_claim.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "event": "verification.needs_input", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "needs_input", + "verification": { + "status": "needs_input", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "reason": "multi_claim", + "claims": [ + { + "claim": "The Earth is round.", + "domain": "" + }, + { + "claim": "The Moon is made of cheese.", + "domain": "Science" + } + ], + "hint": "The text holds several distinct claims. Send the ones to check to POST /verify/{task_id}/select." + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/expected/account__api_root.json b/tests/fixtures/parity/expected/account__api_root.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/parity/expected/account__api_root.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/parity/expected/account__ask_history_after_reset.json b/tests/fixtures/parity/expected/account__ask_history_after_reset.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/parity/expected/account__ask_history_after_reset.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/parity/expected/account__ask_history_after_send.json b/tests/fixtures/parity/expected/account__ask_history_after_send.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/parity/expected/account__ask_history_after_send.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/parity/expected/account__ask_history_empty.json b/tests/fixtures/parity/expected/account__ask_history_empty.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/parity/expected/account__ask_history_empty.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/parity/expected/account__ask_history_messages.json b/tests/fixtures/parity/expected/account__ask_history_messages.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/parity/expected/account__ask_history_messages.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/parity/expected/account__ask_reset.json b/tests/fixtures/parity/expected/account__ask_reset.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/parity/expected/account__ask_reset.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/parity/expected/account__ask_send.json b/tests/fixtures/parity/expected/account__ask_send.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/parity/expected/account__ask_send.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/parity/expected/account__ask_send_language.json b/tests/fixtures/parity/expected/account__ask_send_language.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/parity/expected/account__ask_send_language.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/parity/expected/account__library_empty.json b/tests/fixtures/parity/expected/account__library_empty.json new file mode 100644 index 0000000..2184439 --- /dev/null +++ b/tests/fixtures/parity/expected/account__library_empty.json @@ -0,0 +1,16 @@ +{ + "dump": { + "items": [], + "page": 1, + "page_size": 20, + "total": 0 + }, + "dump_unset": { + "items": [], + "page": 1, + "page_size": 20, + "total": 0 + }, + "render_json": null, + "repr": "LibraryList(items=[], total=0, page=1, page_size=20)" +} diff --git a/tests/fixtures/parity/expected/account__library_item_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/expected/account__library_item_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..d6bafee --- /dev/null +++ b/tests/fixtures/parity/expected/account__library_item_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,48 @@ +{ + "dump": { + "items": [ + { + "claim": "A library claim.", + "confidence": "low", + "created_at": "2026-10-01T23:55:00.123456+00:00", + "domain": "", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + } + ], + "page": 1, + "page_size": 20, + "total": 1 + }, + "dump_unset": { + "items": [ + { + "claim": "A library claim.", + "confidence": "low", + "created_at": "2026-10-01T23:55:00.123456+00:00", + "domain": "", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + } + ], + "page": 1, + "page_size": 20, + "total": 1 + }, + "render_json": null, + "repr": "LibraryList(items=[LibraryItem(verification_id='68ca4aaf', claim='A library claim.', domain='', entities=[], verdict='True', confidence='low', lenz_score=10, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', suggested_rewrite=None, created_at='2026-10-01T23:55:00.123456+00:00', modified_at='2026-10-02T00:03:00.123456+00:00', language='en')], total=1, page=1, page_size=20)" +} diff --git a/tests/fixtures/parity/expected/account__library_item_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/expected/account__library_item_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..3e2043e --- /dev/null +++ b/tests/fixtures/parity/expected/account__library_item_modified_at_same_day_hours_apart.json @@ -0,0 +1,48 @@ +{ + "dump": { + "items": [ + { + "claim": "A library claim.", + "confidence": "low", + "created_at": "2026-10-01T08:00:00.123456+00:00", + "domain": "", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + } + ], + "page": 1, + "page_size": 20, + "total": 1 + }, + "dump_unset": { + "items": [ + { + "claim": "A library claim.", + "confidence": "low", + "created_at": "2026-10-01T08:00:00.123456+00:00", + "domain": "", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + } + ], + "page": 1, + "page_size": 20, + "total": 1 + }, + "render_json": null, + "repr": "LibraryList(items=[LibraryItem(verification_id='68ca4aaf', claim='A library claim.', domain='', entities=[], verdict='True', confidence='low', lenz_score=10, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', suggested_rewrite=None, created_at='2026-10-01T08:00:00.123456+00:00', modified_at=None, language='en')], total=1, page=1, page_size=20)" +} diff --git a/tests/fixtures/parity/expected/account__library_items.json b/tests/fixtures/parity/expected/account__library_items.json new file mode 100644 index 0000000..00d7d2f --- /dev/null +++ b/tests/fixtures/parity/expected/account__library_items.json @@ -0,0 +1,108 @@ +{ + "dump": { + "items": [ + { + "claim": "Library claim 0.", + "confidence": "low", + "created_at": "2026-10-01T09:07:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + }, + { + "claim": "Library claim 1.", + "confidence": "low", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "4d44dfaf" + }, + { + "claim": "Library claim 2.", + "confidence": "low", + "created_at": "2026-10-01T09:21:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "7c83247c" + } + ], + "page": 1, + "page_size": 20, + "total": 3 + }, + "dump_unset": { + "items": [ + { + "claim": "Library claim 0.", + "confidence": "low", + "created_at": "2026-10-01T09:07:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + }, + { + "claim": "Library claim 1.", + "confidence": "low", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "4d44dfaf" + }, + { + "claim": "Library claim 2.", + "confidence": "low", + "created_at": "2026-10-01T09:21:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "7c83247c" + } + ], + "page": 1, + "page_size": 20, + "total": 3 + }, + "render_json": null, + "repr": "LibraryList(items=[LibraryItem(verification_id='68ca4aaf', claim='Library claim 0.', domain='Science', entities=[], verdict='True', confidence='low', lenz_score=10, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', suggested_rewrite=None, created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en'), LibraryItem(verification_id='4d44dfaf', claim='Library claim 1.', domain='Science', entities=[], verdict='True', confidence='low', lenz_score=10, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', suggested_rewrite=None, created_at='2026-10-01T09:14:00.123456+00:00', modified_at=None, language='en'), LibraryItem(verification_id='7c83247c', claim='Library claim 2.', domain='Science', entities=[], verdict='True', confidence='low', lenz_score=10, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', suggested_rewrite=None, created_at='2026-10-01T09:21:00.123456+00:00', modified_at=None, language='en')], total=3, page=1, page_size=20)" +} diff --git a/tests/fixtures/parity/expected/account__library_no_match.json b/tests/fixtures/parity/expected/account__library_no_match.json new file mode 100644 index 0000000..2184439 --- /dev/null +++ b/tests/fixtures/parity/expected/account__library_no_match.json @@ -0,0 +1,16 @@ +{ + "dump": { + "items": [], + "page": 1, + "page_size": 20, + "total": 0 + }, + "dump_unset": { + "items": [], + "page": 1, + "page_size": 20, + "total": 0 + }, + "render_json": null, + "repr": "LibraryList(items=[], total=0, page=1, page_size=20)" +} diff --git a/tests/fixtures/parity/expected/account__library_page_past_end.json b/tests/fixtures/parity/expected/account__library_page_past_end.json new file mode 100644 index 0000000..fc8bd17 --- /dev/null +++ b/tests/fixtures/parity/expected/account__library_page_past_end.json @@ -0,0 +1,16 @@ +{ + "dump": { + "items": [], + "page": 2, + "page_size": 20, + "total": 1 + }, + "dump_unset": { + "items": [], + "page": 2, + "page_size": 20, + "total": 1 + }, + "render_json": null, + "repr": "LibraryList(items=[], total=1, page=2, page_size=20)" +} diff --git a/tests/fixtures/parity/expected/account__library_paginated_second_page.json b/tests/fixtures/parity/expected/account__library_paginated_second_page.json new file mode 100644 index 0000000..e572a47 --- /dev/null +++ b/tests/fixtures/parity/expected/account__library_paginated_second_page.json @@ -0,0 +1,78 @@ +{ + "dump": { + "items": [ + { + "claim": "Paged claim 020.", + "confidence": "low", + "created_at": "2026-10-01T09:07:00.123456+00:00", + "domain": "", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + }, + { + "claim": "Paged claim 021.", + "confidence": "low", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "domain": "", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "4d44dfaf" + } + ], + "page": 2, + "page_size": 20, + "total": 22 + }, + "dump_unset": { + "items": [ + { + "claim": "Paged claim 020.", + "confidence": "low", + "created_at": "2026-10-01T09:07:00.123456+00:00", + "domain": "", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + }, + { + "claim": "Paged claim 021.", + "confidence": "low", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "domain": "", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 10, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "4d44dfaf" + } + ], + "page": 2, + "page_size": 20, + "total": 22 + }, + "render_json": null, + "repr": "LibraryList(items=[LibraryItem(verification_id='68ca4aaf', claim='Paged claim 020.', domain='', entities=[], verdict='True', confidence='low', lenz_score=10, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', suggested_rewrite=None, created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en'), LibraryItem(verification_id='4d44dfaf', claim='Paged claim 021.', domain='', entities=[], verdict='True', confidence='low', lenz_score=10, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', suggested_rewrite=None, created_at='2026-10-01T09:14:00.123456+00:00', modified_at=None, language='en')], total=22, page=2, page_size=20)" +} diff --git a/tests/fixtures/parity/expected/account__me_usage_extra_credits.json b/tests/fixtures/parity/expected/account__me_usage_extra_credits.json new file mode 100644 index 0000000..3099e7d --- /dev/null +++ b/tests/fixtures/parity/expected/account__me_usage_extra_credits.json @@ -0,0 +1,121 @@ +{ + "dump": { + "ask": { + "bonus": 250, + "credits": 250, + "quota_remaining": 350, + "quota_total": 350, + "quota_used": 0, + "remaining": 350 + }, + "assess": { + "bonus": 250, + "credits": 250, + "quota_remaining": 350, + "quota_total": 350, + "quota_used": 0, + "remaining": 350 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 250, + "extra": 250, + "remaining": 350, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 350, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 25, + "credits": 25, + "quota_remaining": 35, + "quota_total": 35, + "quota_used": 0, + "remaining": 35 + } + }, + "dump_unset": { + "ask": { + "bonus": 250, + "credits": 250, + "quota_remaining": 350, + "quota_total": 350, + "quota_used": 0, + "remaining": 350 + }, + "assess": { + "bonus": 250, + "credits": 250, + "quota_remaining": 350, + "quota_total": 350, + "quota_used": 0, + "remaining": 350 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 250, + "extra": 250, + "remaining": 350, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 350, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 25, + "credits": 25, + "quota_remaining": 35, + "quota_total": 35, + "quota_used": 0, + "remaining": 35 + } + }, + "render": "Lenz usage (Free plan)\n 350 credits left (≈ 35 verifications · 350 assessments)\n Verify: 35 left (0 / 35 quota + 25 extra · 10 credits each · 5 at depth \"low\")\n Ask: 350 left (0 / 350 quota + 250 extra · 1 credit each)\n Assess: 350 left (0 / 350 quota + 250 extra · 1 credit each)\n Extract: 0 / 1000 today (free — no credit charge)\n Credits reset Oct 1, 2026\n", + "render_json": "{\n \"plan\": \"free\",\n \"plan_label\": \"Free\",\n \"quota_resets_at\": \"2026-10-01T14:07:00+00:00\",\n \"credits\": {\n \"total\": 350,\n \"used\": 0,\n \"remaining\": 350,\n \"extra\": 250,\n \"bonus\": 250,\n \"resets_at\": \"2026-10-01T14:07:00+00:00\"\n },\n \"costs\": {\n \"verify\": 10,\n \"assess\": 1,\n \"ask\": 1,\n \"citation\": 1,\n \"extract\": 0\n },\n \"cost_options\": {\n \"verify\": {\n \"depth\": {\n \"standard\": 10,\n \"low\": 5\n }\n }\n },\n \"verify\": {\n \"quota_used\": 0,\n \"quota_total\": 35,\n \"quota_remaining\": 35,\n \"bonus\": 25,\n \"credits\": 25,\n \"remaining\": 35\n },\n \"ask\": {\n \"quota_used\": 0,\n \"quota_total\": 350,\n \"quota_remaining\": 350,\n \"bonus\": 250,\n \"credits\": 250,\n \"remaining\": 350\n },\n \"assess\": {\n \"quota_used\": 0,\n \"quota_total\": 350,\n \"quota_remaining\": 350,\n \"bonus\": 250,\n \"credits\": 250,\n \"remaining\": 350\n },\n \"extract\": {\n \"calls_today\": 0,\n \"daily_limit\": 1000,\n \"unlimited\": false\n },\n \"has_webhook_secret\": false\n}\n", + "repr": "Usage(plan='free', plan_label='Free', quota_resets_at='2026-10-01T14:07:00+00:00', credits=UsageCredits(total=350, used=0, remaining=350, extra=250, bonus=250, resets_at='2026-10-01T14:07:00+00:00'), costs={'verify': 10, 'assess': 1, 'ask': 1, 'citation': 1, 'extract': 0}, cost_options={'verify': {'depth': {'standard': 10, 'low': 5}}}, verify=UsageCapacity(quota_used=0, quota_total=35, quota_remaining=35, bonus=25, credits=25, remaining=35), ask=UsageCapacity(quota_used=0, quota_total=350, quota_remaining=350, bonus=250, credits=250, remaining=350), assess=UsageCapacity(quota_used=0, quota_total=350, quota_remaining=350, bonus=250, credits=250, remaining=350), extract=UsageExtract(calls_today=0, daily_limit=1000, unlimited=False), has_webhook_secret=False)" +} diff --git a/tests/fixtures/parity/expected/account__me_usage_extra_only.json b/tests/fixtures/parity/expected/account__me_usage_extra_only.json new file mode 100644 index 0000000..e1f90b6 --- /dev/null +++ b/tests/fixtures/parity/expected/account__me_usage_extra_only.json @@ -0,0 +1,121 @@ +{ + "dump": { + "ask": { + "bonus": 37, + "credits": 37, + "quota_remaining": 37, + "quota_total": 137, + "quota_used": 100, + "remaining": 37 + }, + "assess": { + "bonus": 37, + "credits": 37, + "quota_remaining": 37, + "quota_total": 137, + "quota_used": 100, + "remaining": 37 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 37, + "extra": 37, + "remaining": 37, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 137, + "used": 100 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 3, + "credits": 3, + "quota_remaining": 3, + "quota_total": 13, + "quota_used": 10, + "remaining": 3 + } + }, + "dump_unset": { + "ask": { + "bonus": 37, + "credits": 37, + "quota_remaining": 37, + "quota_total": 137, + "quota_used": 100, + "remaining": 37 + }, + "assess": { + "bonus": 37, + "credits": 37, + "quota_remaining": 37, + "quota_total": 137, + "quota_used": 100, + "remaining": 37 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 37, + "extra": 37, + "remaining": 37, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 137, + "used": 100 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 3, + "credits": 3, + "quota_remaining": 3, + "quota_total": 13, + "quota_used": 10, + "remaining": 3 + } + }, + "render": "Lenz usage (Free plan)\n 37 credits left (≈ 3 verifications · 37 assessments)\n Verify: 3 left (10 / 13 quota + 3 extra · 10 credits each · 5 at depth \"low\")\n Ask: 37 left (100 / 137 quota + 37 extra · 1 credit each)\n Assess: 37 left (100 / 137 quota + 37 extra · 1 credit each)\n Extract: 0 / 1000 today (free — no credit charge)\n Credits reset Oct 1, 2026\n", + "render_json": "{\n \"plan\": \"free\",\n \"plan_label\": \"Free\",\n \"quota_resets_at\": \"2026-10-01T14:07:00+00:00\",\n \"credits\": {\n \"total\": 137,\n \"used\": 100,\n \"remaining\": 37,\n \"extra\": 37,\n \"bonus\": 37,\n \"resets_at\": \"2026-10-01T14:07:00+00:00\"\n },\n \"costs\": {\n \"verify\": 10,\n \"assess\": 1,\n \"ask\": 1,\n \"citation\": 1,\n \"extract\": 0\n },\n \"cost_options\": {\n \"verify\": {\n \"depth\": {\n \"standard\": 10,\n \"low\": 5\n }\n }\n },\n \"verify\": {\n \"quota_used\": 10,\n \"quota_total\": 13,\n \"quota_remaining\": 3,\n \"bonus\": 3,\n \"credits\": 3,\n \"remaining\": 3\n },\n \"ask\": {\n \"quota_used\": 100,\n \"quota_total\": 137,\n \"quota_remaining\": 37,\n \"bonus\": 37,\n \"credits\": 37,\n \"remaining\": 37\n },\n \"assess\": {\n \"quota_used\": 100,\n \"quota_total\": 137,\n \"quota_remaining\": 37,\n \"bonus\": 37,\n \"credits\": 37,\n \"remaining\": 37\n },\n \"extract\": {\n \"calls_today\": 0,\n \"daily_limit\": 1000,\n \"unlimited\": false\n },\n \"has_webhook_secret\": false\n}\n", + "repr": "Usage(plan='free', plan_label='Free', quota_resets_at='2026-10-01T14:07:00+00:00', credits=UsageCredits(total=137, used=100, remaining=37, extra=37, bonus=37, resets_at='2026-10-01T14:07:00+00:00'), costs={'verify': 10, 'assess': 1, 'ask': 1, 'citation': 1, 'extract': 0}, cost_options={'verify': {'depth': {'standard': 10, 'low': 5}}}, verify=UsageCapacity(quota_used=10, quota_total=13, quota_remaining=3, bonus=3, credits=3, remaining=3), ask=UsageCapacity(quota_used=100, quota_total=137, quota_remaining=37, bonus=37, credits=37, remaining=37), assess=UsageCapacity(quota_used=100, quota_total=137, quota_remaining=37, bonus=37, credits=37, remaining=37), extract=UsageExtract(calls_today=0, daily_limit=1000, unlimited=False), has_webhook_secret=False)" +} diff --git a/tests/fixtures/parity/expected/account__me_usage_extract_calls.json b/tests/fixtures/parity/expected/account__me_usage_extract_calls.json new file mode 100644 index 0000000..5cfc97c --- /dev/null +++ b/tests/fixtures/parity/expected/account__me_usage_extract_calls.json @@ -0,0 +1,121 @@ +{ + "dump": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 100, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 100, + "used": 0 + }, + "extract": { + "calls_today": 7, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 10, + "quota_total": 10, + "quota_used": 0, + "remaining": 10 + } + }, + "dump_unset": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 100, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 100, + "used": 0 + }, + "extract": { + "calls_today": 7, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 10, + "quota_total": 10, + "quota_used": 0, + "remaining": 10 + } + }, + "render": "Lenz usage (Free plan)\n 100 credits left (≈ 10 verifications · 100 assessments)\n Verify: 10 left (0 / 10 quota · 10 credits each · 5 at depth \"low\")\n Ask: 100 left (0 / 100 quota · 1 credit each)\n Assess: 100 left (0 / 100 quota · 1 credit each)\n Extract: 7 / 1000 today (free — no credit charge)\n Credits reset Oct 1, 2026\n", + "render_json": "{\n \"plan\": \"free\",\n \"plan_label\": \"Free\",\n \"quota_resets_at\": \"2026-10-01T14:07:00+00:00\",\n \"credits\": {\n \"total\": 100,\n \"used\": 0,\n \"remaining\": 100,\n \"extra\": 0,\n \"bonus\": 0,\n \"resets_at\": \"2026-10-01T14:07:00+00:00\"\n },\n \"costs\": {\n \"verify\": 10,\n \"assess\": 1,\n \"ask\": 1,\n \"citation\": 1,\n \"extract\": 0\n },\n \"cost_options\": {\n \"verify\": {\n \"depth\": {\n \"standard\": 10,\n \"low\": 5\n }\n }\n },\n \"verify\": {\n \"quota_used\": 0,\n \"quota_total\": 10,\n \"quota_remaining\": 10,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 10\n },\n \"ask\": {\n \"quota_used\": 0,\n \"quota_total\": 100,\n \"quota_remaining\": 100,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 100\n },\n \"assess\": {\n \"quota_used\": 0,\n \"quota_total\": 100,\n \"quota_remaining\": 100,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 100\n },\n \"extract\": {\n \"calls_today\": 7,\n \"daily_limit\": 1000,\n \"unlimited\": false\n },\n \"has_webhook_secret\": false\n}\n", + "repr": "Usage(plan='free', plan_label='Free', quota_resets_at='2026-10-01T14:07:00+00:00', credits=UsageCredits(total=100, used=0, remaining=100, extra=0, bonus=0, resets_at='2026-10-01T14:07:00+00:00'), costs={'verify': 10, 'assess': 1, 'ask': 1, 'citation': 1, 'extract': 0}, cost_options={'verify': {'depth': {'standard': 10, 'low': 5}}}, verify=UsageCapacity(quota_used=0, quota_total=10, quota_remaining=10, bonus=0, credits=0, remaining=10), ask=UsageCapacity(quota_used=0, quota_total=100, quota_remaining=100, bonus=0, credits=0, remaining=100), assess=UsageCapacity(quota_used=0, quota_total=100, quota_remaining=100, bonus=0, credits=0, remaining=100), extract=UsageExtract(calls_today=7, daily_limit=1000, unlimited=False), has_webhook_secret=False)" +} diff --git a/tests/fixtures/parity/expected/account__me_usage_free.json b/tests/fixtures/parity/expected/account__me_usage_free.json new file mode 100644 index 0000000..f2f3166 --- /dev/null +++ b/tests/fixtures/parity/expected/account__me_usage_free.json @@ -0,0 +1,121 @@ +{ + "dump": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 100, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 100, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 10, + "quota_total": 10, + "quota_used": 0, + "remaining": 10 + } + }, + "dump_unset": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 100, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 100, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 10, + "quota_total": 10, + "quota_used": 0, + "remaining": 10 + } + }, + "render": "Lenz usage (Free plan)\n 100 credits left (≈ 10 verifications · 100 assessments)\n Verify: 10 left (0 / 10 quota · 10 credits each · 5 at depth \"low\")\n Ask: 100 left (0 / 100 quota · 1 credit each)\n Assess: 100 left (0 / 100 quota · 1 credit each)\n Extract: 0 / 1000 today (free — no credit charge)\n Credits reset Oct 1, 2026\n", + "render_json": "{\n \"plan\": \"free\",\n \"plan_label\": \"Free\",\n \"quota_resets_at\": \"2026-10-01T14:07:00+00:00\",\n \"credits\": {\n \"total\": 100,\n \"used\": 0,\n \"remaining\": 100,\n \"extra\": 0,\n \"bonus\": 0,\n \"resets_at\": \"2026-10-01T14:07:00+00:00\"\n },\n \"costs\": {\n \"verify\": 10,\n \"assess\": 1,\n \"ask\": 1,\n \"citation\": 1,\n \"extract\": 0\n },\n \"cost_options\": {\n \"verify\": {\n \"depth\": {\n \"standard\": 10,\n \"low\": 5\n }\n }\n },\n \"verify\": {\n \"quota_used\": 0,\n \"quota_total\": 10,\n \"quota_remaining\": 10,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 10\n },\n \"ask\": {\n \"quota_used\": 0,\n \"quota_total\": 100,\n \"quota_remaining\": 100,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 100\n },\n \"assess\": {\n \"quota_used\": 0,\n \"quota_total\": 100,\n \"quota_remaining\": 100,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 100\n },\n \"extract\": {\n \"calls_today\": 0,\n \"daily_limit\": 1000,\n \"unlimited\": false\n },\n \"has_webhook_secret\": false\n}\n", + "repr": "Usage(plan='free', plan_label='Free', quota_resets_at='2026-10-01T14:07:00+00:00', credits=UsageCredits(total=100, used=0, remaining=100, extra=0, bonus=0, resets_at='2026-10-01T14:07:00+00:00'), costs={'verify': 10, 'assess': 1, 'ask': 1, 'citation': 1, 'extract': 0}, cost_options={'verify': {'depth': {'standard': 10, 'low': 5}}}, verify=UsageCapacity(quota_used=0, quota_total=10, quota_remaining=10, bonus=0, credits=0, remaining=10), ask=UsageCapacity(quota_used=0, quota_total=100, quota_remaining=100, bonus=0, credits=0, remaining=100), assess=UsageCapacity(quota_used=0, quota_total=100, quota_remaining=100, bonus=0, credits=0, remaining=100), extract=UsageExtract(calls_today=0, daily_limit=1000, unlimited=False), has_webhook_secret=False)" +} diff --git a/tests/fixtures/parity/expected/account__me_usage_free_partly_spent.json b/tests/fixtures/parity/expected/account__me_usage_free_partly_spent.json new file mode 100644 index 0000000..d353d1e --- /dev/null +++ b/tests/fixtures/parity/expected/account__me_usage_free_partly_spent.json @@ -0,0 +1,121 @@ +{ + "dump": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 83, + "quota_total": 100, + "quota_used": 17, + "remaining": 83 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 83, + "quota_total": 100, + "quota_used": 17, + "remaining": 83 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 83, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 100, + "used": 17 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 8, + "quota_total": 10, + "quota_used": 2, + "remaining": 8 + } + }, + "dump_unset": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 83, + "quota_total": 100, + "quota_used": 17, + "remaining": 83 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 83, + "quota_total": 100, + "quota_used": 17, + "remaining": 83 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 83, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 100, + "used": 17 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 8, + "quota_total": 10, + "quota_used": 2, + "remaining": 8 + } + }, + "render": "Lenz usage (Free plan)\n 83 credits left (≈ 8 verifications · 83 assessments)\n Verify: 8 left (2 / 10 quota · 10 credits each · 5 at depth \"low\")\n Ask: 83 left (17 / 100 quota · 1 credit each)\n Assess: 83 left (17 / 100 quota · 1 credit each)\n Extract: 0 / 1000 today (free — no credit charge)\n Credits reset Oct 1, 2026\n", + "render_json": "{\n \"plan\": \"free\",\n \"plan_label\": \"Free\",\n \"quota_resets_at\": \"2026-10-01T14:07:00+00:00\",\n \"credits\": {\n \"total\": 100,\n \"used\": 17,\n \"remaining\": 83,\n \"extra\": 0,\n \"bonus\": 0,\n \"resets_at\": \"2026-10-01T14:07:00+00:00\"\n },\n \"costs\": {\n \"verify\": 10,\n \"assess\": 1,\n \"ask\": 1,\n \"citation\": 1,\n \"extract\": 0\n },\n \"cost_options\": {\n \"verify\": {\n \"depth\": {\n \"standard\": 10,\n \"low\": 5\n }\n }\n },\n \"verify\": {\n \"quota_used\": 2,\n \"quota_total\": 10,\n \"quota_remaining\": 8,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 8\n },\n \"ask\": {\n \"quota_used\": 17,\n \"quota_total\": 100,\n \"quota_remaining\": 83,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 83\n },\n \"assess\": {\n \"quota_used\": 17,\n \"quota_total\": 100,\n \"quota_remaining\": 83,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 83\n },\n \"extract\": {\n \"calls_today\": 0,\n \"daily_limit\": 1000,\n \"unlimited\": false\n },\n \"has_webhook_secret\": false\n}\n", + "repr": "Usage(plan='free', plan_label='Free', quota_resets_at='2026-10-01T14:07:00+00:00', credits=UsageCredits(total=100, used=17, remaining=83, extra=0, bonus=0, resets_at='2026-10-01T14:07:00+00:00'), costs={'verify': 10, 'assess': 1, 'ask': 1, 'citation': 1, 'extract': 0}, cost_options={'verify': {'depth': {'standard': 10, 'low': 5}}}, verify=UsageCapacity(quota_used=2, quota_total=10, quota_remaining=8, bonus=0, credits=0, remaining=8), ask=UsageCapacity(quota_used=17, quota_total=100, quota_remaining=83, bonus=0, credits=0, remaining=83), assess=UsageCapacity(quota_used=17, quota_total=100, quota_remaining=83, bonus=0, credits=0, remaining=83), extract=UsageExtract(calls_today=0, daily_limit=1000, unlimited=False), has_webhook_secret=False)" +} diff --git a/tests/fixtures/parity/expected/account__me_usage_oauth.json b/tests/fixtures/parity/expected/account__me_usage_oauth.json new file mode 100644 index 0000000..f2f3166 --- /dev/null +++ b/tests/fixtures/parity/expected/account__me_usage_oauth.json @@ -0,0 +1,121 @@ +{ + "dump": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 100, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 100, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 10, + "quota_total": 10, + "quota_used": 0, + "remaining": 10 + } + }, + "dump_unset": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 100, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 100, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 10, + "quota_total": 10, + "quota_used": 0, + "remaining": 10 + } + }, + "render": "Lenz usage (Free plan)\n 100 credits left (≈ 10 verifications · 100 assessments)\n Verify: 10 left (0 / 10 quota · 10 credits each · 5 at depth \"low\")\n Ask: 100 left (0 / 100 quota · 1 credit each)\n Assess: 100 left (0 / 100 quota · 1 credit each)\n Extract: 0 / 1000 today (free — no credit charge)\n Credits reset Oct 1, 2026\n", + "render_json": "{\n \"plan\": \"free\",\n \"plan_label\": \"Free\",\n \"quota_resets_at\": \"2026-10-01T14:07:00+00:00\",\n \"credits\": {\n \"total\": 100,\n \"used\": 0,\n \"remaining\": 100,\n \"extra\": 0,\n \"bonus\": 0,\n \"resets_at\": \"2026-10-01T14:07:00+00:00\"\n },\n \"costs\": {\n \"verify\": 10,\n \"assess\": 1,\n \"ask\": 1,\n \"citation\": 1,\n \"extract\": 0\n },\n \"cost_options\": {\n \"verify\": {\n \"depth\": {\n \"standard\": 10,\n \"low\": 5\n }\n }\n },\n \"verify\": {\n \"quota_used\": 0,\n \"quota_total\": 10,\n \"quota_remaining\": 10,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 10\n },\n \"ask\": {\n \"quota_used\": 0,\n \"quota_total\": 100,\n \"quota_remaining\": 100,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 100\n },\n \"assess\": {\n \"quota_used\": 0,\n \"quota_total\": 100,\n \"quota_remaining\": 100,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 100\n },\n \"extract\": {\n \"calls_today\": 0,\n \"daily_limit\": 1000,\n \"unlimited\": false\n },\n \"has_webhook_secret\": false\n}\n", + "repr": "Usage(plan='free', plan_label='Free', quota_resets_at='2026-10-01T14:07:00+00:00', credits=UsageCredits(total=100, used=0, remaining=100, extra=0, bonus=0, resets_at='2026-10-01T14:07:00+00:00'), costs={'verify': 10, 'assess': 1, 'ask': 1, 'citation': 1, 'extract': 0}, cost_options={'verify': {'depth': {'standard': 10, 'low': 5}}}, verify=UsageCapacity(quota_used=0, quota_total=10, quota_remaining=10, bonus=0, credits=0, remaining=10), ask=UsageCapacity(quota_used=0, quota_total=100, quota_remaining=100, bonus=0, credits=0, remaining=100), assess=UsageCapacity(quota_used=0, quota_total=100, quota_remaining=100, bonus=0, credits=0, remaining=100), extract=UsageExtract(calls_today=0, daily_limit=1000, unlimited=False), has_webhook_secret=False)" +} diff --git a/tests/fixtures/parity/expected/account__me_usage_plus.json b/tests/fixtures/parity/expected/account__me_usage_plus.json new file mode 100644 index 0000000..faadaf1 --- /dev/null +++ b/tests/fixtures/parity/expected/account__me_usage_plus.json @@ -0,0 +1,121 @@ +{ + "dump": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 500, + "quota_total": 500, + "quota_used": 0, + "remaining": 500 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 500, + "quota_total": 500, + "quota_used": 0, + "remaining": 500 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 500, + "resets_at": "2026-10-01T14:07:00.123456+00:00", + "total": 500, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "plus", + "plan_label": "Plus", + "quota_resets_at": "2026-10-01T14:07:00.123456+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 50, + "quota_total": 50, + "quota_used": 0, + "remaining": 50 + } + }, + "dump_unset": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 500, + "quota_total": 500, + "quota_used": 0, + "remaining": 500 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 500, + "quota_total": 500, + "quota_used": 0, + "remaining": 500 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 500, + "resets_at": "2026-10-01T14:07:00.123456+00:00", + "total": 500, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "plus", + "plan_label": "Plus", + "quota_resets_at": "2026-10-01T14:07:00.123456+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 50, + "quota_total": 50, + "quota_used": 0, + "remaining": 50 + } + }, + "render": "Lenz usage (Plus plan)\n 500 credits left (≈ 50 verifications · 500 assessments)\n Verify: 50 left (0 / 50 quota · 10 credits each · 5 at depth \"low\")\n Ask: 500 left (0 / 500 quota · 1 credit each)\n Assess: 500 left (0 / 500 quota · 1 credit each)\n Extract: 0 / 1000 today (free — no credit charge)\n Credits reset Oct 1, 2026\n", + "render_json": "{\n \"plan\": \"plus\",\n \"plan_label\": \"Plus\",\n \"quota_resets_at\": \"2026-10-01T14:07:00.123456+00:00\",\n \"credits\": {\n \"total\": 500,\n \"used\": 0,\n \"remaining\": 500,\n \"extra\": 0,\n \"bonus\": 0,\n \"resets_at\": \"2026-10-01T14:07:00.123456+00:00\"\n },\n \"costs\": {\n \"verify\": 10,\n \"assess\": 1,\n \"ask\": 1,\n \"citation\": 1,\n \"extract\": 0\n },\n \"cost_options\": {\n \"verify\": {\n \"depth\": {\n \"standard\": 10,\n \"low\": 5\n }\n }\n },\n \"verify\": {\n \"quota_used\": 0,\n \"quota_total\": 50,\n \"quota_remaining\": 50,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 50\n },\n \"ask\": {\n \"quota_used\": 0,\n \"quota_total\": 500,\n \"quota_remaining\": 500,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 500\n },\n \"assess\": {\n \"quota_used\": 0,\n \"quota_total\": 500,\n \"quota_remaining\": 500,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 500\n },\n \"extract\": {\n \"calls_today\": 0,\n \"daily_limit\": 1000,\n \"unlimited\": false\n },\n \"has_webhook_secret\": false\n}\n", + "repr": "Usage(plan='plus', plan_label='Plus', quota_resets_at='2026-10-01T14:07:00.123456+00:00', credits=UsageCredits(total=500, used=0, remaining=500, extra=0, bonus=0, resets_at='2026-10-01T14:07:00.123456+00:00'), costs={'verify': 10, 'assess': 1, 'ask': 1, 'citation': 1, 'extract': 0}, cost_options={'verify': {'depth': {'standard': 10, 'low': 5}}}, verify=UsageCapacity(quota_used=0, quota_total=50, quota_remaining=50, bonus=0, credits=0, remaining=50), ask=UsageCapacity(quota_used=0, quota_total=500, quota_remaining=500, bonus=0, credits=0, remaining=500), assess=UsageCapacity(quota_used=0, quota_total=500, quota_remaining=500, bonus=0, credits=0, remaining=500), extract=UsageExtract(calls_today=0, daily_limit=1000, unlimited=False), has_webhook_secret=False)" +} diff --git a/tests/fixtures/parity/expected/account__me_usage_pro.json b/tests/fixtures/parity/expected/account__me_usage_pro.json new file mode 100644 index 0000000..17433cd --- /dev/null +++ b/tests/fixtures/parity/expected/account__me_usage_pro.json @@ -0,0 +1,121 @@ +{ + "dump": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 5000, + "quota_total": 5000, + "quota_used": 0, + "remaining": 5000 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 5000, + "quota_total": 5000, + "quota_used": 0, + "remaining": 5000 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 5000, + "resets_at": "2026-10-01T14:07:00.123456+00:00", + "total": 5000, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "pro", + "plan_label": "Pro", + "quota_resets_at": "2026-10-01T14:07:00.123456+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 500, + "quota_total": 500, + "quota_used": 0, + "remaining": 500 + } + }, + "dump_unset": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 5000, + "quota_total": 5000, + "quota_used": 0, + "remaining": 5000 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 5000, + "quota_total": 5000, + "quota_used": 0, + "remaining": 5000 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 5000, + "resets_at": "2026-10-01T14:07:00.123456+00:00", + "total": 5000, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "pro", + "plan_label": "Pro", + "quota_resets_at": "2026-10-01T14:07:00.123456+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 500, + "quota_total": 500, + "quota_used": 0, + "remaining": 500 + } + }, + "render": "Lenz usage (Pro plan)\n 5000 credits left (≈ 500 verifications · 5000 assessments)\n Verify: 500 left (0 / 500 quota · 10 credits each · 5 at depth \"low\")\n Ask: 5000 left (0 / 5000 quota · 1 credit each)\n Assess: 5000 left (0 / 5000 quota · 1 credit each)\n Extract: 0 / 1000 today (free — no credit charge)\n Credits reset Oct 1, 2026\n", + "render_json": "{\n \"plan\": \"pro\",\n \"plan_label\": \"Pro\",\n \"quota_resets_at\": \"2026-10-01T14:07:00.123456+00:00\",\n \"credits\": {\n \"total\": 5000,\n \"used\": 0,\n \"remaining\": 5000,\n \"extra\": 0,\n \"bonus\": 0,\n \"resets_at\": \"2026-10-01T14:07:00.123456+00:00\"\n },\n \"costs\": {\n \"verify\": 10,\n \"assess\": 1,\n \"ask\": 1,\n \"citation\": 1,\n \"extract\": 0\n },\n \"cost_options\": {\n \"verify\": {\n \"depth\": {\n \"standard\": 10,\n \"low\": 5\n }\n }\n },\n \"verify\": {\n \"quota_used\": 0,\n \"quota_total\": 500,\n \"quota_remaining\": 500,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 500\n },\n \"ask\": {\n \"quota_used\": 0,\n \"quota_total\": 5000,\n \"quota_remaining\": 5000,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 5000\n },\n \"assess\": {\n \"quota_used\": 0,\n \"quota_total\": 5000,\n \"quota_remaining\": 5000,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 5000\n },\n \"extract\": {\n \"calls_today\": 0,\n \"daily_limit\": 1000,\n \"unlimited\": false\n },\n \"has_webhook_secret\": false\n}\n", + "repr": "Usage(plan='pro', plan_label='Pro', quota_resets_at='2026-10-01T14:07:00.123456+00:00', credits=UsageCredits(total=5000, used=0, remaining=5000, extra=0, bonus=0, resets_at='2026-10-01T14:07:00.123456+00:00'), costs={'verify': 10, 'assess': 1, 'ask': 1, 'citation': 1, 'extract': 0}, cost_options={'verify': {'depth': {'standard': 10, 'low': 5}}}, verify=UsageCapacity(quota_used=0, quota_total=500, quota_remaining=500, bonus=0, credits=0, remaining=500), ask=UsageCapacity(quota_used=0, quota_total=5000, quota_remaining=5000, bonus=0, credits=0, remaining=5000), assess=UsageCapacity(quota_used=0, quota_total=5000, quota_remaining=5000, bonus=0, credits=0, remaining=5000), extract=UsageExtract(calls_today=0, daily_limit=1000, unlimited=False), has_webhook_secret=False)" +} diff --git a/tests/fixtures/parity/expected/account__me_usage_pro_extra.json b/tests/fixtures/parity/expected/account__me_usage_pro_extra.json new file mode 100644 index 0000000..99126d3 --- /dev/null +++ b/tests/fixtures/parity/expected/account__me_usage_pro_extra.json @@ -0,0 +1,121 @@ +{ + "dump": { + "ask": { + "bonus": 1000, + "credits": 1000, + "quota_remaining": 6000, + "quota_total": 6000, + "quota_used": 0, + "remaining": 6000 + }, + "assess": { + "bonus": 1000, + "credits": 1000, + "quota_remaining": 6000, + "quota_total": 6000, + "quota_used": 0, + "remaining": 6000 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 1000, + "extra": 1000, + "remaining": 6000, + "resets_at": "2026-10-01T14:07:00.123456+00:00", + "total": 6000, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "pro", + "plan_label": "Pro", + "quota_resets_at": "2026-10-01T14:07:00.123456+00:00", + "verify": { + "bonus": 100, + "credits": 100, + "quota_remaining": 600, + "quota_total": 600, + "quota_used": 0, + "remaining": 600 + } + }, + "dump_unset": { + "ask": { + "bonus": 1000, + "credits": 1000, + "quota_remaining": 6000, + "quota_total": 6000, + "quota_used": 0, + "remaining": 6000 + }, + "assess": { + "bonus": 1000, + "credits": 1000, + "quota_remaining": 6000, + "quota_total": 6000, + "quota_used": 0, + "remaining": 6000 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 1000, + "extra": 1000, + "remaining": 6000, + "resets_at": "2026-10-01T14:07:00.123456+00:00", + "total": 6000, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "pro", + "plan_label": "Pro", + "quota_resets_at": "2026-10-01T14:07:00.123456+00:00", + "verify": { + "bonus": 100, + "credits": 100, + "quota_remaining": 600, + "quota_total": 600, + "quota_used": 0, + "remaining": 600 + } + }, + "render": "Lenz usage (Pro plan)\n 6000 credits left (≈ 600 verifications · 6000 assessments)\n Verify: 600 left (0 / 600 quota + 100 extra · 10 credits each · 5 at depth \"low\")\n Ask: 6000 left (0 / 6000 quota + 1000 extra · 1 credit each)\n Assess: 6000 left (0 / 6000 quota + 1000 extra · 1 credit each)\n Extract: 0 / 1000 today (free — no credit charge)\n Credits reset Oct 1, 2026\n", + "render_json": "{\n \"plan\": \"pro\",\n \"plan_label\": \"Pro\",\n \"quota_resets_at\": \"2026-10-01T14:07:00.123456+00:00\",\n \"credits\": {\n \"total\": 6000,\n \"used\": 0,\n \"remaining\": 6000,\n \"extra\": 1000,\n \"bonus\": 1000,\n \"resets_at\": \"2026-10-01T14:07:00.123456+00:00\"\n },\n \"costs\": {\n \"verify\": 10,\n \"assess\": 1,\n \"ask\": 1,\n \"citation\": 1,\n \"extract\": 0\n },\n \"cost_options\": {\n \"verify\": {\n \"depth\": {\n \"standard\": 10,\n \"low\": 5\n }\n }\n },\n \"verify\": {\n \"quota_used\": 0,\n \"quota_total\": 600,\n \"quota_remaining\": 600,\n \"bonus\": 100,\n \"credits\": 100,\n \"remaining\": 600\n },\n \"ask\": {\n \"quota_used\": 0,\n \"quota_total\": 6000,\n \"quota_remaining\": 6000,\n \"bonus\": 1000,\n \"credits\": 1000,\n \"remaining\": 6000\n },\n \"assess\": {\n \"quota_used\": 0,\n \"quota_total\": 6000,\n \"quota_remaining\": 6000,\n \"bonus\": 1000,\n \"credits\": 1000,\n \"remaining\": 6000\n },\n \"extract\": {\n \"calls_today\": 0,\n \"daily_limit\": 1000,\n \"unlimited\": false\n },\n \"has_webhook_secret\": false\n}\n", + "repr": "Usage(plan='pro', plan_label='Pro', quota_resets_at='2026-10-01T14:07:00.123456+00:00', credits=UsageCredits(total=6000, used=0, remaining=6000, extra=1000, bonus=1000, resets_at='2026-10-01T14:07:00.123456+00:00'), costs={'verify': 10, 'assess': 1, 'ask': 1, 'citation': 1, 'extract': 0}, cost_options={'verify': {'depth': {'standard': 10, 'low': 5}}}, verify=UsageCapacity(quota_used=0, quota_total=600, quota_remaining=600, bonus=100, credits=100, remaining=600), ask=UsageCapacity(quota_used=0, quota_total=6000, quota_remaining=6000, bonus=1000, credits=1000, remaining=6000), assess=UsageCapacity(quota_used=0, quota_total=6000, quota_remaining=6000, bonus=1000, credits=1000, remaining=6000), extract=UsageExtract(calls_today=0, daily_limit=1000, unlimited=False), has_webhook_secret=False)" +} diff --git a/tests/fixtures/parity/expected/account__me_usage_stale_quota_row.json b/tests/fixtures/parity/expected/account__me_usage_stale_quota_row.json new file mode 100644 index 0000000..f2f3166 --- /dev/null +++ b/tests/fixtures/parity/expected/account__me_usage_stale_quota_row.json @@ -0,0 +1,121 @@ +{ + "dump": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 100, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 100, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 10, + "quota_total": 10, + "quota_used": 0, + "remaining": 10 + } + }, + "dump_unset": { + "ask": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "assess": { + "bonus": 0, + "credits": 0, + "quota_remaining": 100, + "quota_total": 100, + "quota_used": 0, + "remaining": 100 + }, + "cost_options": { + "verify": { + "depth": { + "low": 5, + "standard": 10 + } + } + }, + "costs": { + "ask": 1, + "assess": 1, + "citation": 1, + "extract": 0, + "verify": 10 + }, + "credits": { + "bonus": 0, + "extra": 0, + "remaining": 100, + "resets_at": "2026-10-01T14:07:00+00:00", + "total": 100, + "used": 0 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false, + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "verify": { + "bonus": 0, + "credits": 0, + "quota_remaining": 10, + "quota_total": 10, + "quota_used": 0, + "remaining": 10 + } + }, + "render": "Lenz usage (Free plan)\n 100 credits left (≈ 10 verifications · 100 assessments)\n Verify: 10 left (0 / 10 quota · 10 credits each · 5 at depth \"low\")\n Ask: 100 left (0 / 100 quota · 1 credit each)\n Assess: 100 left (0 / 100 quota · 1 credit each)\n Extract: 0 / 1000 today (free — no credit charge)\n Credits reset Oct 1, 2026\n", + "render_json": "{\n \"plan\": \"free\",\n \"plan_label\": \"Free\",\n \"quota_resets_at\": \"2026-10-01T14:07:00+00:00\",\n \"credits\": {\n \"total\": 100,\n \"used\": 0,\n \"remaining\": 100,\n \"extra\": 0,\n \"bonus\": 0,\n \"resets_at\": \"2026-10-01T14:07:00+00:00\"\n },\n \"costs\": {\n \"verify\": 10,\n \"assess\": 1,\n \"ask\": 1,\n \"citation\": 1,\n \"extract\": 0\n },\n \"cost_options\": {\n \"verify\": {\n \"depth\": {\n \"standard\": 10,\n \"low\": 5\n }\n }\n },\n \"verify\": {\n \"quota_used\": 0,\n \"quota_total\": 10,\n \"quota_remaining\": 10,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 10\n },\n \"ask\": {\n \"quota_used\": 0,\n \"quota_total\": 100,\n \"quota_remaining\": 100,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 100\n },\n \"assess\": {\n \"quota_used\": 0,\n \"quota_total\": 100,\n \"quota_remaining\": 100,\n \"bonus\": 0,\n \"credits\": 0,\n \"remaining\": 100\n },\n \"extract\": {\n \"calls_today\": 0,\n \"daily_limit\": 1000,\n \"unlimited\": false\n },\n \"has_webhook_secret\": false\n}\n", + "repr": "Usage(plan='free', plan_label='Free', quota_resets_at='2026-10-01T14:07:00+00:00', credits=UsageCredits(total=100, used=0, remaining=100, extra=0, bonus=0, resets_at='2026-10-01T14:07:00+00:00'), costs={'verify': 10, 'assess': 1, 'ask': 1, 'citation': 1, 'extract': 0}, cost_options={'verify': {'depth': {'standard': 10, 'low': 5}}}, verify=UsageCapacity(quota_used=0, quota_total=10, quota_remaining=10, bonus=0, credits=0, remaining=10), ask=UsageCapacity(quota_used=0, quota_total=100, quota_remaining=100, bonus=0, credits=0, remaining=100), assess=UsageCapacity(quota_used=0, quota_total=100, quota_remaining=100, bonus=0, credits=0, remaining=100), extract=UsageExtract(calls_today=0, daily_limit=1000, unlimited=False), has_webhook_secret=False)" +} diff --git a/tests/fixtures/parity/expected/account__oauth_register_success.json b/tests/fixtures/parity/expected/account__oauth_register_success.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/parity/expected/account__oauth_register_success.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/parity/expected/account__oauth_revoke.json b/tests/fixtures/parity/expected/account__oauth_revoke.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/parity/expected/account__oauth_revoke.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/parity/expected/account__oauth_revoke_token.json b/tests/fixtures/parity/expected/account__oauth_revoke_token.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/parity/expected/account__oauth_revoke_token.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/parity/expected/account__webhook_secret_api_key.json b/tests/fixtures/parity/expected/account__webhook_secret_api_key.json new file mode 100644 index 0000000..99f0634 --- /dev/null +++ b/tests/fixtures/parity/expected/account__webhook_secret_api_key.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "An API key's webhook secret is managed on the API credentials page (https://lenz.io/api-credentials). This endpoint is for OAuth connections.", + "code": "oauth_only", + "doc_url": "https://lenz.io/docs/auth", + "fix": "This key doesn't have access to that resource.", + "friendly_text": "An API key's webhook secret is managed on the API credentials page (https://lenz.io/api-credentials). This endpoint is for OAuth connections.\n Fix: This key doesn't have access to that resource.", + "message": "An API key's webhook secret is managed on the API credentials page (https://lenz.io/api-credentials). This endpoint is for OAuth connections.", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "This key doesn't have access to that resource.", + "message": "An API key's webhook secret is managed on the API credentials page (https://lenz.io/api-credentials). This endpoint is for OAuth connections.", + "status": 403 + } + }, + "request_id": "", + "status_code": 403, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/account__webhook_secret_insufficient_scope.json b/tests/fixtures/parity/expected/account__webhook_secret_insufficient_scope.json new file mode 100644 index 0000000..567f3ae --- /dev/null +++ b/tests/fixtures/parity/expected/account__webhook_secret_insufficient_scope.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "The access token does not allow this call.", + "code": "insufficient_scope", + "doc_url": "https://lenz.io/docs/auth", + "fix": "This key doesn't have access to that resource.", + "friendly_text": "The access token does not allow this call.\n Fix: This key doesn't have access to that resource.", + "message": "The access token does not allow this call.", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "This key doesn't have access to that resource.", + "message": "The access token does not allow this call.", + "status": 403 + } + }, + "request_id": "", + "status_code": 403, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/account__webhook_secret_oauth.json b/tests/fixtures/parity/expected/account__webhook_secret_oauth.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/tests/fixtures/parity/expected/account__webhook_secret_oauth.json @@ -0,0 +1 @@ +{} diff --git a/tests/fixtures/parity/expected/assess__401_no_key.json b/tests/fixtures/parity/expected/assess__401_no_key.json new file mode 100644 index 0000000..e57982a --- /dev/null +++ b/tests/fixtures/parity/expected/assess__401_no_key.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Unauthorized", + "code": "", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "Unauthorized\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/assess__402_no_credits.json b/tests/fixtures/parity/expected/assess__402_no_credits.json new file mode 100644 index 0000000..91af7cd --- /dev/null +++ b/tests/fixtures/parity/expected/assess__402_no_credits.json @@ -0,0 +1,28 @@ +{ + "error": { + "cause": "No remaining /assess units.", + "code": "no_credits", + "cost": 1, + "credit_balance": 0, + "doc_url": "https://lenz.io/docs/billing", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "friendly_text": "No remaining /assess units.\n Fix: Top up or upgrade at https://lenz.io/plans, or wait for the period reset. See https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "message": "No remaining /assess units.", + "payload_json": { + "error": { + "code": "no_credits", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "message": "No remaining /assess units.", + "status": 402, + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } + }, + "remaining": 0, + "request_id": "", + "requested": null, + "resets_at": "2026-10-01T14:07:00+00:00", + "status_code": 402, + "type": "LenzQuotaExceededError", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } +} diff --git a/tests/fixtures/parity/expected/assess__422_blank_item.json b/tests/fixtures/parity/expected/assess__422_blank_item.json new file mode 100644 index 0000000..4b35c85 --- /dev/null +++ b/tests/fixtures/parity/expected/assess__422_blank_item.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "claims[1] is blank.", + "code": "blank_item", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "claims[1] is blank.\n Fix: Check the request body against the OpenAPI spec.", + "message": "claims[1] is blank.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "claims[1] is blank.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/assess__422_blank_text.json b/tests/fixtures/parity/expected/assess__422_blank_text.json new file mode 100644 index 0000000..872ff11 --- /dev/null +++ b/tests/fixtures/parity/expected/assess__422_blank_text.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Text is required.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Text is required.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Text is required.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Text is required.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/assess__422_input_conflict.json b/tests/fixtures/parity/expected/assess__422_input_conflict.json new file mode 100644 index 0000000..215d4af --- /dev/null +++ b/tests/fixtures/parity/expected/assess__422_input_conflict.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Send either `claim` (one text) or `claims` (a list of claims), not both.", + "code": "input_conflict", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Send either `claim` (one text) or `claims` (a list of claims), not both.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Send either `claim` (one text) or `claims` (a list of claims), not both.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Send either `claim` (one text) or `claims` (a list of claims), not both.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/assess__422_item_too_long.json b/tests/fixtures/parity/expected/assess__422_item_too_long.json new file mode 100644 index 0000000..1e678c0 --- /dev/null +++ b/tests/fixtures/parity/expected/assess__422_item_too_long.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "claims[1] is 2001 characters; each claim may be at most 2000. Send a document to /extract first, then assess its claims.", + "code": "item_too_long", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "claims[1] is 2001 characters; each claim may be at most 2000. Send a document to /extract first, then assess its claims.\n Fix: Check the request body against the OpenAPI spec.", + "message": "claims[1] is 2001 characters; each claim may be at most 2000. Send a document to /extract first, then assess its claims.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "claims[1] is 2001 characters; each claim may be at most 2000. Send a document to /extract first, then assess its claims.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/assess__422_no_input_field.json b/tests/fixtures/parity/expected/assess__422_no_input_field.json new file mode 100644 index 0000000..6760d1a --- /dev/null +++ b/tests/fixtures/parity/expected/assess__422_no_input_field.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required", + "type": "missing" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]\n Fix: Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/assess__422_too_many_items.json b/tests/fixtures/parity/expected/assess__422_too_many_items.json new file mode 100644 index 0000000..14bdc66 --- /dev/null +++ b/tests/fixtures/parity/expected/assess__422_too_many_items.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "At most 20 claims per call; got 21. Split the list.", + "code": "too_many_items", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "At most 20 claims per call; got 21. Split the list.\n Fix: Check the request body against the OpenAPI spec.", + "message": "At most 20 claims per call; got 21. Split the list.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "At most 20 claims per call; got 21. Split the list.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/assess__422_wrong_type_claim.json b/tests/fixtures/parity/expected/assess__422_wrong_type_claim.json new file mode 100644 index 0000000..45b3d77 --- /dev/null +++ b/tests/fixtures/parity/expected/assess__422_wrong_type_claim.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "[{'type': 'string_type', 'loc': ['body', 'payload', 'claim'], 'msg': 'Input should be a valid string'}]", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "claim" + ], + "msg": "Input should be a valid string", + "type": "string_type" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "[{'type': 'string_type', 'loc': ['body', 'payload', 'claim'], 'msg': 'Input should be a valid string'}]\n Fix: Check the request body against the OpenAPI spec.", + "message": "[{'type': 'string_type', 'loc': ['body', 'payload', 'claim'], 'msg': 'Input should be a valid string'}]", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "[{'type': 'string_type', 'loc': ['body', 'payload', 'claim'], 'msg': 'Input should be a valid string'}]", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/assess__422_wrong_type_claims.json b/tests/fixtures/parity/expected/assess__422_wrong_type_claims.json new file mode 100644 index 0000000..7713b4c --- /dev/null +++ b/tests/fixtures/parity/expected/assess__422_wrong_type_claims.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "[{'type': 'list_type', 'loc': ['body', 'payload', 'claims'], 'msg': 'Input should be a valid list'}]", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "claims" + ], + "msg": "Input should be a valid list", + "type": "list_type" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "[{'type': 'list_type', 'loc': ['body', 'payload', 'claims'], 'msg': 'Input should be a valid list'}]\n Fix: Check the request body against the OpenAPI spec.", + "message": "[{'type': 'list_type', 'loc': ['body', 'payload', 'claims'], 'msg': 'Input should be a valid list'}]", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "[{'type': 'list_type', 'loc': ['body', 'payload', 'claims'], 'msg': 'Input should be a valid list'}]", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/assess__502_framing_failed.json b/tests/fixtures/parity/expected/assess__502_framing_failed.json new file mode 100644 index 0000000..c8d0b2d --- /dev/null +++ b/tests/fixtures/parity/expected/assess__502_framing_failed.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Framing failed", + "code": "framing_failed", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Framing failed\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Framing failed", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Framing failed", + "status": 502 + } + }, + "request_id": "", + "retry_after": null, + "status_code": 502, + "type": "LenzAPIError" + } +} diff --git a/tests/fixtures/parity/expected/assess__503_capacity.json b/tests/fixtures/parity/expected/assess__503_capacity.json new file mode 100644 index 0000000..017e2bc --- /dev/null +++ b/tests/fixtures/parity/expected/assess__503_capacity.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "doc_url": "https://lenz.io/docs/errors#unavailable", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "status": 503 + } + }, + "request_id": "", + "retry_after": 100, + "status_code": 503, + "type": "LenzUpstreamUnavailableError" + } +} diff --git a/tests/fixtures/parity/expected/assess__503_list_all_upstream_unavailable.json b/tests/fixtures/parity/expected/assess__503_list_all_upstream_unavailable.json new file mode 100644 index 0000000..b61a2fb --- /dev/null +++ b/tests/fixtures/parity/expected/assess__503_list_all_upstream_unavailable.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Our model providers are temporarily unavailable. Please retry shortly. Nothing was charged.", + "code": "upstream_unavailable", + "doc_url": "https://lenz.io/docs/errors#unavailable", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Our model providers are temporarily unavailable. Please retry shortly. Nothing was charged.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Our model providers are temporarily unavailable. Please retry shortly. Nothing was charged.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Our model providers are temporarily unavailable. Please retry shortly. Nothing was charged.", + "status": 503 + } + }, + "request_id": "", + "retry_after": 90, + "status_code": 503, + "type": "LenzUpstreamUnavailableError" + } +} diff --git a/tests/fixtures/parity/expected/assess__503_upstream_unavailable.json b/tests/fixtures/parity/expected/assess__503_upstream_unavailable.json new file mode 100644 index 0000000..7553c4c --- /dev/null +++ b/tests/fixtures/parity/expected/assess__503_upstream_unavailable.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Our model providers are temporarily unavailable. Please retry shortly.", + "code": "upstream_unavailable", + "doc_url": "https://lenz.io/docs/errors#unavailable", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Our model providers are temporarily unavailable. Please retry shortly.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Our model providers are temporarily unavailable. Please retry shortly.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Our model providers are temporarily unavailable. Please retry shortly.", + "status": 503 + } + }, + "request_id": "", + "retry_after": 90, + "status_code": 503, + "type": "LenzUpstreamUnavailableError" + } +} diff --git a/tests/fixtures/parity/expected/assess__deep_tier_hit.json b/tests/fixtures/parity/expected/assess__deep_tier_hit.json new file mode 100644 index 0000000..2964620 --- /dev/null +++ b/tests/fixtures/parity/expected/assess__deep_tier_hit.json @@ -0,0 +1,47 @@ +{ + "dump": { + "candidate_claims": [], + "claims": [ + { + "candidate_claims": [], + "claim": "Water boils at 100C.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": "The claim is verified.", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": "https://lenz.io/api/v1/verifications/f3436f50" + } + ], + "error": null, + "error_code": "", + "more_claims": [] + }, + "dump_unset": { + "claims": [ + { + "candidate_claims": [], + "claim": "Water boils at 100C.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": "The claim is verified.", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": "https://lenz.io/api/v1/verifications/f3436f50" + } + ], + "error": null, + "more_claims": [] + }, + "render": "True (high) — Water boils at 100C.\n The claim is verified.\n ask follow-ups: lenz ask f3436f50 \"\"\n", + "render_json": "{\n \"claims\": [\n {\n \"claim\": \"Water boils at 100C.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": \"https://lenz.io/api/v1/verifications/f3436f50\",\n \"rationale\": \"The claim is verified.\",\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n }\n ],\n \"error\": null,\n \"error_code\": \"\",\n \"candidate_claims\": [],\n \"more_claims\": []\n}\n", + "repr": "AssessResponse(claims=[AssessClaim(claim='Water boils at 100C.', language='en', verdict='True', confidence='high', verification_url='https://lenz.io/api/v1/verifications/f3436f50', rationale='The claim is verified.', dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None)], error=None, error_code='', candidate_claims=[], more_claims=[])" +} diff --git a/tests/fixtures/parity/expected/assess__idempotency_body_mismatch.json b/tests/fixtures/parity/expected/assess__idempotency_body_mismatch.json new file mode 100644 index 0000000..989af48 --- /dev/null +++ b/tests/fixtures/parity/expected/assess__idempotency_body_mismatch.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Idempotency-Key reused with a different request body.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Idempotency-Key reused with a different request body.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Idempotency-Key reused with a different request body.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Idempotency-Key reused with a different request body.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/assess__idempotency_first.json b/tests/fixtures/parity/expected/assess__idempotency_first.json new file mode 100644 index 0000000..614661f --- /dev/null +++ b/tests/fixtures/parity/expected/assess__idempotency_first.json @@ -0,0 +1,47 @@ +{ + "dump": { + "candidate_claims": [], + "claims": [ + { + "candidate_claims": [], + "claim": "The Earth orbits the Sun.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "error_code": "", + "more_claims": [] + }, + "dump_unset": { + "claims": [ + { + "candidate_claims": [], + "claim": "The Earth orbits the Sun.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "more_claims": [] + }, + "render": "True (high) — The Earth orbits the Sun.\n", + "render_json": "{\n \"claims\": [\n {\n \"claim\": \"The Earth orbits the Sun.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n }\n ],\n \"error\": null,\n \"error_code\": \"\",\n \"candidate_claims\": [],\n \"more_claims\": []\n}\n", + "repr": "AssessResponse(claims=[AssessClaim(claim='The Earth orbits the Sun.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None)], error=None, error_code='', candidate_claims=[], more_claims=[])" +} diff --git a/tests/fixtures/parity/expected/assess__idempotency_replay.json b/tests/fixtures/parity/expected/assess__idempotency_replay.json new file mode 100644 index 0000000..614661f --- /dev/null +++ b/tests/fixtures/parity/expected/assess__idempotency_replay.json @@ -0,0 +1,47 @@ +{ + "dump": { + "candidate_claims": [], + "claims": [ + { + "candidate_claims": [], + "claim": "The Earth orbits the Sun.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "error_code": "", + "more_claims": [] + }, + "dump_unset": { + "claims": [ + { + "candidate_claims": [], + "claim": "The Earth orbits the Sun.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "more_claims": [] + }, + "render": "True (high) — The Earth orbits the Sun.\n", + "render_json": "{\n \"claims\": [\n {\n \"claim\": \"The Earth orbits the Sun.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n }\n ],\n \"error\": null,\n \"error_code\": \"\",\n \"candidate_claims\": [],\n \"more_claims\": []\n}\n", + "repr": "AssessResponse(claims=[AssessClaim(claim='The Earth orbits the Sun.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None)], error=None, error_code='', candidate_claims=[], more_claims=[])" +} diff --git a/tests/fixtures/parity/expected/assess__list_all_error_rows.json b/tests/fixtures/parity/expected/assess__list_all_error_rows.json new file mode 100644 index 0000000..5617abd --- /dev/null +++ b/tests/fixtures/parity/expected/assess__list_all_error_rows.json @@ -0,0 +1,75 @@ +{ + "dump": { + "candidate_claims": [], + "claims": [ + { + "candidate_claims": [], + "claim": "hi", + "confidence": "low", + "dissent": null, + "error_code": "no_claim", + "hint": "The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.", + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Error", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "hello", + "confidence": "low", + "dissent": null, + "error_code": "no_claim", + "hint": "The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.", + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Error", + "verification_url": null + } + ], + "error": null, + "error_code": "", + "more_claims": [] + }, + "dump_unset": { + "claims": [ + { + "candidate_claims": [], + "claim": "hi", + "confidence": "low", + "dissent": null, + "error_code": "no_claim", + "hint": "The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.", + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Error", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "hello", + "confidence": "low", + "dissent": null, + "error_code": "no_claim", + "hint": "The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.", + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Error", + "verification_url": null + } + ], + "error": null, + "more_claims": [] + }, + "render": "Error (no_claim) — hi\n The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.\nError (no_claim) — hello\n The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.\n", + "render_json": "{\n \"claims\": [\n {\n \"claim\": \"hi\",\n \"language\": \"en\",\n \"verdict\": \"Error\",\n \"confidence\": \"low\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": \"no_claim\",\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": \"The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.\"\n },\n {\n \"claim\": \"hello\",\n \"language\": \"en\",\n \"verdict\": \"Error\",\n \"confidence\": \"low\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": \"no_claim\",\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": \"The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.\"\n }\n ],\n \"error\": null,\n \"error_code\": \"\",\n \"candidate_claims\": [],\n \"more_claims\": []\n}\n", + "repr": "AssessResponse(claims=[AssessClaim(claim='hi', language='en', verdict='Error', confidence='low', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code='no_claim', candidate_claims=[], identified_claims=[], hint='The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.'), AssessClaim(claim='hello', language='en', verdict='Error', confidence='low', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code='no_claim', candidate_claims=[], identified_claims=[], hint='The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.')], error=None, error_code='', candidate_claims=[], more_claims=[])" +} diff --git a/tests/fixtures/parity/expected/assess__list_compound_item.json b/tests/fixtures/parity/expected/assess__list_compound_item.json new file mode 100644 index 0000000..550432b --- /dev/null +++ b/tests/fixtures/parity/expected/assess__list_compound_item.json @@ -0,0 +1,81 @@ +{ + "dump": { + "candidate_claims": [], + "claims": [ + { + "candidate_claims": [], + "claim": "Primary claim.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": "Assessed the main claim only. Send identified_claims as their own items to check the rest.", + "identified_claims": [ + "Second claim.", + "Third claim." + ], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Mostly False", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "A plain claim.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Mostly False", + "verification_url": null + } + ], + "error": null, + "error_code": "", + "more_claims": [] + }, + "dump_unset": { + "claims": [ + { + "candidate_claims": [], + "claim": "Primary claim.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": "Assessed the main claim only. Send identified_claims as their own items to check the rest.", + "identified_claims": [ + "Second claim.", + "Third claim." + ], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Mostly False", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "A plain claim.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Mostly False", + "verification_url": null + } + ], + "error": null, + "more_claims": [] + }, + "render": "Mostly False (high) — Primary claim.\n also found:\n • Second claim.\n • Third claim.\n Assessed the main claim only. Send identified_claims as their own items to check the rest.\nMostly False (high) — A plain claim.\n", + "render_json": "{\n \"claims\": [\n {\n \"claim\": \"Primary claim.\",\n \"language\": \"en\",\n \"verdict\": \"Mostly False\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [\n \"Second claim.\",\n \"Third claim.\"\n ],\n \"hint\": \"Assessed the main claim only. Send identified_claims as their own items to check the rest.\"\n },\n {\n \"claim\": \"A plain claim.\",\n \"language\": \"en\",\n \"verdict\": \"Mostly False\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n }\n ],\n \"error\": null,\n \"error_code\": \"\",\n \"candidate_claims\": [],\n \"more_claims\": []\n}\n", + "repr": "AssessResponse(claims=[AssessClaim(claim='Primary claim.', language='en', verdict='Mostly False', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=['Second claim.', 'Third claim.'], hint='Assessed the main claim only. Send identified_claims as their own items to check the rest.'), AssessClaim(claim='A plain claim.', language='en', verdict='Mostly False', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None)], error=None, error_code='', candidate_claims=[], more_claims=[])" +} diff --git a/tests/fixtures/parity/expected/assess__list_mixed_rows.json b/tests/fixtures/parity/expected/assess__list_mixed_rows.json new file mode 100644 index 0000000..edb640a --- /dev/null +++ b/tests/fixtures/parity/expected/assess__list_mixed_rows.json @@ -0,0 +1,131 @@ +{ + "dump": { + "candidate_claims": [], + "claims": [ + { + "candidate_claims": [], + "claim": "Water boils at 100 C at sea level.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "hello there", + "confidence": "low", + "dissent": null, + "error_code": "no_claim", + "hint": "The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.", + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Error", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "vendor is down", + "confidence": "low", + "dissent": null, + "error_code": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Error", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "cannot frame", + "confidence": "low", + "dissent": null, + "error_code": "framing_failed", + "hint": "This item could not be processed; retrying it as-is will not help. Send it rephrased as one factual statement; nothing was charged.", + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Error", + "verification_url": null + } + ], + "error": null, + "error_code": "", + "more_claims": [] + }, + "dump_unset": { + "claims": [ + { + "candidate_claims": [], + "claim": "Water boils at 100 C at sea level.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "hello there", + "confidence": "low", + "dissent": null, + "error_code": "no_claim", + "hint": "The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.", + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Error", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "vendor is down", + "confidence": "low", + "dissent": null, + "error_code": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Error", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "cannot frame", + "confidence": "low", + "dissent": null, + "error_code": "framing_failed", + "hint": "This item could not be processed; retrying it as-is will not help. Send it rephrased as one factual statement; nothing was charged.", + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Error", + "verification_url": null + } + ], + "error": null, + "more_claims": [] + }, + "render": "True (high) — Water boils at 100 C at sea level.\nError (no_claim) — hello there\n The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.\nError (upstream_unavailable) — vendor is down\n A model provider was unavailable for this item. Retry it; nothing was charged.\nError (framing_failed) — cannot frame\n This item could not be processed; retrying it as-is will not help. Send it rephrased as one factual statement; \nnothing was charged.\n", + "render_json": "{\n \"claims\": [\n {\n \"claim\": \"Water boils at 100 C at sea level.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"hello there\",\n \"language\": \"en\",\n \"verdict\": \"Error\",\n \"confidence\": \"low\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": \"no_claim\",\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": \"The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.\"\n },\n {\n \"claim\": \"vendor is down\",\n \"language\": \"en\",\n \"verdict\": \"Error\",\n \"confidence\": \"low\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": \"upstream_unavailable\",\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": \"A model provider was unavailable for this item. Retry it; nothing was charged.\"\n },\n {\n \"claim\": \"cannot frame\",\n \"language\": \"en\",\n \"verdict\": \"Error\",\n \"confidence\": \"low\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": \"framing_failed\",\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": \"This item could not be processed; retrying it as-is will not help. Send it rephrased as one factual statement; nothing was charged.\"\n }\n ],\n \"error\": null,\n \"error_code\": \"\",\n \"candidate_claims\": [],\n \"more_claims\": []\n}\n", + "repr": "AssessResponse(claims=[AssessClaim(claim='Water boils at 100 C at sea level.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='hello there', language='en', verdict='Error', confidence='low', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code='no_claim', candidate_claims=[], identified_claims=[], hint='The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims.'), AssessClaim(claim='vendor is down', language='en', verdict='Error', confidence='low', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code='upstream_unavailable', candidate_claims=[], identified_claims=[], hint='A model provider was unavailable for this item. Retry it; nothing was charged.'), AssessClaim(claim='cannot frame', language='en', verdict='Error', confidence='low', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code='framing_failed', candidate_claims=[], identified_claims=[], hint='This item could not be processed; retrying it as-is will not help. Send it rephrased as one factual statement; nothing was charged.')], error=None, error_code='', candidate_claims=[], more_claims=[])" +} diff --git a/tests/fixtures/parity/expected/assess__memo_hit.json b/tests/fixtures/parity/expected/assess__memo_hit.json new file mode 100644 index 0000000..9fad459 --- /dev/null +++ b/tests/fixtures/parity/expected/assess__memo_hit.json @@ -0,0 +1,47 @@ +{ + "dump": { + "candidate_claims": [], + "claims": [ + { + "candidate_claims": [], + "claim": "The Danube flows through Vienna.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": "The river runs through the city.", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "error_code": "", + "more_claims": [] + }, + "dump_unset": { + "claims": [ + { + "candidate_claims": [], + "claim": "The Danube flows through Vienna.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": "The river runs through the city.", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "more_claims": [] + }, + "render": "True (high) — The Danube flows through Vienna.\n The river runs through the city.\n", + "render_json": "{\n \"claims\": [\n {\n \"claim\": \"The Danube flows through Vienna.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": \"The river runs through the city.\",\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n }\n ],\n \"error\": null,\n \"error_code\": \"\",\n \"candidate_claims\": [],\n \"more_claims\": []\n}\n", + "repr": "AssessResponse(claims=[AssessClaim(claim='The Danube flows through Vienna.', language='en', verdict='True', confidence='high', verification_url=None, rationale='The river runs through the city.', dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None)], error=None, error_code='', candidate_claims=[], more_claims=[])" +} diff --git a/tests/fixtures/parity/expected/assess__replay_later_200.json b/tests/fixtures/parity/expected/assess__replay_later_200.json new file mode 100644 index 0000000..614661f --- /dev/null +++ b/tests/fixtures/parity/expected/assess__replay_later_200.json @@ -0,0 +1,47 @@ +{ + "dump": { + "candidate_claims": [], + "claims": [ + { + "candidate_claims": [], + "claim": "The Earth orbits the Sun.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "error_code": "", + "more_claims": [] + }, + "dump_unset": { + "claims": [ + { + "candidate_claims": [], + "claim": "The Earth orbits the Sun.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "more_claims": [] + }, + "render": "True (high) — The Earth orbits the Sun.\n", + "render_json": "{\n \"claims\": [\n {\n \"claim\": \"The Earth orbits the Sun.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n }\n ],\n \"error\": null,\n \"error_code\": \"\",\n \"candidate_claims\": [],\n \"more_claims\": []\n}\n", + "repr": "AssessResponse(claims=[AssessClaim(claim='The Earth orbits the Sun.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None)], error=None, error_code='', candidate_claims=[], more_claims=[])" +} diff --git a/tests/fixtures/parity/expected/assess__single_no_claim.json b/tests/fixtures/parity/expected/assess__single_no_claim.json new file mode 100644 index 0000000..71489d8 --- /dev/null +++ b/tests/fixtures/parity/expected/assess__single_no_claim.json @@ -0,0 +1,19 @@ +{ + "dump": { + "candidate_claims": [], + "claims": [], + "error": "No verifiable claim detected", + "error_code": "no_claim", + "more_claims": [] + }, + "dump_unset": { + "candidate_claims": [], + "claims": [], + "error": "No verifiable claim detected", + "error_code": "no_claim", + "more_claims": [] + }, + "render": "No claim found.\n", + "render_json": "{\n \"claims\": [],\n \"error\": \"No verifiable claim detected\",\n \"error_code\": \"no_claim\",\n \"candidate_claims\": [],\n \"more_claims\": []\n}\n", + "repr": "AssessResponse(claims=[], error='No verifiable claim detected', error_code='no_claim', candidate_claims=[], more_claims=[])" +} diff --git a/tests/fixtures/parity/expected/assess__single_one_claim.json b/tests/fixtures/parity/expected/assess__single_one_claim.json new file mode 100644 index 0000000..a5ad7b9 --- /dev/null +++ b/tests/fixtures/parity/expected/assess__single_one_claim.json @@ -0,0 +1,47 @@ +{ + "dump": { + "candidate_claims": [], + "claims": [ + { + "candidate_claims": [], + "claim": "The registry reported 4,200 filings in 2024.", + "confidence": "high", + "dissent": "The registry figure is provisional, so the 2024 total cannot yet be confirmed.", + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": "The registry lists 4,200 filings for 2024 and has not revised the figure.", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "error_code": "", + "more_claims": [] + }, + "dump_unset": { + "claims": [ + { + "candidate_claims": [], + "claim": "The registry reported 4,200 filings in 2024.", + "confidence": "high", + "dissent": "The registry figure is provisional, so the 2024 total cannot yet be confirmed.", + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": "The registry lists 4,200 filings for 2024 and has not revised the figure.", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "more_claims": [] + }, + "render": "True (high) — The registry reported 4,200 filings in 2024.\n The registry lists 4,200 filings for 2024 and has not revised the figure.\n One reviewer disagreed: The registry figure is provisional, so the 2024 total cannot yet be confirmed.\n", + "render_json": "{\n \"claims\": [\n {\n \"claim\": \"The registry reported 4,200 filings in 2024.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": \"The registry lists 4,200 filings for 2024 and has not revised the figure.\",\n \"dissent\": \"The registry figure is provisional, so the 2024 total cannot yet be confirmed.\",\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n }\n ],\n \"error\": null,\n \"error_code\": \"\",\n \"candidate_claims\": [],\n \"more_claims\": []\n}\n", + "repr": "AssessResponse(claims=[AssessClaim(claim='The registry reported 4,200 filings in 2024.', language='en', verdict='True', confidence='high', verification_url=None, rationale='The registry lists 4,200 filings for 2024 and has not revised the figure.', dissent='The registry figure is provisional, so the 2024 total cannot yet be confirmed.', suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None)], error=None, error_code='', candidate_claims=[], more_claims=[])" +} diff --git a/tests/fixtures/parity/expected/assess__single_text_over_wave_more_claims.json b/tests/fixtures/parity/expected/assess__single_text_over_wave_more_claims.json new file mode 100644 index 0000000..1a19a79 --- /dev/null +++ b/tests/fixtures/parity/expected/assess__single_text_over_wave_more_claims.json @@ -0,0 +1,585 @@ +{ + "dump": { + "candidate_claims": [], + "claims": [ + { + "candidate_claims": [], + "claim": "Claim number 0 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 1 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 2 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 3 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 4 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 5 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 6 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 7 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 8 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 9 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 10 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 11 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 12 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 13 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 14 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 15 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 16 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 17 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 18 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 19 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "error_code": "", + "more_claims": [ + "Claim number 20 is documented.", + "Claim number 21 is documented." + ] + }, + "dump_unset": { + "claims": [ + { + "candidate_claims": [], + "claim": "Claim number 0 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 1 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 2 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 3 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 4 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 5 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 6 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 7 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 8 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 9 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 10 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 11 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 12 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 13 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 14 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 15 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 16 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 17 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 18 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Claim number 19 is documented.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "more_claims": [ + "Claim number 20 is documented.", + "Claim number 21 is documented." + ] + }, + "render": "True (high) — Claim number 0 is documented.\nTrue (high) — Claim number 1 is documented.\nTrue (high) — Claim number 2 is documented.\nTrue (high) — Claim number 3 is documented.\nTrue (high) — Claim number 4 is documented.\nTrue (high) — Claim number 5 is documented.\nTrue (high) — Claim number 6 is documented.\nTrue (high) — Claim number 7 is documented.\nTrue (high) — Claim number 8 is documented.\nTrue (high) — Claim number 9 is documented.\nTrue (high) — Claim number 10 is documented.\nTrue (high) — Claim number 11 is documented.\nTrue (high) — Claim number 12 is documented.\nTrue (high) — Claim number 13 is documented.\nTrue (high) — Claim number 14 is documented.\nTrue (high) — Claim number 15 is documented.\nTrue (high) — Claim number 16 is documented.\nTrue (high) — Claim number 17 is documented.\nTrue (high) — Claim number 18 is documented.\nTrue (high) — Claim number 19 is documented.\n\nNot checked (2 more claims found; pass them to `lenz assess`, 20 a call):\n • Claim number 20 is documented.\n • Claim number 21 is documented.\n", + "render_json": "{\n \"claims\": [\n {\n \"claim\": \"Claim number 0 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 1 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 2 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 3 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 4 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 5 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 6 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 7 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 8 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 9 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 10 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 11 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 12 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 13 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 14 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 15 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 16 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 17 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 18 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Claim number 19 is documented.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n }\n ],\n \"error\": null,\n \"error_code\": \"\",\n \"candidate_claims\": [],\n \"more_claims\": [\n \"Claim number 20 is documented.\",\n \"Claim number 21 is documented.\"\n ]\n}\n", + "repr": "AssessResponse(claims=[AssessClaim(claim='Claim number 0 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 1 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 2 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 3 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 4 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 5 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 6 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 7 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 8 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 9 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 10 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 11 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 12 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 13 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 14 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 15 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 16 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 17 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 18 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Claim number 19 is documented.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None)], error=None, error_code='', candidate_claims=[], more_claims=['Claim number 20 is documented.', 'Claim number 21 is documented.'])" +} diff --git a/tests/fixtures/parity/expected/assess__single_text_several_claims.json b/tests/fixtures/parity/expected/assess__single_text_several_claims.json new file mode 100644 index 0000000..c3d142e --- /dev/null +++ b/tests/fixtures/parity/expected/assess__single_text_several_claims.json @@ -0,0 +1,103 @@ +{ + "dump": { + "candidate_claims": [], + "claims": [ + { + "candidate_claims": [], + "claim": "Water boils at 100 C at sea level.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "The Moon is made of cheese.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "The Pacific is the deepest ocean.", + "confidence": "medium", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Mostly True", + "verification_url": null + } + ], + "error": null, + "error_code": "", + "more_claims": [] + }, + "dump_unset": { + "claims": [ + { + "candidate_claims": [], + "claim": "Water boils at 100 C at sea level.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "The Moon is made of cheese.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "The Pacific is the deepest ocean.", + "confidence": "medium", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": null, + "suggested_rewrite": null, + "verdict": "Mostly True", + "verification_url": null + } + ], + "error": null, + "more_claims": [] + }, + "render": "True (high) — Water boils at 100 C at sea level.\nFalse (high) — The Moon is made of cheese.\nMostly True (medium) — The Pacific is the deepest ocean.\n", + "render_json": "{\n \"claims\": [\n {\n \"claim\": \"Water boils at 100 C at sea level.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"The Moon is made of cheese.\",\n \"language\": \"en\",\n \"verdict\": \"False\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"The Pacific is the deepest ocean.\",\n \"language\": \"en\",\n \"verdict\": \"Mostly True\",\n \"confidence\": \"medium\",\n \"verification_url\": null,\n \"rationale\": null,\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n }\n ],\n \"error\": null,\n \"error_code\": \"\",\n \"candidate_claims\": [],\n \"more_claims\": []\n}\n", + "repr": "AssessResponse(claims=[AssessClaim(claim='Water boils at 100 C at sea level.', language='en', verdict='True', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='The Moon is made of cheese.', language='en', verdict='False', confidence='high', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='The Pacific is the deepest ocean.', language='en', verdict='Mostly True', confidence='medium', verification_url=None, rationale=None, dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None)], error=None, error_code='', candidate_claims=[], more_claims=[])" +} diff --git a/tests/fixtures/parity/expected/assess__suggest_rewrite.json b/tests/fixtures/parity/expected/assess__suggest_rewrite.json new file mode 100644 index 0000000..e24cfab --- /dev/null +++ b/tests/fixtures/parity/expected/assess__suggest_rewrite.json @@ -0,0 +1,75 @@ +{ + "dump": { + "candidate_claims": [], + "claims": [ + { + "candidate_claims": [], + "claim": "Venus is the closest planet to the Sun.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": "Mercury, not Venus, is the closest planet to the Sun.", + "suggested_rewrite": "Mercury is the closest planet to the Sun.", + "verdict": "False", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Mercury is the closest planet to the Sun.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": "Mercury is the innermost planet.", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "error_code": "", + "more_claims": [] + }, + "dump_unset": { + "claims": [ + { + "candidate_claims": [], + "claim": "Venus is the closest planet to the Sun.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": "Mercury, not Venus, is the closest planet to the Sun.", + "suggested_rewrite": "Mercury is the closest planet to the Sun.", + "verdict": "False", + "verification_url": null + }, + { + "candidate_claims": [], + "claim": "Mercury is the closest planet to the Sun.", + "confidence": "high", + "dissent": null, + "error_code": null, + "hint": null, + "identified_claims": [], + "language": "en", + "rationale": "Mercury is the innermost planet.", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + } + ], + "error": null, + "more_claims": [] + }, + "render": "False (high) — Venus is the closest planet to the Sun.\n Mercury, not Venus, is the closest planet to the Sun.\nTrue (high) — Mercury is the closest planet to the Sun.\n Mercury is the innermost planet.\n", + "render_json": "{\n \"claims\": [\n {\n \"claim\": \"Venus is the closest planet to the Sun.\",\n \"language\": \"en\",\n \"verdict\": \"False\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": \"Mercury, not Venus, is the closest planet to the Sun.\",\n \"dissent\": null,\n \"suggested_rewrite\": \"Mercury is the closest planet to the Sun.\",\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n },\n {\n \"claim\": \"Mercury is the closest planet to the Sun.\",\n \"language\": \"en\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"verification_url\": null,\n \"rationale\": \"Mercury is the innermost planet.\",\n \"dissent\": null,\n \"suggested_rewrite\": null,\n \"error_code\": null,\n \"candidate_claims\": [],\n \"identified_claims\": [],\n \"hint\": null\n }\n ],\n \"error\": null,\n \"error_code\": \"\",\n \"candidate_claims\": [],\n \"more_claims\": []\n}\n", + "repr": "AssessResponse(claims=[AssessClaim(claim='Venus is the closest planet to the Sun.', language='en', verdict='False', confidence='high', verification_url=None, rationale='Mercury, not Venus, is the closest planet to the Sun.', dissent=None, suggested_rewrite='Mercury is the closest planet to the Sun.', error_code=None, candidate_claims=[], identified_claims=[], hint=None), AssessClaim(claim='Mercury is the closest planet to the Sun.', language='en', verdict='True', confidence='high', verification_url=None, rationale='Mercury is the innermost planet.', dissent=None, suggested_rewrite=None, error_code=None, candidate_claims=[], identified_claims=[], hint=None)], error=None, error_code='', candidate_claims=[], more_claims=[])" +} diff --git a/tests/fixtures/parity/expected/citecheck__402_no_credits.json b/tests/fixtures/parity/expected/citecheck__402_no_credits.json new file mode 100644 index 0000000..add7b94 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__402_no_credits.json @@ -0,0 +1,28 @@ +{ + "error": { + "cause": "No remaining credits for citation checks.", + "code": "no_credits", + "cost": 1, + "credit_balance": 100, + "doc_url": "https://lenz.io/docs/billing", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "friendly_text": "No remaining credits for citation checks.\n Fix: Top up or upgrade at https://lenz.io/plans, or wait for the period reset. See https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "message": "No remaining credits for citation checks.", + "payload_json": { + "error": { + "code": "no_credits", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "message": "No remaining credits for citation checks.", + "status": 402, + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } + }, + "remaining": 100, + "request_id": "", + "requested": null, + "resets_at": "2026-10-01T14:07:00+00:00", + "status_code": 402, + "type": "LenzQuotaExceededError", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_empty_body.json b/tests/fixtures/parity/expected/citecheck__422_empty_body.json new file mode 100644 index 0000000..26fe6bc --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_empty_body.json @@ -0,0 +1,30 @@ +{ + "error": { + "cause": "payload: Value error, send exactly one of text and pairs", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload" + ], + "msg": "Value error, send exactly one of text and pairs" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload: Value error, send exactly one of text and pairs\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload: Value error, send exactly one of text and pairs", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload: Value error, send exactly one of text and pairs", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_invalid_doi.json b/tests/fixtures/parity/expected/citecheck__422_invalid_doi.json new file mode 100644 index 0000000..3e13201 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_invalid_doi.json @@ -0,0 +1,33 @@ +{ + "error": { + "cause": "payload.pairs.0.doi: Send the DOI alone, like 10.1038/nature12373.", + "code": "invalid_doi", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0, + "doi" + ], + "msg": "Send the DOI alone, like 10.1038/nature12373." + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.pairs.0.doi: Send the DOI alone, like 10.1038/nature12373.\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.pairs.0.doi: Send the DOI alone, like 10.1038/nature12373.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.pairs.0.doi: Send the DOI alone, like 10.1038/nature12373.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_max_citations_over_20.json b/tests/fixtures/parity/expected/citecheck__422_max_citations_over_20.json new file mode 100644 index 0000000..aae4ebc --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_max_citations_over_20.json @@ -0,0 +1,31 @@ +{ + "error": { + "cause": "payload.max_citations: Input should be less than or equal to 20", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "max_citations" + ], + "msg": "Input should be less than or equal to 20" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.max_citations: Input should be less than or equal to 20\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.max_citations: Input should be less than or equal to 20", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.max_citations: Input should be less than or equal to 20", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_max_citations_with_pairs.json b/tests/fixtures/parity/expected/citecheck__422_max_citations_with_pairs.json new file mode 100644 index 0000000..f08b4c2 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_max_citations_with_pairs.json @@ -0,0 +1,30 @@ +{ + "error": { + "cause": "payload: Value error, max_citations goes with text: every pair is checked", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload" + ], + "msg": "Value error, max_citations goes with text: every pair is checked" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload: Value error, max_citations goes with text: every pair is checked\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload: Value error, max_citations goes with text: every pair is checked", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload: Value error, max_citations goes with text: every pair is checked", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_pair_bad_url_scheme.json b/tests/fixtures/parity/expected/citecheck__422_pair_bad_url_scheme.json new file mode 100644 index 0000000..76595fb --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_pair_bad_url_scheme.json @@ -0,0 +1,33 @@ +{ + "error": { + "cause": "payload.pairs.0.url: Value error, url: an http or https link", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0, + "url" + ], + "msg": "Value error, url: an http or https link" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.pairs.0.url: Value error, url: an http or https link\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.pairs.0.url: Value error, url: an http or https link", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.pairs.0.url: Value error, url: an http or https link", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_pair_no_source.json b/tests/fixtures/parity/expected/citecheck__422_pair_no_source.json new file mode 100644 index 0000000..f8ebec7 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_pair_no_source.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "payload.pairs.0: Value error, send exactly one of url and doi", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0 + ], + "msg": "Value error, send exactly one of url and doi" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.pairs.0: Value error, send exactly one of url and doi\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.pairs.0: Value error, send exactly one of url and doi", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.pairs.0: Value error, send exactly one of url and doi", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_pair_url_and_doi.json b/tests/fixtures/parity/expected/citecheck__422_pair_url_and_doi.json new file mode 100644 index 0000000..f8ebec7 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_pair_url_and_doi.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "payload.pairs.0: Value error, send exactly one of url and doi", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0 + ], + "msg": "Value error, send exactly one of url and doi" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.pairs.0: Value error, send exactly one of url and doi\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.pairs.0: Value error, send exactly one of url and doi", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.pairs.0: Value error, send exactly one of url and doi", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_pairs_empty.json b/tests/fixtures/parity/expected/citecheck__422_pairs_empty.json new file mode 100644 index 0000000..53538a0 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_pairs_empty.json @@ -0,0 +1,31 @@ +{ + "error": { + "cause": "payload.pairs: Value error, pairs: 1 to 20 items", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs" + ], + "msg": "Value error, pairs: 1 to 20 items" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.pairs: Value error, pairs: 1 to 20 items\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.pairs: Value error, pairs: 1 to 20 items", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.pairs: Value error, pairs: 1 to 20 items", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_pairs_over_20.json b/tests/fixtures/parity/expected/citecheck__422_pairs_over_20.json new file mode 100644 index 0000000..53538a0 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_pairs_over_20.json @@ -0,0 +1,31 @@ +{ + "error": { + "cause": "payload.pairs: Value error, pairs: 1 to 20 items", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs" + ], + "msg": "Value error, pairs: 1 to 20 items" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.pairs: Value error, pairs: 1 to 20 items\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.pairs: Value error, pairs: 1 to 20 items", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.pairs: Value error, pairs: 1 to 20 items", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_quote_not_in_statement.json b/tests/fixtures/parity/expected/citecheck__422_quote_not_in_statement.json new file mode 100644 index 0000000..96e097c --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_quote_not_in_statement.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "payload.pairs.0: Each quote must be words of its statement.", + "code": "quote_not_in_statement", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0 + ], + "msg": "Each quote must be words of its statement." + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.pairs.0: Each quote must be words of its statement.\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.pairs.0: Each quote must be words of its statement.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.pairs.0: Each quote must be words of its statement.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_text_and_pairs.json b/tests/fixtures/parity/expected/citecheck__422_text_and_pairs.json new file mode 100644 index 0000000..26fe6bc --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_text_and_pairs.json @@ -0,0 +1,30 @@ +{ + "error": { + "cause": "payload: Value error, send exactly one of text and pairs", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload" + ], + "msg": "Value error, send exactly one of text and pairs" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload: Value error, send exactly one of text and pairs\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload: Value error, send exactly one of text and pairs", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload: Value error, send exactly one of text and pairs", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_unknown_field.json b/tests/fixtures/parity/expected/citecheck__422_unknown_field.json new file mode 100644 index 0000000..bafff34 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_unknown_field.json @@ -0,0 +1,33 @@ +{ + "error": { + "cause": "payload.pairs.0.extra: Extra inputs are not permitted", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0, + "extra" + ], + "msg": "Extra inputs are not permitted" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.pairs.0.extra: Extra inputs are not permitted\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.pairs.0.extra: Extra inputs are not permitted", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.pairs.0.extra: Extra inputs are not permitted", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_url_input.json b/tests/fixtures/parity/expected/citecheck__422_url_input.json new file mode 100644 index 0000000..d5d08dc --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_url_input.json @@ -0,0 +1,30 @@ +{ + "error": { + "cause": "Send the page's text, with its links, to check the sources it cites.", + "code": "url_input", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "text" + ], + "msg": "Send the page's text, with its links, to check the sources it cites." + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Send the page's text, with its links, to check the sources it cites.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Send the page's text, with its links, to check the sources it cites.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Send the page's text, with its links, to check the sources it cites.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__422_webhook_secret_missing.json b/tests/fixtures/parity/expected/citecheck__422_webhook_secret_missing.json new file mode 100644 index 0000000..aa5a20c --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__422_webhook_secret_missing.json @@ -0,0 +1,30 @@ +{ + "error": { + "cause": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.", + "code": "webhook_secret_missing", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "webhook_url" + ], + "msg": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend." + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.\n Fix: Check the request body against the OpenAPI spec.", + "message": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__429_citecheck_in_flight.json b/tests/fixtures/parity/expected/citecheck__429_citecheck_in_flight.json new file mode 100644 index 0000000..45b31c1 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__429_citecheck_in_flight.json @@ -0,0 +1,25 @@ +{ + "error": { + "cause": "This account already has 3 citation checks running. Wait for one to finish.", + "code": "citecheck_in_flight", + "doc_url": "https://lenz.io/docs/rate-limits", + "fix": "Wait Retry-After seconds and retry.", + "friendly_text": "This account already has 3 citation checks running. Wait for one to finish.\n Fix: Wait Retry-After seconds and retry.", + "limit": null, + "message": "This account already has 3 citation checks running. Wait for one to finish.", + "payload_json": { + "error": { + "code": "rate_limited", + "fix": "Wait Retry-After seconds and retry.", + "message": "This account already has 3 citation checks running. Wait for one to finish.", + "status": 429 + } + }, + "request_id": "", + "reset_in_seconds": null, + "retry_after": 60, + "status_code": 429, + "type": "LenzRateLimitError", + "upgrade_url": "" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__503_capacity.json b/tests/fixtures/parity/expected/citecheck__503_capacity.json new file mode 100644 index 0000000..5384727 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__503_capacity.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "doc_url": "https://lenz.io/docs/errors#unavailable", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "status": 503 + } + }, + "request_id": "", + "retry_after": 90, + "status_code": 503, + "type": "LenzUpstreamUnavailableError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__503_citations_unavailable.json b/tests/fixtures/parity/expected/citecheck__503_citations_unavailable.json new file mode 100644 index 0000000..d3cc317 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__503_citations_unavailable.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Citation checking is switched off right now. Retry later; nothing was charged.", + "code": "citations_unavailable", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Citation checking is switched off right now. Retry later; nothing was charged.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Citation checking is switched off right now. Retry later; nothing was charged.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Citation checking is switched off right now. Retry later; nothing was charged.", + "status": 503 + } + }, + "request_id": "", + "retry_after": 300, + "status_code": 503, + "type": "LenzAPIError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__get_404_not_found.json b/tests/fixtures/parity/expected/citecheck__get_404_not_found.json new file mode 100644 index 0000000..b1353bd --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_404_not_found.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Citation check not found.", + "code": "not_found", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Citation check not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Citation check not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Citation check not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__get_404_review_id.json b/tests/fixtures/parity/expected/citecheck__get_404_review_id.json new file mode 100644 index 0000000..b1353bd --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_404_review_id.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Citation check not found.", + "code": "not_found", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Citation check not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Citation check not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Citation check not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__get_410_purged.json b/tests/fixtures/parity/expected/citecheck__get_410_purged.json new file mode 100644 index 0000000..6cf59a9 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_410_purged.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "This check is no longer available: its account removes content after a set period.", + "code": "purged", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Its account's retention period removed it. A certificate issued for it is still available.", + "friendly_text": "This check is no longer available: its account removes content after a set period.\n Fix: Its account's retention period removed it. A certificate issued for it is still available.", + "message": "This check is no longer available: its account removes content after a set period.", + "payload_json": { + "error": { + "code": "gone", + "fix": "Its account's retention period removed it. A certificate issued for it is still available.", + "message": "This check is no longer available: its account removes content after a set period.", + "status": 410 + } + }, + "purged_at": "2026-10-01T09:07:00.123456Z", + "request_id": "", + "status_code": 410, + "type": "LenzGoneError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__get_checking.json b/tests/fixtures/parity/expected/citecheck__get_checking.json new file mode 100644 index 0000000..2490a65 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_checking.json @@ -0,0 +1,196 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "pending", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "https://example.gov/report-2024", + "result": null, + "statement": "Unemployment fell to 4.1% in 2024." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "pending", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "https://example.org/statement", + "result": null, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": null, + "policy": { + "max_citations": 2 + }, + "poll_after_seconds": 10, + "status": "checking", + "summary": { + "citation_checks": { + "checked": 0, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "pending", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "https://example.gov/report-2024", + "result": null, + "statement": "Unemployment fell to 4.1% in 2024." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "pending", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "https://example.org/statement", + "result": null, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": null, + "policy": { + "max_citations": 2 + }, + "poll_after_seconds": 10, + "status": "checking", + "summary": { + "citation_checks": { + "checked": 0, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "exit_code": 2, + "render": "Citation check 8eb49302: checking — 0 credits charged\n\n2 sources cited in your draft\nLenz checks each one: does the source say what your draft says it does.\n", + "render_json": null, + "repr": "Citecheck(citecheck_id='8eb49302', status='checking', outcome=None, created_at='2026-10-01T09:07:00.123456Z', completed_at=None, poll_after_seconds=10, policy=CitecheckPolicy(max_citations=2), summary=CitecheckSummary(citations_found=2, citations_selected=2, citation_limit=2, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=0, unchecked=0, failed=0), citation_issues=0), credits=ReviewCredits(charged=0), citations=[ReviewCitation(index=0, reference='https://example.gov/report-2024', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024.', quotes=[], position=None, result=None, check=ReviewCitationCheck(status='pending', page_read=None, page_title=None, page_published_date=None, page_language=None, source_url=None, source_version=None, support=None, snippet=None, rationale=None, quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None)), ReviewCitation(index=1, reference='https://example.org/statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=None, result=None, check=ReviewCitationCheck(status='pending', page_read=None, page_title=None, page_published_date=None, page_language=None, source_url=None, source_version=None, support=None, snippet=None, rationale=None, quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))], citation_issues=[], citation_failures=[], more_citations=[], failure=None, language='en')" +} diff --git a/tests/fixtures/parity/expected/citecheck__get_completed_clean.json b/tests/fixtures/parity/expected/citecheck__get_completed_clean.json new file mode 100644 index 0000000..e1cfe30 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_completed_clean.json @@ -0,0 +1,212 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "https://example.gov/report-2024", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "https://example.org/statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "clean", + "policy": { + "max_citations": 2 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "https://example.gov/report-2024", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "https://example.org/statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "clean", + "policy": { + "max_citations": 2 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "exit_code": 0, + "render": "Citation check 8eb49302: clean — 2 credits charged\n\n2 sources cited in your draft\n2 checked.\n\nNo issues.\n", + "render_json": null, + "repr": "Citecheck(citecheck_id='8eb49302', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', poll_after_seconds=None, policy=CitecheckPolicy(max_citations=2), summary=CitecheckSummary(citations_found=2, citations_selected=2, citation_limit=2, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=2, unchecked=0, failed=0), citation_issues=0), credits=ReviewCredits(charged=2), citations=[ReviewCitation(index=0, reference='https://example.gov/report-2024', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024.', quotes=[], position=None, result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None)), ReviewCitation(index=1, reference='https://example.org/statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=None, result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.org/statement', page_published_date=None, page_language='en', source_url='https://example.org/statement', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))], citation_issues=[], citation_failures=[], more_citations=[], failure=None, language='en')" +} diff --git a/tests/fixtures/parity/expected/citecheck__get_completed_doi_pair.json b/tests/fixtures/parity/expected/citecheck__get_completed_doi_pair.json new file mode 100644 index 0000000..e793493 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_completed_doi_pair.json @@ -0,0 +1,142 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at None", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": null, + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://doi.org/10.1038/nature12373", + "doi": "10.1038/nature12373", + "index": 0, + "position": null, + "quotes": [], + "reference": "10.1038/nature12373", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Diamond sensors measure heat in cells." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "clean", + "policy": { + "max_citations": 1 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 1, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 1, + "citation_limit_reached": false, + "citations_found": 1, + "citations_selected": 1 + } + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at None", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": null, + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://doi.org/10.1038/nature12373", + "doi": "10.1038/nature12373", + "index": 0, + "position": null, + "quotes": [], + "reference": "10.1038/nature12373", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Diamond sensors measure heat in cells." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "clean", + "policy": { + "max_citations": 1 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 1, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 1, + "citation_limit_reached": false, + "citations_found": 1, + "citations_selected": 1 + } + }, + "exit_code": 0, + "render": "Citation check 8eb49302: clean — 1 credit charged\n\n1 source cited in your draft\n1 checked.\n\nNo issues.\n", + "render_json": null, + "repr": "Citecheck(citecheck_id='8eb49302', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', poll_after_seconds=None, policy=CitecheckPolicy(max_citations=1), summary=CitecheckSummary(citations_found=1, citations_selected=1, citation_limit=1, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=1, unchecked=0, failed=0), citation_issues=0), credits=ReviewCredits(charged=1), citations=[ReviewCitation(index=0, reference='10.1038/nature12373', cited_url='https://doi.org/10.1038/nature12373', doi='10.1038/nature12373', statement='Diamond sensors measure heat in cells.', quotes=[], position=None, result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at None', page_published_date=None, page_language='en', source_url=None, source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))], citation_issues=[], citation_failures=[], more_citations=[], failure=None, language='en')" +} diff --git a/tests/fixtures/parity/expected/citecheck__get_completed_incomplete.json b/tests/fixtures/parity/expected/citecheck__get_completed_incomplete.json new file mode 100644 index 0000000..9a2c57c --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_completed_incomplete.json @@ -0,0 +1,244 @@ +{ + "dump": { + "citation_failures": [ + { + "citation_index": 1, + "cited_url": "https://example.org/statement", + "doi": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#internal", + "failure_class": "internal", + "failure_reason": "internal", + "hint": "The check failed on our side. Try again later.", + "retryable": false + }, + "reference": "https://example.org/statement" + } + ], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "https://example.gov/report-2024", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024." + }, + { + "check": { + "doi_registered": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#internal", + "failure_class": "internal", + "failure_reason": "internal", + "hint": "The check failed on our side. Try again later.", + "retryable": false + }, + "hint": "The check failed on our side. Try again later.", + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "failed", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "https://example.org/statement", + "result": null, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "incomplete", + "policy": { + "max_citations": 2 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 1, + "failed": 1, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "dump_unset": { + "citation_failures": [ + { + "citation_index": 1, + "cited_url": "https://example.org/statement", + "doi": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#internal", + "failure_class": "internal", + "failure_reason": "internal", + "hint": "The check failed on our side. Try again later.", + "retryable": false + }, + "reference": "https://example.org/statement" + } + ], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "https://example.gov/report-2024", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024." + }, + { + "check": { + "doi_registered": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#internal", + "failure_class": "internal", + "failure_reason": "internal", + "hint": "The check failed on our side. Try again later.", + "retryable": false + }, + "hint": "The check failed on our side. Try again later.", + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "failed", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "https://example.org/statement", + "result": null, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "incomplete", + "policy": { + "max_citations": 2 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 1, + "failed": 1, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "exit_code": 2, + "render": "Citation check 8eb49302: incomplete — 1 credit charged\n\n2 sources cited in your draft\n1 checked. 1 could not be checked.\n\n[source 2/2] Could not be checked this time.\n https://example.org/statement\n The check failed on our side. Try again later.\n", + "render_json": null, + "repr": "Citecheck(citecheck_id='8eb49302', status='completed', outcome='incomplete', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', poll_after_seconds=None, policy=CitecheckPolicy(max_citations=2), summary=CitecheckSummary(citations_found=2, citations_selected=2, citation_limit=2, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=1, unchecked=0, failed=1), citation_issues=0), credits=ReviewCredits(charged=1), citations=[ReviewCitation(index=0, reference='https://example.gov/report-2024', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024.', quotes=[], position=None, result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None)), ReviewCitation(index=1, reference='https://example.org/statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=None, result=None, check=ReviewCitationCheck(status='failed', page_read=None, page_title=None, page_published_date=None, page_language=None, source_url=None, source_version=None, support=None, snippet=None, rationale=None, quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint='The check failed on our side. Try again later.', failure=FailureBlock(failure_reason='internal', failure_class='internal', retryable=False, hint='The check failed on our side. Try again later.', docs_url='https://lenz.io/docs/errors#internal')))], citation_issues=[], citation_failures=[ReviewCitationFailure(citation_index=1, reference='https://example.org/statement', cited_url='https://example.org/statement', doi=None, failure=FailureBlock(failure_reason='internal', failure_class='internal', retryable=False, hint='The check failed on our side. Try again later.', docs_url='https://lenz.io/docs/errors#internal'))], more_citations=[], failure=None, language='en')" +} diff --git a/tests/fixtures/parity/expected/citecheck__get_completed_issues_found.json b/tests/fixtures/parity/expected/citecheck__get_completed_issues_found.json new file mode 100644 index 0000000..2d22ac8 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_completed_issues_found.json @@ -0,0 +1,272 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [ + { + "citation_index": 0, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": null, + "finding": "contradicted", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "rationale": "The page states it.", + "reference": "a report from the ministry", + "snippet": "The source says so.", + "source": "support", + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + } + ], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "contradicted", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "contradicted", + "is_issue": true, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "issues_found", + "policy": { + "max_citations": 20 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 1, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [ + { + "citation_index": 0, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": null, + "finding": "contradicted", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "rationale": "The page states it.", + "reference": "a report from the ministry", + "snippet": "The source says so.", + "source": "support", + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + } + ], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "contradicted", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "contradicted", + "is_issue": true, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "issues_found", + "policy": { + "max_citations": 20 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 1, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "exit_code": 1, + "render": "Citation check 8eb49302: issues found — 2 credits charged\n\n2 sources cited in your draft\n2 checked, 1 with a problem.\n\n[source 1/2] Contradicted\n Unemployment fell to 4.1% in 2024, according to a report from the ministry.\n https://example.gov/report-2024\n The source says:\n “The source says so.”\n Reviewer's note: The page states it.\n\nA reviewer's note is reasoning, not a checked source; the quoted passage is from the page.\n", + "render_json": null, + "repr": "Citecheck(citecheck_id='8eb49302', status='completed', outcome='issues_found', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', poll_after_seconds=None, policy=CitecheckPolicy(max_citations=20), summary=CitecheckSummary(citations_found=2, citations_selected=2, citation_limit=20, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=2, unchecked=0, failed=0), citation_issues=1), credits=ReviewCredits(charged=2), citations=[ReviewCitation(index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), result=ReviewCitationResult(finding='contradicted', source='support', is_issue=True), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='contradicted', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None)), ReviewCitation(index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=Position(start=111, end=178, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.org/statement', page_published_date=None, page_language='en', source_url='https://example.org/statement', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))], citation_issues=[ReviewCitationIssue(citation_index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), finding='contradicted', source='support', snippet='The source says so.', rationale='The page states it.', missing_quote=None, metadata_differences=[], page_title='Page at https://example.gov/report-2024', failure=None)], citation_failures=[], more_citations=[], failure=None, language='en')" +} diff --git a/tests/fixtures/parity/expected/citecheck__get_completed_partly_supported.json b/tests/fixtures/parity/expected/citecheck__get_completed_partly_supported.json new file mode 100644 index 0000000..8077d22 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_completed_partly_supported.json @@ -0,0 +1,212 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "partly_supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "https://example.gov/report-2024", + "result": { + "finding": "partly_supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "https://example.org/statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "clean", + "policy": { + "max_citations": 2 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "partly_supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "https://example.gov/report-2024", + "result": { + "finding": "partly_supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "https://example.org/statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "clean", + "policy": { + "max_citations": 2 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "exit_code": 0, + "render": "Citation check 8eb49302: clean — 2 credits charged\n\n2 sources cited in your draft\n2 checked.\n\nNo issues.\n", + "render_json": null, + "repr": "Citecheck(citecheck_id='8eb49302', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', poll_after_seconds=None, policy=CitecheckPolicy(max_citations=2), summary=CitecheckSummary(citations_found=2, citations_selected=2, citation_limit=2, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=2, unchecked=0, failed=0), citation_issues=0), credits=ReviewCredits(charged=2), citations=[ReviewCitation(index=0, reference='https://example.gov/report-2024', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024.', quotes=[], position=None, result=ReviewCitationResult(finding='partly_supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='partly_supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None)), ReviewCitation(index=1, reference='https://example.org/statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=None, result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.org/statement', page_published_date=None, page_language='en', source_url='https://example.org/statement', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))], citation_issues=[], citation_failures=[], more_citations=[], failure=None, language='en')" +} diff --git a/tests/fixtures/parity/expected/citecheck__get_completed_unchecked.json b/tests/fixtures/parity/expected/citecheck__get_completed_unchecked.json new file mode 100644 index 0000000..b5c061f --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_completed_unchecked.json @@ -0,0 +1,212 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": null, + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "unchecked", + "unchecked_reason": "no_text" + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "https://example.gov/report-2024", + "result": { + "finding": "unchecked", + "is_issue": false, + "source": null + }, + "statement": "Unemployment fell to 4.1% in 2024." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": null, + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "unchecked", + "unchecked_reason": "no_text" + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "https://example.org/statement", + "result": { + "finding": "unchecked", + "is_issue": false, + "source": null + }, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "unchecked", + "policy": { + "max_citations": 2 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 0, + "failed": 0, + "unchecked": 2 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": null, + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "unchecked", + "unchecked_reason": "no_text" + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "https://example.gov/report-2024", + "result": { + "finding": "unchecked", + "is_issue": false, + "source": null + }, + "statement": "Unemployment fell to 4.1% in 2024." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": null, + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "unchecked", + "unchecked_reason": "no_text" + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "https://example.org/statement", + "result": { + "finding": "unchecked", + "is_issue": false, + "source": null + }, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "unchecked", + "policy": { + "max_citations": 2 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 0, + "failed": 0, + "unchecked": 2 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "exit_code": 2, + "render": "Citation check 8eb49302: unchecked — 0 credits charged\n\n2 sources cited in your draft\n2 could not be checked.\n\nCheck these by hand (Lenz could not check them)\n[source 1/2] The page gave no text to read.\n https://example.gov/report-2024\n[source 2/2] The page gave no text to read.\n https://example.org/statement\n\nNo issues.\n", + "render_json": null, + "repr": "Citecheck(citecheck_id='8eb49302', status='completed', outcome='unchecked', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', poll_after_seconds=None, policy=CitecheckPolicy(max_citations=2), summary=CitecheckSummary(citations_found=2, citations_selected=2, citation_limit=2, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=0, unchecked=2, failed=0), citation_issues=0), credits=ReviewCredits(charged=0), citations=[ReviewCitation(index=0, reference='https://example.gov/report-2024', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024.', quotes=[], position=None, result=ReviewCitationResult(finding='unchecked', source=None, is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='unchecked', snippet=None, rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason='no_text', hint=None, failure=None)), ReviewCitation(index=1, reference='https://example.org/statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=None, result=ReviewCitationResult(finding='unchecked', source=None, is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.org/statement', page_published_date=None, page_language='en', source_url='https://example.org/statement', source_version=None, support='unchecked', snippet=None, rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason='no_text', hint=None, failure=None))], citation_issues=[], citation_failures=[], more_citations=[], failure=None, language='en')" +} diff --git a/tests/fixtures/parity/expected/citecheck__get_failed_no_citations.json b/tests/fixtures/parity/expected/citecheck__get_failed_no_citations.json new file mode 100644 index 0000000..fbc25bf --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_failed_no_citations.json @@ -0,0 +1,74 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "failure_class": "invalid_input", + "failure_reason": "no_citations", + "hint": "The text has no citation to check: no link, DOI or numbered reference with one.", + "retryable": false + }, + "language": "en", + "more_citations": null, + "outcome": "unchecked", + "policy": { + "max_citations": 20 + }, + "poll_after_seconds": null, + "status": "failed", + "summary": { + "citation_checks": null, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null + } + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "failure_class": "invalid_input", + "failure_reason": "no_citations", + "hint": "The text has no citation to check: no link, DOI or numbered reference with one.", + "retryable": false + }, + "language": "en", + "more_citations": null, + "outcome": "unchecked", + "policy": { + "max_citations": 20 + }, + "poll_after_seconds": null, + "status": "failed", + "summary": { + "citation_checks": null, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null + } + }, + "exit_code": 2, + "render": "Citation check 8eb49302: unchecked — 0 credits charged\nFailed: The text has no citation to check: no link, DOI or numbered reference with one.\n", + "render_json": null, + "repr": "Citecheck(citecheck_id='8eb49302', status='failed', outcome='unchecked', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', poll_after_seconds=None, policy=CitecheckPolicy(max_citations=20), summary=CitecheckSummary(citations_found=None, citations_selected=None, citation_limit=20, citation_limit_reached=None, citation_checks=None, citation_issues=0), credits=ReviewCredits(charged=0), citations=[], citation_issues=[], citation_failures=[], more_citations=None, failure=FailureBlock(failure_reason='no_citations', failure_class='invalid_input', retryable=False, hint='The text has no citation to check: no link, DOI or numbered reference with one.', docs_url='https://lenz.io/docs/errors#invalid-input'), language='en')" +} diff --git a/tests/fixtures/parity/expected/citecheck__get_failed_upstream_unavailable.json b/tests/fixtures/parity/expected/citecheck__get_failed_upstream_unavailable.json new file mode 100644 index 0000000..8365eb9 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_failed_upstream_unavailable.json @@ -0,0 +1,286 @@ +{ + "dump": { + "citation_failures": [ + { + "citation_index": 0, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "Lenz could not reach this source just now. Try again later.", + "retryable": true + }, + "reference": "a report from the ministry" + }, + { + "citation_index": 1, + "cited_url": "https://example.org/statement", + "doi": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "Lenz could not reach this source just now. Try again later.", + "retryable": true + }, + "reference": "a statement" + } + ], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "Lenz could not reach this source just now. Try again later.", + "retryable": true + }, + "hint": "Lenz could not reach this source just now. Try again later.", + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "failed", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "a report from the ministry", + "result": null, + "statement": null + }, + { + "check": { + "doi_registered": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "Lenz could not reach this source just now. Try again later.", + "retryable": true + }, + "hint": "Lenz could not reach this source just now. Try again later.", + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "failed", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "a statement", + "result": null, + "statement": null + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": null, + "retryable": true + }, + "language": "en", + "more_citations": [], + "outcome": "unchecked", + "policy": { + "max_citations": 20 + }, + "poll_after_seconds": null, + "status": "failed", + "summary": { + "citation_checks": { + "checked": 0, + "failed": 2, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "dump_unset": { + "citation_failures": [ + { + "citation_index": 0, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "Lenz could not reach this source just now. Try again later.", + "retryable": true + }, + "reference": "a report from the ministry" + }, + { + "citation_index": 1, + "cited_url": "https://example.org/statement", + "doi": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "Lenz could not reach this source just now. Try again later.", + "retryable": true + }, + "reference": "a statement" + } + ], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "Lenz could not reach this source just now. Try again later.", + "retryable": true + }, + "hint": "Lenz could not reach this source just now. Try again later.", + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "failed", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "a report from the ministry", + "result": null, + "statement": null + }, + { + "check": { + "doi_registered": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "Lenz could not reach this source just now. Try again later.", + "retryable": true + }, + "hint": "Lenz could not reach this source just now. Try again later.", + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "failed", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "a statement", + "result": null, + "statement": null + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": null, + "retryable": true + }, + "language": "en", + "more_citations": [], + "outcome": "unchecked", + "policy": { + "max_citations": 20 + }, + "poll_after_seconds": null, + "status": "failed", + "summary": { + "citation_checks": { + "checked": 0, + "failed": 2, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "exit_code": 2, + "render": "Citation check 8eb49302: unchecked — 0 credits charged\nFailed: upstream_unavailable\n\n2 sources cited in your draft\n2 could not be checked.\n\n[source 1/2] Could not be checked this time.\n https://example.gov/report-2024\n Lenz could not reach this source just now. Try again later.\n\n[source 2/2] Could not be checked this time.\n https://example.org/statement\n Lenz could not reach this source just now. Try again later.\n", + "render_json": null, + "repr": "Citecheck(citecheck_id='8eb49302', status='failed', outcome='unchecked', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', poll_after_seconds=None, policy=CitecheckPolicy(max_citations=20), summary=CitecheckSummary(citations_found=2, citations_selected=2, citation_limit=20, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=0, unchecked=0, failed=2), citation_issues=0), credits=ReviewCredits(charged=0), citations=[ReviewCitation(index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement=None, quotes=[], position=None, result=None, check=ReviewCitationCheck(status='failed', page_read=None, page_title=None, page_published_date=None, page_language=None, source_url=None, source_version=None, support=None, snippet=None, rationale=None, quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint='Lenz could not reach this source just now. Try again later.', failure=FailureBlock(failure_reason='upstream_unavailable', failure_class='upstream_unavailable', retryable=True, hint='Lenz could not reach this source just now. Try again later.', docs_url='https://lenz.io/docs/errors#upstream-unavailable'))), ReviewCitation(index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, statement=None, quotes=[], position=None, result=None, check=ReviewCitationCheck(status='failed', page_read=None, page_title=None, page_published_date=None, page_language=None, source_url=None, source_version=None, support=None, snippet=None, rationale=None, quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint='Lenz could not reach this source just now. Try again later.', failure=FailureBlock(failure_reason='upstream_unavailable', failure_class='upstream_unavailable', retryable=True, hint='Lenz could not reach this source just now. Try again later.', docs_url='https://lenz.io/docs/errors#upstream-unavailable')))], citation_issues=[], citation_failures=[ReviewCitationFailure(citation_index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, failure=FailureBlock(failure_reason='upstream_unavailable', failure_class='upstream_unavailable', retryable=True, hint='Lenz could not reach this source just now. Try again later.', docs_url='https://lenz.io/docs/errors#upstream-unavailable')), ReviewCitationFailure(citation_index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, failure=FailureBlock(failure_reason='upstream_unavailable', failure_class='upstream_unavailable', retryable=True, hint='Lenz could not reach this source just now. Try again later.', docs_url='https://lenz.io/docs/errors#upstream-unavailable'))], more_citations=[], failure=FailureBlock(failure_reason='upstream_unavailable', failure_class='upstream_unavailable', retryable=True, hint=None, docs_url='https://lenz.io/docs/errors#upstream-unavailable'), language='en')" +} diff --git a/tests/fixtures/parity/expected/citecheck__get_queued.json b/tests/fixtures/parity/expected/citecheck__get_queued.json new file mode 100644 index 0000000..b74baa6 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_queued.json @@ -0,0 +1,134 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "pending", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "https://example.gov/report-2024", + "result": null, + "statement": "Unemployment fell to 4.1% in 2024." + } + ], + "citecheck_id": "8eb49302", + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": null, + "policy": { + "max_citations": 1 + }, + "poll_after_seconds": 10, + "status": "queued", + "summary": { + "citation_checks": { + "checked": 0, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 1, + "citation_limit_reached": false, + "citations_found": 1, + "citations_selected": 1 + } + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "pending", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "https://example.gov/report-2024", + "result": null, + "statement": "Unemployment fell to 4.1% in 2024." + } + ], + "citecheck_id": "8eb49302", + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": null, + "policy": { + "max_citations": 1 + }, + "poll_after_seconds": 10, + "status": "queued", + "summary": { + "citation_checks": { + "checked": 0, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 1, + "citation_limit_reached": false, + "citations_found": 1, + "citations_selected": 1 + } + }, + "exit_code": 2, + "render": "Citation check 8eb49302: queued — 0 credits charged\n\n1 source cited in your draft\nLenz checks each one: does the source say what your draft says it does.\n", + "render_json": null, + "repr": "Citecheck(citecheck_id='8eb49302', status='queued', outcome=None, created_at='2026-10-01T09:07:00.123456Z', completed_at=None, poll_after_seconds=10, policy=CitecheckPolicy(max_citations=1), summary=CitecheckSummary(citations_found=1, citations_selected=1, citation_limit=1, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=0, unchecked=0, failed=0), citation_issues=0), credits=ReviewCredits(charged=0), citations=[ReviewCitation(index=0, reference='https://example.gov/report-2024', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024.', quotes=[], position=None, result=None, check=ReviewCitationCheck(status='pending', page_read=None, page_title=None, page_published_date=None, page_language=None, source_url=None, source_version=None, support=None, snippet=None, rationale=None, quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))], citation_issues=[], citation_failures=[], more_citations=[], failure=None, language='en')" +} diff --git a/tests/fixtures/parity/expected/citecheck__get_text_limit_exactly_at_limit.json b/tests/fixtures/parity/expected/citecheck__get_text_limit_exactly_at_limit.json new file mode 100644 index 0000000..f3818cf --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_text_limit_exactly_at_limit.json @@ -0,0 +1,228 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "clean", + "policy": { + "max_citations": 2 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "clean", + "policy": { + "max_citations": 2 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "exit_code": 0, + "render": "Citation check 8eb49302: clean — 2 credits charged\n\n2 sources cited in your draft\n2 checked.\n\nNo issues.\n", + "render_json": null, + "repr": "Citecheck(citecheck_id='8eb49302', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', poll_after_seconds=None, policy=CitecheckPolicy(max_citations=2), summary=CitecheckSummary(citations_found=2, citations_selected=2, citation_limit=2, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=2, unchecked=0, failed=0), citation_issues=0), credits=ReviewCredits(charged=2), citations=[ReviewCitation(index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None)), ReviewCitation(index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=Position(start=111, end=178, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.org/statement', page_published_date=None, page_language='en', source_url='https://example.org/statement', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))], citation_issues=[], citation_failures=[], more_citations=[], failure=None, language='en')" +} diff --git a/tests/fixtures/parity/expected/citecheck__get_text_limit_reached.json b/tests/fixtures/parity/expected/citecheck__get_text_limit_reached.json new file mode 100644 index 0000000..bd075a8 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__get_text_limit_reached.json @@ -0,0 +1,176 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "language": "en", + "more_citations": [ + { + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "reference": "a statement", + "sentence": "The agency said so in a statement." + } + ], + "outcome": "clean", + "policy": { + "max_citations": 1 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 1, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 1, + "citation_limit_reached": true, + "citations_found": 2, + "citations_selected": 1 + } + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "language": "en", + "more_citations": [ + { + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "reference": "a statement", + "sentence": "The agency said so in a statement." + } + ], + "outcome": "clean", + "policy": { + "max_citations": 1 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 1, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 1, + "citation_limit_reached": true, + "citations_found": 2, + "citations_selected": 1 + } + }, + "exit_code": 0, + "render": "Citation check 8eb49302: clean — 1 credit charged\n\n2 sources cited in your draft\n1 checked.\n1 more was not checked: one check covers 1.\n\nNo issues.\n\n1 more citation was found but not checked.\n", + "render_json": null, + "repr": "Citecheck(citecheck_id='8eb49302', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', poll_after_seconds=None, policy=CitecheckPolicy(max_citations=1), summary=CitecheckSummary(citations_found=2, citations_selected=1, citation_limit=1, citation_limit_reached=True, citation_checks=ReviewCitationCheckCounts(checked=1, unchecked=0, failed=0), citation_issues=0), credits=ReviewCredits(charged=1), citations=[ReviewCitation(index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))], citation_issues=[], citation_failures=[], more_citations=[ReviewMoreCitation(index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, sentence='The agency said so in a statement.', position=Position(start=111, end=178, text=None))], failure=None, language='en')" +} diff --git a/tests/fixtures/parity/expected/citecheck__idempotency_body_mismatch_422.json b/tests/fixtures/parity/expected/citecheck__idempotency_body_mismatch_422.json new file mode 100644 index 0000000..5de20e3 --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__idempotency_body_mismatch_422.json @@ -0,0 +1,29 @@ +{ + "error": { + "cause": "Idempotency-Key reused with a different request body.", + "code": "idempotency_body_mismatch", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "header" + ], + "msg": "Idempotency-Key reused with a different request body." + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Idempotency-Key reused with a different request body.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Idempotency-Key reused with a different request body.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Idempotency-Key reused with a different request body.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__idempotency_conflict_409.json b/tests/fixtures/parity/expected/citecheck__idempotency_conflict_409.json new file mode 100644 index 0000000..f674e5f --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__idempotency_conflict_409.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "A check with this Idempotency-Key is still being created. Retry shortly.", + "code": "idempotency_conflict", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "A check with this Idempotency-Key is still being created. Retry shortly.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "A check with this Idempotency-Key is still being created. Retry shortly.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "A check with this Idempotency-Key is still being created. Retry shortly.", + "status": 409 + } + }, + "request_id": "", + "status_code": 409, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/citecheck__idempotent_replay_202.json b/tests/fixtures/parity/expected/citecheck__idempotent_replay_202.json new file mode 100644 index 0000000..a0700ca --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__idempotent_replay_202.json @@ -0,0 +1,12 @@ +{ + "dump": { + "citecheck_id": "8eb49302", + "status": "queued" + }, + "dump_unset": { + "citecheck_id": "8eb49302", + "status": "queued" + }, + "render_json": null, + "repr": "CitecheckStarted(citecheck_id='8eb49302', status='queued')" +} diff --git a/tests/fixtures/parity/expected/citecheck__receipt_202.json b/tests/fixtures/parity/expected/citecheck__receipt_202.json new file mode 100644 index 0000000..a0700ca --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__receipt_202.json @@ -0,0 +1,12 @@ +{ + "dump": { + "citecheck_id": "8eb49302", + "status": "queued" + }, + "dump_unset": { + "citecheck_id": "8eb49302", + "status": "queued" + }, + "render_json": null, + "repr": "CitecheckStarted(citecheck_id='8eb49302', status='queued')" +} diff --git a/tests/fixtures/parity/expected/citecheck__receipt_202_empty_webhook_url.json b/tests/fixtures/parity/expected/citecheck__receipt_202_empty_webhook_url.json new file mode 100644 index 0000000..a0700ca --- /dev/null +++ b/tests/fixtures/parity/expected/citecheck__receipt_202_empty_webhook_url.json @@ -0,0 +1,12 @@ +{ + "dump": { + "citecheck_id": "8eb49302", + "status": "queued" + }, + "dump_unset": { + "citecheck_id": "8eb49302", + "status": "queued" + }, + "render_json": null, + "repr": "CitecheckStarted(citecheck_id='8eb49302', status='queued')" +} diff --git a/tests/fixtures/parity/expected/errors__ask_bad_language.json b/tests/fixtures/parity/expected/errors__ask_bad_language.json new file mode 100644 index 0000000..81b1bdf --- /dev/null +++ b/tests/fixtures/parity/expected/errors__ask_bad_language.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Unsupported language 'xx-nope'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Unsupported language 'xx-nope'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Unsupported language 'xx-nope'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Unsupported language 'xx-nope'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/errors__ask_empty_message.json b/tests/fixtures/parity/expected/errors__ask_empty_message.json new file mode 100644 index 0000000..817db2b --- /dev/null +++ b/tests/fixtures/parity/expected/errors__ask_empty_message.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Message cannot be empty.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Message cannot be empty.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Message cannot be empty.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Message cannot be empty.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/errors__ask_failed.json b/tests/fixtures/parity/expected/errors__ask_failed.json new file mode 100644 index 0000000..4aa0601 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__ask_failed.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "The chat model could not answer this question.", + "code": "ask_failed", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "The chat model could not answer this question.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "The chat model could not answer this question.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "The chat model could not answer this question.", + "status": 502 + } + }, + "request_id": "", + "retry_after": null, + "status_code": 502, + "type": "LenzAPIError" + } +} diff --git a/tests/fixtures/parity/expected/errors__ask_idempotency_key_reused.json b/tests/fixtures/parity/expected/errors__ask_idempotency_key_reused.json new file mode 100644 index 0000000..989af48 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__ask_idempotency_key_reused.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Idempotency-Key reused with a different request body.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Idempotency-Key reused with a different request body.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Idempotency-Key reused with a different request body.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Idempotency-Key reused with a different request body.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/errors__ask_message_too_long.json b/tests/fixtures/parity/expected/errors__ask_message_too_long.json new file mode 100644 index 0000000..8345a29 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__ask_message_too_long.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Message too long (max 500 characters).", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Message too long (max 500 characters).\n Fix: Check the request body against the OpenAPI spec.", + "message": "Message too long (max 500 characters).", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Message too long (max 500 characters).", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/errors__ask_not_completed.json b/tests/fixtures/parity/expected/errors__ask_not_completed.json new file mode 100644 index 0000000..cfdc7c3 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__ask_not_completed.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Ask is only available for completed verifications.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Ask is only available for completed verifications.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Ask is only available for completed verifications.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Ask is only available for completed verifications.", + "status": 400 + } + }, + "request_id": "", + "status_code": 400, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__ask_reset_not_found.json b/tests/fixtures/parity/expected/errors__ask_reset_not_found.json new file mode 100644 index 0000000..956264c --- /dev/null +++ b/tests/fixtures/parity/expected/errors__ask_reset_not_found.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Verification not found.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Verification not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Verification not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Verification not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__ask_send_not_found.json b/tests/fixtures/parity/expected/errors__ask_send_not_found.json new file mode 100644 index 0000000..956264c --- /dev/null +++ b/tests/fixtures/parity/expected/errors__ask_send_not_found.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Verification not found.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Verification not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Verification not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Verification not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__auth_bad_key.json b/tests/fixtures/parity/expected/errors__auth_bad_key.json new file mode 100644 index 0000000..e57982a --- /dev/null +++ b/tests/fixtures/parity/expected/errors__auth_bad_key.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Unauthorized", + "code": "", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "Unauthorized\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__auth_bad_oauth_token.json b/tests/fixtures/parity/expected/errors__auth_bad_oauth_token.json new file mode 100644 index 0000000..5186317 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__auth_bad_oauth_token.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "The access token is invalid, expired or revoked.", + "code": "invalid_token", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "The access token is invalid, expired or revoked.\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "The access token is invalid, expired or revoked.", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "The access token is invalid, expired or revoked.", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__auth_basic_scheme.json b/tests/fixtures/parity/expected/errors__auth_basic_scheme.json new file mode 100644 index 0000000..e57982a --- /dev/null +++ b/tests/fixtures/parity/expected/errors__auth_basic_scheme.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Unauthorized", + "code": "", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "Unauthorized\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__auth_expired_oauth_token.json b/tests/fixtures/parity/expected/errors__auth_expired_oauth_token.json new file mode 100644 index 0000000..5186317 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__auth_expired_oauth_token.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "The access token is invalid, expired or revoked.", + "code": "invalid_token", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "The access token is invalid, expired or revoked.\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "The access token is invalid, expired or revoked.", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "The access token is invalid, expired or revoked.", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__auth_insufficient_scope.json b/tests/fixtures/parity/expected/errors__auth_insufficient_scope.json new file mode 100644 index 0000000..567f3ae --- /dev/null +++ b/tests/fixtures/parity/expected/errors__auth_insufficient_scope.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "The access token does not allow this call.", + "code": "insufficient_scope", + "doc_url": "https://lenz.io/docs/auth", + "fix": "This key doesn't have access to that resource.", + "friendly_text": "The access token does not allow this call.\n Fix: This key doesn't have access to that resource.", + "message": "The access token does not allow this call.", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "This key doesn't have access to that resource.", + "message": "The access token does not allow this call.", + "status": 403 + } + }, + "request_id": "", + "status_code": 403, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__auth_missing_bearer.json b/tests/fixtures/parity/expected/errors__auth_missing_bearer.json new file mode 100644 index 0000000..e57982a --- /dev/null +++ b/tests/fixtures/parity/expected/errors__auth_missing_bearer.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Unauthorized", + "code": "", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "Unauthorized\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__auth_missing_bearer_post.json b/tests/fixtures/parity/expected/errors__auth_missing_bearer_post.json new file mode 100644 index 0000000..e57982a --- /dev/null +++ b/tests/fixtures/parity/expected/errors__auth_missing_bearer_post.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Unauthorized", + "code": "", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "Unauthorized\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__auth_oauth_issuer_off.json b/tests/fixtures/parity/expected/errors__auth_oauth_issuer_off.json new file mode 100644 index 0000000..e57982a --- /dev/null +++ b/tests/fixtures/parity/expected/errors__auth_oauth_issuer_off.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Unauthorized", + "code": "", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "Unauthorized\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__auth_oauth_only.json b/tests/fixtures/parity/expected/errors__auth_oauth_only.json new file mode 100644 index 0000000..99f0634 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__auth_oauth_only.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "An API key's webhook secret is managed on the API credentials page (https://lenz.io/api-credentials). This endpoint is for OAuth connections.", + "code": "oauth_only", + "doc_url": "https://lenz.io/docs/auth", + "fix": "This key doesn't have access to that resource.", + "friendly_text": "An API key's webhook secret is managed on the API credentials page (https://lenz.io/api-credentials). This endpoint is for OAuth connections.\n Fix: This key doesn't have access to that resource.", + "message": "An API key's webhook secret is managed on the API credentials page (https://lenz.io/api-credentials). This endpoint is for OAuth connections.", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "This key doesn't have access to that resource.", + "message": "An API key's webhook secret is managed on the API credentials page (https://lenz.io/api-credentials). This endpoint is for OAuth connections.", + "status": 403 + } + }, + "request_id": "", + "status_code": 403, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__auth_private_claim_ask_history.json b/tests/fixtures/parity/expected/errors__auth_private_claim_ask_history.json new file mode 100644 index 0000000..a29a3fb --- /dev/null +++ b/tests/fixtures/parity/expected/errors__auth_private_claim_ask_history.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "This report is private.", + "code": "private_claim", + "doc_url": "https://lenz.io/docs/auth", + "fix": "This key doesn't have access to that resource.", + "friendly_text": "This report is private.\n Fix: This key doesn't have access to that resource.", + "message": "This report is private.", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "This key doesn't have access to that resource.", + "message": "This report is private.", + "status": 403 + } + }, + "request_id": "", + "status_code": 403, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__auth_private_claim_ask_send.json b/tests/fixtures/parity/expected/errors__auth_private_claim_ask_send.json new file mode 100644 index 0000000..a29a3fb --- /dev/null +++ b/tests/fixtures/parity/expected/errors__auth_private_claim_ask_send.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "This report is private.", + "code": "private_claim", + "doc_url": "https://lenz.io/docs/auth", + "fix": "This key doesn't have access to that resource.", + "friendly_text": "This report is private.\n Fix: This key doesn't have access to that resource.", + "message": "This report is private.", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "This key doesn't have access to that resource.", + "message": "This report is private.", + "status": 403 + } + }, + "request_id": "", + "status_code": 403, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__auth_unrecognised_prefix.json b/tests/fixtures/parity/expected/errors__auth_unrecognised_prefix.json new file mode 100644 index 0000000..e57982a --- /dev/null +++ b/tests/fixtures/parity/expected/errors__auth_unrecognised_prefix.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Unauthorized", + "code": "", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "Unauthorized\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__http_error_library_bad_curated.json b/tests/fixtures/parity/expected/errors__http_error_library_bad_curated.json new file mode 100644 index 0000000..9eb06ac --- /dev/null +++ b/tests/fixtures/parity/expected/errors__http_error_library_bad_curated.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Invalid curated list(s). Allowed: trivia", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Invalid curated list(s). Allowed: trivia\n Fix: Check the request body against the OpenAPI spec.", + "message": "Invalid curated list(s). Allowed: trivia", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Invalid curated list(s). Allowed: trivia", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/errors__http_error_library_bad_verdict.json b/tests/fixtures/parity/expected/errors__http_error_library_bad_verdict.json new file mode 100644 index 0000000..2dce420 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__http_error_library_bad_verdict.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Invalid verdict label(s). Allowed: False, Mostly False, Mixed, Mostly True, True", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Invalid verdict label(s). Allowed: False, Mostly False, Mixed, Mostly True, True\n Fix: Check the request body against the OpenAPI spec.", + "message": "Invalid verdict label(s). Allowed: False, Mostly False, Mixed, Mostly True, True", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Invalid verdict label(s). Allowed: False, Mostly False, Mixed, Mostly True, True", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/errors__method_not_allowed_get_verify.json b/tests/fixtures/parity/expected/errors__method_not_allowed_get_verify.json new file mode 100644 index 0000000..ebe2cee --- /dev/null +++ b/tests/fixtures/parity/expected/errors__method_not_allowed_get_verify.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "HTTP 405", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "HTTP 405\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 405", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 405", + "status": 405 + } + }, + "request_id": "", + "status_code": 405, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__method_not_allowed_post_library.json b/tests/fixtures/parity/expected/errors__method_not_allowed_post_library.json new file mode 100644 index 0000000..ebe2cee --- /dev/null +++ b/tests/fixtures/parity/expected/errors__method_not_allowed_post_library.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "HTTP 405", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "HTTP 405\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 405", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 405", + "status": 405 + } + }, + "request_id": "", + "status_code": 405, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__not_found_ask.json b/tests/fixtures/parity/expected/errors__not_found_ask.json new file mode 100644 index 0000000..956264c --- /dev/null +++ b/tests/fixtures/parity/expected/errors__not_found_ask.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Verification not found.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Verification not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Verification not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Verification not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__not_found_route.json b/tests/fixtures/parity/expected/errors__not_found_route.json new file mode 100644 index 0000000..8c9406d --- /dev/null +++ b/tests/fixtures/parity/expected/errors__not_found_route.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "HTTP 404", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "HTTP 404\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 404", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 404", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__not_found_verification.json b/tests/fixtures/parity/expected/errors__not_found_verification.json new file mode 100644 index 0000000..41573fe --- /dev/null +++ b/tests/fixtures/parity/expected/errors__not_found_verification.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Not found.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__not_found_verify_status.json b/tests/fixtures/parity/expected/errors__not_found_verify_status.json new file mode 100644 index 0000000..68a468c --- /dev/null +++ b/tests/fixtures/parity/expected/errors__not_found_verify_status.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Task not found.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Task not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Task not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Task not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__oauth_register_disabled.json b/tests/fixtures/parity/expected/errors__oauth_register_disabled.json new file mode 100644 index 0000000..8c9406d --- /dev/null +++ b/tests/fixtures/parity/expected/errors__oauth_register_disabled.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "HTTP 404", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "HTTP 404\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 404", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 404", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__oauth_register_invalid_client_metadata.json b/tests/fixtures/parity/expected/errors__oauth_register_invalid_client_metadata.json new file mode 100644 index 0000000..3ae0fc8 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__oauth_register_invalid_client_metadata.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "HTTP 400", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "HTTP 400\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 400", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 400", + "status": 400 + } + }, + "request_id": "", + "status_code": 400, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__oauth_register_invalid_redirect_uri.json b/tests/fixtures/parity/expected/errors__oauth_register_invalid_redirect_uri.json new file mode 100644 index 0000000..3ae0fc8 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__oauth_register_invalid_redirect_uri.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "HTTP 400", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "HTTP 400\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 400", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 400", + "status": 400 + } + }, + "request_id": "", + "status_code": 400, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__oauth_revoke_invalid_client.json b/tests/fixtures/parity/expected/errors__oauth_revoke_invalid_client.json new file mode 100644 index 0000000..e57982a --- /dev/null +++ b/tests/fixtures/parity/expected/errors__oauth_revoke_invalid_client.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Unauthorized", + "code": "", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "Unauthorized\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__oauth_token_invalid_client.json b/tests/fixtures/parity/expected/errors__oauth_token_invalid_client.json new file mode 100644 index 0000000..e57982a --- /dev/null +++ b/tests/fixtures/parity/expected/errors__oauth_token_invalid_client.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Unauthorized", + "code": "", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "Unauthorized\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__oauth_token_invalid_grant.json b/tests/fixtures/parity/expected/errors__oauth_token_invalid_grant.json new file mode 100644 index 0000000..3ae0fc8 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__oauth_token_invalid_grant.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "HTTP 400", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "HTTP 400\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 400", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 400", + "status": 400 + } + }, + "request_id": "", + "status_code": 400, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__oauth_token_missing_grant_type.json b/tests/fixtures/parity/expected/errors__oauth_token_missing_grant_type.json new file mode 100644 index 0000000..3ae0fc8 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__oauth_token_missing_grant_type.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "HTTP 400", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "HTTP 400\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 400", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 400", + "status": 400 + } + }, + "request_id": "", + "status_code": 400, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__oauth_token_refresh_invalid_grant.json b/tests/fixtures/parity/expected/errors__oauth_token_refresh_invalid_grant.json new file mode 100644 index 0000000..3ae0fc8 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__oauth_token_refresh_invalid_grant.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "HTTP 400", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "HTTP 400\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 400", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 400", + "status": 400 + } + }, + "request_id": "", + "status_code": 400, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__oauth_token_unsupported_grant_type.json b/tests/fixtures/parity/expected/errors__oauth_token_unsupported_grant_type.json new file mode 100644 index 0000000..3ae0fc8 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__oauth_token_unsupported_grant_type.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "HTTP 400", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "HTTP 400\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 400", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 400", + "status": 400 + } + }, + "request_id": "", + "status_code": 400, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__payment_required_ask.json b/tests/fixtures/parity/expected/errors__payment_required_ask.json new file mode 100644 index 0000000..a635323 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__payment_required_ask.json @@ -0,0 +1,28 @@ +{ + "error": { + "cause": "No remaining ask credits.", + "code": "no_credits", + "cost": 1, + "credit_balance": 0, + "doc_url": "https://lenz.io/docs/billing", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "friendly_text": "No remaining ask credits.\n Fix: Top up or upgrade at https://lenz.io/plans, or wait for the period reset. See https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "message": "No remaining ask credits.", + "payload_json": { + "error": { + "code": "no_credits", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "message": "No remaining ask credits.", + "status": 402, + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } + }, + "remaining": 0, + "request_id": "", + "requested": null, + "resets_at": "2026-10-01T14:07:00+00:00", + "status_code": 402, + "type": "LenzQuotaExceededError", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } +} diff --git a/tests/fixtures/parity/expected/errors__payment_required_assess.json b/tests/fixtures/parity/expected/errors__payment_required_assess.json new file mode 100644 index 0000000..91af7cd --- /dev/null +++ b/tests/fixtures/parity/expected/errors__payment_required_assess.json @@ -0,0 +1,28 @@ +{ + "error": { + "cause": "No remaining /assess units.", + "code": "no_credits", + "cost": 1, + "credit_balance": 0, + "doc_url": "https://lenz.io/docs/billing", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "friendly_text": "No remaining /assess units.\n Fix: Top up or upgrade at https://lenz.io/plans, or wait for the period reset. See https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "message": "No remaining /assess units.", + "payload_json": { + "error": { + "code": "no_credits", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "message": "No remaining /assess units.", + "status": 402, + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } + }, + "remaining": 0, + "request_id": "", + "requested": null, + "resets_at": "2026-10-01T14:07:00+00:00", + "status_code": 402, + "type": "LenzQuotaExceededError", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } +} diff --git a/tests/fixtures/parity/expected/errors__payment_required_verify.json b/tests/fixtures/parity/expected/errors__payment_required_verify.json new file mode 100644 index 0000000..f16364a --- /dev/null +++ b/tests/fixtures/parity/expected/errors__payment_required_verify.json @@ -0,0 +1,28 @@ +{ + "error": { + "cause": "No remaining claim checks.", + "code": "no_credits", + "cost": 10, + "credit_balance": 0, + "doc_url": "https://lenz.io/docs/billing", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "friendly_text": "No remaining claim checks.\n Fix: Top up or upgrade at https://lenz.io/plans, or wait for the period reset. See https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "message": "No remaining claim checks.", + "payload_json": { + "error": { + "code": "no_credits", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "message": "No remaining claim checks.", + "status": 402, + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } + }, + "remaining": 0, + "request_id": "", + "requested": null, + "resets_at": "2026-10-01T14:07:00+00:00", + "status_code": 402, + "type": "LenzQuotaExceededError", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } +} diff --git a/tests/fixtures/parity/expected/errors__payment_required_verify_batch_short.json b/tests/fixtures/parity/expected/errors__payment_required_verify_batch_short.json new file mode 100644 index 0000000..21c7df3 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__payment_required_verify_batch_short.json @@ -0,0 +1,28 @@ +{ + "error": { + "cause": "Insufficient credits for batch.", + "code": "no_credits", + "cost": 50, + "credit_balance": 30, + "doc_url": "https://lenz.io/docs/billing", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "friendly_text": "Insufficient credits for batch.\n Fix: Top up or upgrade at https://lenz.io/plans, or wait for the period reset. See https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "message": "Insufficient credits for batch.", + "payload_json": { + "error": { + "code": "no_credits", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "message": "Insufficient credits for batch.", + "status": 402, + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } + }, + "remaining": 3, + "request_id": "", + "requested": 5, + "resets_at": "2026-10-01T14:07:00+00:00", + "status_code": 402, + "type": "LenzQuotaExceededError", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } +} diff --git a/tests/fixtures/parity/expected/errors__rate_limited_extract.json b/tests/fixtures/parity/expected/errors__rate_limited_extract.json new file mode 100644 index 0000000..336a59b --- /dev/null +++ b/tests/fixtures/parity/expected/errors__rate_limited_extract.json @@ -0,0 +1,25 @@ +{ + "error": { + "cause": "Daily /extract limit of 1000 reached for this account. The allowance is shared by every key on the account and by extractions run from the Lenz website.", + "code": "extract_daily_limit", + "doc_url": "https://lenz.io/docs/rate-limits", + "fix": "Wait Retry-After seconds and retry.", + "friendly_text": "Daily /extract limit of 1000 reached for this account. The allowance is shared by every key on the account and by extractions run from the Lenz website.\n Fix: Wait Retry-After seconds and retry.", + "limit": 1000, + "message": "Daily /extract limit of 1000 reached for this account. The allowance is shared by every key on the account and by extractions run from the Lenz website.", + "payload_json": { + "error": { + "code": "rate_limited", + "fix": "Wait Retry-After seconds and retry.", + "message": "Daily /extract limit of 1000 reached for this account. The allowance is shared by every key on the account and by extractions run from the Lenz website.", + "status": 429 + } + }, + "request_id": "", + "reset_in_seconds": 900, + "retry_after": 900, + "status_code": 429, + "type": "LenzRateLimitError", + "upgrade_url": "https://lenz.io/plans" + } +} diff --git a/tests/fixtures/parity/expected/errors__service_unavailable_ask.json b/tests/fixtures/parity/expected/errors__service_unavailable_ask.json new file mode 100644 index 0000000..c9e8778 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__service_unavailable_ask.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "The chat model is unavailable right now. Retry shortly.", + "code": "upstream_unavailable", + "doc_url": "https://lenz.io/docs/errors#unavailable", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "The chat model is unavailable right now. Retry shortly.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "The chat model is unavailable right now. Retry shortly.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "The chat model is unavailable right now. Retry shortly.", + "status": 503 + } + }, + "request_id": "", + "retry_after": 90, + "status_code": 503, + "type": "LenzUpstreamUnavailableError" + } +} diff --git a/tests/fixtures/parity/expected/errors__service_unavailable_capacity.json b/tests/fixtures/parity/expected/errors__service_unavailable_capacity.json new file mode 100644 index 0000000..b628bec --- /dev/null +++ b/tests/fixtures/parity/expected/errors__service_unavailable_capacity.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "doc_url": "https://lenz.io/docs/errors#unavailable", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "status": 503 + } + }, + "request_id": "", + "retry_after": 60, + "status_code": 503, + "type": "LenzUpstreamUnavailableError" + } +} diff --git a/tests/fixtures/parity/expected/errors__validation_malformed_json.json b/tests/fixtures/parity/expected/errors__validation_malformed_json.json new file mode 100644 index 0000000..4321bb7 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__validation_malformed_json.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Cannot parse request body (Expecting property name enclosed in double quotes: line 1 column 2 (char 1))", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Cannot parse request body (Expecting property name enclosed in double quotes: line 1 column 2 (char 1))\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Cannot parse request body (Expecting property name enclosed in double quotes: line 1 column 2 (char 1))", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Cannot parse request body (Expecting property name enclosed in double quotes: line 1 column 2 (char 1))", + "status": 400 + } + }, + "request_id": "", + "status_code": 400, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/errors__validation_missing_field_hint.json b/tests/fixtures/parity/expected/errors__validation_missing_field_hint.json new file mode 100644 index 0000000..6760d1a --- /dev/null +++ b/tests/fixtures/parity/expected/errors__validation_missing_field_hint.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required", + "type": "missing" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]\n Fix: Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/errors__validation_unknown_field_only.json b/tests/fixtures/parity/expected/errors__validation_unknown_field_only.json new file mode 100644 index 0000000..6760d1a --- /dev/null +++ b/tests/fixtures/parity/expected/errors__validation_unknown_field_only.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required", + "type": "missing" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]\n Fix: Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/errors__validation_unknown_field_wrong_type.json b/tests/fixtures/parity/expected/errors__validation_unknown_field_wrong_type.json new file mode 100644 index 0000000..7713b4c --- /dev/null +++ b/tests/fixtures/parity/expected/errors__validation_unknown_field_wrong_type.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "[{'type': 'list_type', 'loc': ['body', 'payload', 'claims'], 'msg': 'Input should be a valid list'}]", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "claims" + ], + "msg": "Input should be a valid list", + "type": "list_type" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "[{'type': 'list_type', 'loc': ['body', 'payload', 'claims'], 'msg': 'Input should be a valid list'}]\n Fix: Check the request body against the OpenAPI spec.", + "message": "[{'type': 'list_type', 'loc': ['body', 'payload', 'claims'], 'msg': 'Input should be a valid list'}]", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "[{'type': 'list_type', 'loc': ['body', 'payload', 'claims'], 'msg': 'Input should be a valid list'}]", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/errors__validation_wrong_type.json b/tests/fixtures/parity/expected/errors__validation_wrong_type.json new file mode 100644 index 0000000..bf16952 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__validation_wrong_type.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "[{'type': 'string_type', 'loc': ['body', 'payload', 'text'], 'msg': 'Input should be a valid string'}]", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Input should be a valid string", + "type": "string_type" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "[{'type': 'string_type', 'loc': ['body', 'payload', 'text'], 'msg': 'Input should be a valid string'}]\n Fix: Check the request body against the OpenAPI spec.", + "message": "[{'type': 'string_type', 'loc': ['body', 'payload', 'text'], 'msg': 'Input should be a valid string'}]", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "[{'type': 'string_type', 'loc': ['body', 'payload', 'text'], 'msg': 'Input should be a valid string'}]", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/errors__web_assess_payment_required.json b/tests/fixtures/parity/expected/errors__web_assess_payment_required.json new file mode 100644 index 0000000..04bef38 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__web_assess_payment_required.json @@ -0,0 +1,28 @@ +{ + "error": { + "cause": "No assessments left this month.", + "code": "no_credits", + "cost": 1, + "credit_balance": 0, + "doc_url": "https://lenz.io/docs/billing", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "friendly_text": "No assessments left this month.\n Fix: Top up or upgrade at https://lenz.io/plans, or wait for the period reset. See https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "message": "No assessments left this month.", + "payload_json": { + "error": { + "code": "no_credits", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "message": "No assessments left this month.", + "status": 402, + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } + }, + "remaining": 0, + "request_id": "", + "requested": null, + "resets_at": "2026-10-01T14:07:00+00:00", + "status_code": 402, + "type": "LenzQuotaExceededError", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } +} diff --git a/tests/fixtures/parity/expected/errors__web_assess_signup_required.json b/tests/fixtures/parity/expected/errors__web_assess_signup_required.json new file mode 100644 index 0000000..b16a7bb --- /dev/null +++ b/tests/fixtures/parity/expected/errors__web_assess_signup_required.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Sign up to check this — it’s free.", + "code": "signup_required", + "doc_url": "https://lenz.io/docs/auth", + "fix": "This key doesn't have access to that resource.", + "friendly_text": "Sign up to check this — it’s free.\n Fix: This key doesn't have access to that resource.", + "message": "Sign up to check this — it’s free.", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "This key doesn't have access to that resource.", + "message": "Sign up to check this — it’s free.", + "status": 403 + } + }, + "request_id": "", + "status_code": 403, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/errors__web_review_rate_limited.json b/tests/fixtures/parity/expected/errors__web_review_rate_limited.json new file mode 100644 index 0000000..6841e77 --- /dev/null +++ b/tests/fixtures/parity/expected/errors__web_review_rate_limited.json @@ -0,0 +1,25 @@ +{ + "error": { + "cause": "This account has used its extractions for today. The daily allowance is shared with the Lenz API. It resets at 00:00 UTC.", + "code": "extract_daily_limit", + "doc_url": "https://lenz.io/docs/rate-limits", + "fix": "Wait Retry-After seconds and retry.", + "friendly_text": "This account has used its extractions for today. The daily allowance is shared with the Lenz API. It resets at 00:00 UTC.\n Fix: Wait Retry-After seconds and retry.", + "limit": 1000, + "message": "This account has used its extractions for today. The daily allowance is shared with the Lenz API. It resets at 00:00 UTC.", + "payload_json": { + "error": { + "code": "rate_limited", + "fix": "Wait Retry-After seconds and retry.", + "message": "This account has used its extractions for today. The daily allowance is shared with the Lenz API. It resets at 00:00 UTC.", + "status": 429 + } + }, + "request_id": "", + "reset_in_seconds": 777, + "retry_after": 777, + "status_code": 429, + "type": "LenzRateLimitError", + "upgrade_url": "https://lenz.io/plans" + } +} diff --git a/tests/fixtures/parity/expected/extract__401_no_key.json b/tests/fixtures/parity/expected/extract__401_no_key.json new file mode 100644 index 0000000..e57982a --- /dev/null +++ b/tests/fixtures/parity/expected/extract__401_no_key.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Unauthorized", + "code": "", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "Unauthorized\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/extract__422_blank_text.json b/tests/fixtures/parity/expected/extract__422_blank_text.json new file mode 100644 index 0000000..872ff11 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__422_blank_text.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Text is required.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Text is required.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Text is required.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Text is required.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/extract__422_focus_too_long.json b/tests/fixtures/parity/expected/extract__422_focus_too_long.json new file mode 100644 index 0000000..e658cd0 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__422_focus_too_long.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "focus must be at most 300 characters of plain text.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "focus must be at most 300 characters of plain text.\n Fix: Check the request body against the OpenAPI spec.", + "message": "focus must be at most 300 characters of plain text.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "focus must be at most 300 characters of plain text.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/extract__422_missing_text.json b/tests/fixtures/parity/expected/extract__422_missing_text.json new file mode 100644 index 0000000..6760d1a --- /dev/null +++ b/tests/fixtures/parity/expected/extract__422_missing_text.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required", + "type": "missing" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]\n Fix: Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/extract__429_daily_limit.json b/tests/fixtures/parity/expected/extract__429_daily_limit.json new file mode 100644 index 0000000..fe317f9 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__429_daily_limit.json @@ -0,0 +1,25 @@ +{ + "error": { + "cause": "Daily /extract limit of 1000 reached for this account. The allowance is shared by every key on the account and by extractions run from the Lenz website.", + "code": "extract_daily_limit", + "doc_url": "https://lenz.io/docs/rate-limits", + "fix": "Wait Retry-After seconds and retry.", + "friendly_text": "Daily /extract limit of 1000 reached for this account. The allowance is shared by every key on the account and by extractions run from the Lenz website.\n Fix: Wait Retry-After seconds and retry.", + "limit": 1000, + "message": "Daily /extract limit of 1000 reached for this account. The allowance is shared by every key on the account and by extractions run from the Lenz website.", + "payload_json": { + "error": { + "code": "rate_limited", + "fix": "Wait Retry-After seconds and retry.", + "message": "Daily /extract limit of 1000 reached for this account. The allowance is shared by every key on the account and by extractions run from the Lenz website.", + "status": 429 + } + }, + "request_id": "", + "reset_in_seconds": 3600, + "retry_after": 3600, + "status_code": 429, + "type": "LenzRateLimitError", + "upgrade_url": "https://lenz.io/plans" + } +} diff --git a/tests/fixtures/parity/expected/extract__502_extraction_failed.json b/tests/fixtures/parity/expected/extract__502_extraction_failed.json new file mode 100644 index 0000000..7ce9984 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__502_extraction_failed.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Extraction failed", + "code": "extraction_failed", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Extraction failed\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Extraction failed", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Extraction failed", + "status": 502 + } + }, + "request_id": "", + "retry_after": null, + "status_code": 502, + "type": "LenzAPIError" + } +} diff --git a/tests/fixtures/parity/expected/extract__503_upstream_unavailable.json b/tests/fixtures/parity/expected/extract__503_upstream_unavailable.json new file mode 100644 index 0000000..7553c4c --- /dev/null +++ b/tests/fixtures/parity/expected/extract__503_upstream_unavailable.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Our model providers are temporarily unavailable. Please retry shortly.", + "code": "upstream_unavailable", + "doc_url": "https://lenz.io/docs/errors#unavailable", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Our model providers are temporarily unavailable. Please retry shortly.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Our model providers are temporarily unavailable. Please retry shortly.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Our model providers are temporarily unavailable. Please retry shortly.", + "status": 503 + } + }, + "request_id": "", + "retry_after": 90, + "status_code": 503, + "type": "LenzUpstreamUnavailableError" + } +} diff --git a/tests/fixtures/parity/expected/extract__focus_ready.json b/tests/fixtures/parity/expected/extract__focus_ready.json new file mode 100644 index 0000000..19a1965 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__focus_ready.json @@ -0,0 +1,45 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "Beta fell 3% last year.", + "domain": "Economics", + "identified_claims": [], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "Beta fell 3% last year.", + "domain": "Economics", + "identified_claims": [], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "render": "Claim: Beta fell 3% last year.\n\nVerify it: lenz verify \"Beta fell 3% last year.\"\n", + "render_json": "{\n \"status\": \"ready\",\n \"claim\": \"Beta fell 3% last year.\",\n \"identified_claims\": [],\n \"candidate_claims\": [],\n \"domain\": \"Economics\",\n \"key_entities\": [\n {\n \"name\": \"Alpha\",\n \"type\": \"organization\"\n },\n {\n \"name\": \"Beta\",\n \"type\": \"organization\"\n }\n ],\n \"presumed_intent\": \"Verify reported figures\",\n \"original_input\": \"Alpha rose 5% in 2024. Beta fell 3% last year.\",\n \"locations\": null\n}\n", + "repr": "ExtractedClaims(status='ready', claim='Beta fell 3% last year.', identified_claims=[], candidate_claims=[], domain='Economics', key_entities=[ExtractedEntity(name='Alpha', type='organization'), ExtractedEntity(name='Beta', type='organization')], presumed_intent='Verify reported figures', original_input='Alpha rose 5% in 2024. Beta fell 3% last year.', locations=None)" +} diff --git a/tests/fixtures/parity/expected/extract__idempotency_body_mismatch_422.json b/tests/fixtures/parity/expected/extract__idempotency_body_mismatch_422.json new file mode 100644 index 0000000..989af48 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__idempotency_body_mismatch_422.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Idempotency-Key reused with a different request body.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Idempotency-Key reused with a different request body.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Idempotency-Key reused with a different request body.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Idempotency-Key reused with a different request body.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/extract__idempotency_replay.json b/tests/fixtures/parity/expected/extract__idempotency_replay.json new file mode 100644 index 0000000..91b0781 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__idempotency_replay.json @@ -0,0 +1,51 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "render": "2 claims found:\n 1. Alpha rose 5% in 2024.\n 2. Beta fell 3% last year.\n", + "render_json": "{\n \"status\": \"ready\",\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"identified_claims\": [\n \"Alpha rose 5% in 2024.\",\n \"Beta fell 3% last year.\"\n ],\n \"candidate_claims\": [],\n \"domain\": \"Economics\",\n \"key_entities\": [\n {\n \"name\": \"Alpha\",\n \"type\": \"organization\"\n },\n {\n \"name\": \"Beta\",\n \"type\": \"organization\"\n }\n ],\n \"presumed_intent\": \"Verify reported figures\",\n \"original_input\": \"Alpha rose 5% in 2024. Beta fell 3% last year.\",\n \"locations\": null\n}\n", + "repr": "ExtractedClaims(status='ready', claim='Alpha rose 5% in 2024.', identified_claims=['Alpha rose 5% in 2024.', 'Beta fell 3% last year.'], candidate_claims=[], domain='Economics', key_entities=[ExtractedEntity(name='Alpha', type='organization'), ExtractedEntity(name='Beta', type='organization')], presumed_intent='Verify reported figures', original_input='Alpha rose 5% in 2024. Beta fell 3% last year.', locations=None)" +} diff --git a/tests/fixtures/parity/expected/extract__locate_all_dropped.json b/tests/fixtures/parity/expected/extract__locate_all_dropped.json new file mode 100644 index 0000000..637c818 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__locate_all_dropped.json @@ -0,0 +1,45 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "", + "domain": "", + "identified_claims": [], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": [], + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "not_a_claim" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "", + "domain": "", + "identified_claims": [], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": [], + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "not_a_claim" + }, + "render": "No verifiable claim found in that text.\n", + "render_json": "{\n \"status\": \"not_a_claim\",\n \"claim\": \"\",\n \"identified_claims\": [],\n \"candidate_claims\": [],\n \"domain\": \"\",\n \"key_entities\": [\n {\n \"name\": \"Alpha\",\n \"type\": \"organization\"\n },\n {\n \"name\": \"Beta\",\n \"type\": \"organization\"\n }\n ],\n \"presumed_intent\": \"Verify reported figures\",\n \"original_input\": \"Alpha rose 5% in 2024. Beta fell 3% last year.\",\n \"locations\": []\n}\n", + "repr": "ExtractedClaims(status='not_a_claim', claim='', identified_claims=[], candidate_claims=[], domain='', key_entities=[ExtractedEntity(name='Alpha', type='organization'), ExtractedEntity(name='Beta', type='organization')], presumed_intent='Verify reported figures', original_input='Alpha rose 5% in 2024. Beta fell 3% last year.', locations=[])" +} diff --git a/tests/fixtures/parity/expected/extract__locate_failed.json b/tests/fixtures/parity/expected/extract__locate_failed.json new file mode 100644 index 0000000..91b0781 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__locate_failed.json @@ -0,0 +1,51 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "render": "2 claims found:\n 1. Alpha rose 5% in 2024.\n 2. Beta fell 3% last year.\n", + "render_json": "{\n \"status\": \"ready\",\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"identified_claims\": [\n \"Alpha rose 5% in 2024.\",\n \"Beta fell 3% last year.\"\n ],\n \"candidate_claims\": [],\n \"domain\": \"Economics\",\n \"key_entities\": [\n {\n \"name\": \"Alpha\",\n \"type\": \"organization\"\n },\n {\n \"name\": \"Beta\",\n \"type\": \"organization\"\n }\n ],\n \"presumed_intent\": \"Verify reported figures\",\n \"original_input\": \"Alpha rose 5% in 2024. Beta fell 3% last year.\",\n \"locations\": null\n}\n", + "repr": "ExtractedClaims(status='ready', claim='Alpha rose 5% in 2024.', identified_claims=['Alpha rose 5% in 2024.', 'Beta fell 3% last year.'], candidate_claims=[], domain='Economics', key_entities=[ExtractedEntity(name='Alpha', type='organization'), ExtractedEntity(name='Beta', type='organization')], presumed_intent='Verify reported figures', original_input='Alpha rose 5% in 2024. Beta fell 3% last year.', locations=None)" +} diff --git a/tests/fixtures/parity/expected/extract__locate_leading_whitespace.json b/tests/fixtures/parity/expected/extract__locate_leading_whitespace.json new file mode 100644 index 0000000..cac302f --- /dev/null +++ b/tests/fixtures/parity/expected/extract__locate_leading_whitespace.json @@ -0,0 +1,67 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "end": 25, + "start": 3, + "text": "Alpha rose 5% in 2024." + } + ] + } + ], + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "end": 25, + "start": 3, + "text": "Alpha rose 5% in 2024." + } + ] + } + ], + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "render": "Claim: Alpha rose 5% in 2024.\n at 3-25: \"Alpha rose 5% in 2024.\"\n\nVerify it: lenz verify \"Alpha rose 5% in 2024.\"\n", + "render_json": "{\n \"status\": \"ready\",\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"identified_claims\": [],\n \"candidate_claims\": [],\n \"domain\": \"Economics\",\n \"key_entities\": [\n {\n \"name\": \"Alpha\",\n \"type\": \"organization\"\n },\n {\n \"name\": \"Beta\",\n \"type\": \"organization\"\n }\n ],\n \"presumed_intent\": \"Verify reported figures\",\n \"original_input\": \"Alpha rose 5% in 2024. Beta fell 3% last year.\",\n \"locations\": [\n {\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"positions\": [\n {\n \"start\": 3,\n \"end\": 25,\n \"text\": \"Alpha rose 5% in 2024.\"\n }\n ]\n }\n ]\n}\n", + "repr": "ExtractedClaims(status='ready', claim='Alpha rose 5% in 2024.', identified_claims=[], candidate_claims=[], domain='Economics', key_entities=[ExtractedEntity(name='Alpha', type='organization'), ExtractedEntity(name='Beta', type='organization')], presumed_intent='Verify reported figures', original_input='Alpha rose 5% in 2024. Beta fell 3% last year.', locations=[ClaimLocation(claim='Alpha rose 5% in 2024.', positions=[Position(start=3, end=25, text='Alpha rose 5% in 2024.')])])" +} diff --git a/tests/fixtures/parity/expected/extract__locate_some_dropped.json b/tests/fixtures/parity/expected/extract__locate_some_dropped.json new file mode 100644 index 0000000..09f3760 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__locate_some_dropped.json @@ -0,0 +1,93 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "end": 22, + "start": 0, + "text": "Alpha rose 5% in 2024." + } + ] + }, + { + "claim": "Beta fell 3% last year.", + "positions": [ + { + "end": 46, + "start": 23, + "text": "Beta fell 3% last year." + } + ] + } + ], + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "end": 22, + "start": 0, + "text": "Alpha rose 5% in 2024." + } + ] + }, + { + "claim": "Beta fell 3% last year.", + "positions": [ + { + "end": 46, + "start": 23, + "text": "Beta fell 3% last year." + } + ] + } + ], + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "render": "2 claims found:\n 1. Alpha rose 5% in 2024.\n at 0-22: \"Alpha rose 5% in 2024.\"\n 2. Beta fell 3% last year.\n at 23-46: \"Beta fell 3% last year.\"\n", + "render_json": "{\n \"status\": \"ready\",\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"identified_claims\": [\n \"Alpha rose 5% in 2024.\",\n \"Beta fell 3% last year.\"\n ],\n \"candidate_claims\": [],\n \"domain\": \"Economics\",\n \"key_entities\": [\n {\n \"name\": \"Alpha\",\n \"type\": \"organization\"\n },\n {\n \"name\": \"Beta\",\n \"type\": \"organization\"\n }\n ],\n \"presumed_intent\": \"Verify reported figures\",\n \"original_input\": \"Alpha rose 5% in 2024. Beta fell 3% last year.\",\n \"locations\": [\n {\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"positions\": [\n {\n \"start\": 0,\n \"end\": 22,\n \"text\": \"Alpha rose 5% in 2024.\"\n }\n ]\n },\n {\n \"claim\": \"Beta fell 3% last year.\",\n \"positions\": [\n {\n \"start\": 23,\n \"end\": 46,\n \"text\": \"Beta fell 3% last year.\"\n }\n ]\n }\n ]\n}\n", + "repr": "ExtractedClaims(status='ready', claim='Alpha rose 5% in 2024.', identified_claims=['Alpha rose 5% in 2024.', 'Beta fell 3% last year.'], candidate_claims=[], domain='Economics', key_entities=[ExtractedEntity(name='Alpha', type='organization'), ExtractedEntity(name='Beta', type='organization')], presumed_intent='Verify reported figures', original_input='Alpha rose 5% in 2024. Beta fell 3% last year.', locations=[ClaimLocation(claim='Alpha rose 5% in 2024.', positions=[Position(start=0, end=22, text='Alpha rose 5% in 2024.')]), ClaimLocation(claim='Beta fell 3% last year.', positions=[Position(start=23, end=46, text='Beta fell 3% last year.')])])" +} diff --git a/tests/fixtures/parity/expected/extract__locate_true.json b/tests/fixtures/parity/expected/extract__locate_true.json new file mode 100644 index 0000000..09f3760 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__locate_true.json @@ -0,0 +1,93 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "end": 22, + "start": 0, + "text": "Alpha rose 5% in 2024." + } + ] + }, + { + "claim": "Beta fell 3% last year.", + "positions": [ + { + "end": 46, + "start": 23, + "text": "Beta fell 3% last year." + } + ] + } + ], + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "end": 22, + "start": 0, + "text": "Alpha rose 5% in 2024." + } + ] + }, + { + "claim": "Beta fell 3% last year.", + "positions": [ + { + "end": 46, + "start": 23, + "text": "Beta fell 3% last year." + } + ] + } + ], + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "render": "2 claims found:\n 1. Alpha rose 5% in 2024.\n at 0-22: \"Alpha rose 5% in 2024.\"\n 2. Beta fell 3% last year.\n at 23-46: \"Beta fell 3% last year.\"\n", + "render_json": "{\n \"status\": \"ready\",\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"identified_claims\": [\n \"Alpha rose 5% in 2024.\",\n \"Beta fell 3% last year.\"\n ],\n \"candidate_claims\": [],\n \"domain\": \"Economics\",\n \"key_entities\": [\n {\n \"name\": \"Alpha\",\n \"type\": \"organization\"\n },\n {\n \"name\": \"Beta\",\n \"type\": \"organization\"\n }\n ],\n \"presumed_intent\": \"Verify reported figures\",\n \"original_input\": \"Alpha rose 5% in 2024. Beta fell 3% last year.\",\n \"locations\": [\n {\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"positions\": [\n {\n \"start\": 0,\n \"end\": 22,\n \"text\": \"Alpha rose 5% in 2024.\"\n }\n ]\n },\n {\n \"claim\": \"Beta fell 3% last year.\",\n \"positions\": [\n {\n \"start\": 23,\n \"end\": 46,\n \"text\": \"Beta fell 3% last year.\"\n }\n ]\n }\n ]\n}\n", + "repr": "ExtractedClaims(status='ready', claim='Alpha rose 5% in 2024.', identified_claims=['Alpha rose 5% in 2024.', 'Beta fell 3% last year.'], candidate_claims=[], domain='Economics', key_entities=[ExtractedEntity(name='Alpha', type='organization'), ExtractedEntity(name='Beta', type='organization')], presumed_intent='Verify reported figures', original_input='Alpha rose 5% in 2024. Beta fell 3% last year.', locations=[ClaimLocation(claim='Alpha rose 5% in 2024.', positions=[Position(start=0, end=22, text='Alpha rose 5% in 2024.')]), ClaimLocation(claim='Beta fell 3% last year.', positions=[Position(start=23, end=46, text='Beta fell 3% last year.')])])" +} diff --git a/tests/fixtures/parity/expected/extract__no_match_with_focus.json b/tests/fixtures/parity/expected/extract__no_match_with_focus.json new file mode 100644 index 0000000..16a3c71 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__no_match_with_focus.json @@ -0,0 +1,27 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "", + "domain": "", + "identified_claims": [], + "key_entities": [], + "locations": null, + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "", + "status": "no_match" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "", + "domain": "", + "identified_claims": [], + "key_entities": [], + "locations": null, + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "", + "status": "no_match" + }, + "render": "No claims matched the focus.\n", + "render_json": "{\n \"status\": \"no_match\",\n \"claim\": \"\",\n \"identified_claims\": [],\n \"candidate_claims\": [],\n \"domain\": \"\",\n \"key_entities\": [],\n \"presumed_intent\": \"\",\n \"original_input\": \"Alpha rose 5% in 2024. Beta fell 3% last year.\",\n \"locations\": null\n}\n", + "repr": "ExtractedClaims(status='no_match', claim='', identified_claims=[], candidate_claims=[], domain='', key_entities=[], presumed_intent='', original_input='Alpha rose 5% in 2024. Beta fell 3% last year.', locations=None)" +} diff --git a/tests/fixtures/parity/expected/extract__not_a_claim.json b/tests/fixtures/parity/expected/extract__not_a_claim.json new file mode 100644 index 0000000..48b365f --- /dev/null +++ b/tests/fixtures/parity/expected/extract__not_a_claim.json @@ -0,0 +1,27 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "", + "domain": "", + "identified_claims": [], + "key_entities": [], + "locations": null, + "original_input": "What a lovely day.", + "presumed_intent": "", + "status": "not_a_claim" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "", + "domain": "", + "identified_claims": [], + "key_entities": [], + "locations": null, + "original_input": "What a lovely day.", + "presumed_intent": "", + "status": "not_a_claim" + }, + "render": "No verifiable claim found in that text.\n", + "render_json": "{\n \"status\": \"not_a_claim\",\n \"claim\": \"\",\n \"identified_claims\": [],\n \"candidate_claims\": [],\n \"domain\": \"\",\n \"key_entities\": [],\n \"presumed_intent\": \"\",\n \"original_input\": \"What a lovely day.\",\n \"locations\": null\n}\n", + "repr": "ExtractedClaims(status='not_a_claim', claim='', identified_claims=[], candidate_claims=[], domain='', key_entities=[], presumed_intent='', original_input='What a lovely day.', locations=None)" +} diff --git a/tests/fixtures/parity/expected/extract__not_a_claim_beside_claims.json b/tests/fixtures/parity/expected/extract__not_a_claim_beside_claims.json new file mode 100644 index 0000000..13ec077 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__not_a_claim_beside_claims.json @@ -0,0 +1,45 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024.", + "presumed_intent": "Verify reported figures", + "status": "not_a_claim" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024.", + "presumed_intent": "Verify reported figures", + "status": "not_a_claim" + }, + "render": "Claim: Alpha rose 5% in 2024.\n\nVerify it: lenz verify \"Alpha rose 5% in 2024.\"\n", + "render_json": "{\n \"status\": \"not_a_claim\",\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"identified_claims\": [],\n \"candidate_claims\": [],\n \"domain\": \"Economics\",\n \"key_entities\": [\n {\n \"name\": \"Alpha\",\n \"type\": \"organization\"\n },\n {\n \"name\": \"Beta\",\n \"type\": \"organization\"\n }\n ],\n \"presumed_intent\": \"Verify reported figures\",\n \"original_input\": \"Alpha rose 5% in 2024.\",\n \"locations\": null\n}\n", + "repr": "ExtractedClaims(status='not_a_claim', claim='Alpha rose 5% in 2024.', identified_claims=[], candidate_claims=[], domain='Economics', key_entities=[ExtractedEntity(name='Alpha', type='organization'), ExtractedEntity(name='Beta', type='organization')], presumed_intent='Verify reported figures', original_input='Alpha rose 5% in 2024.', locations=None)" +} diff --git a/tests/fixtures/parity/expected/extract__ready_one_claim.json b/tests/fixtures/parity/expected/extract__ready_one_claim.json new file mode 100644 index 0000000..2f536e5 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__ready_one_claim.json @@ -0,0 +1,45 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "render": "Claim: Alpha rose 5% in 2024.\n\nVerify it: lenz verify \"Alpha rose 5% in 2024.\"\n", + "render_json": "{\n \"status\": \"ready\",\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"identified_claims\": [],\n \"candidate_claims\": [],\n \"domain\": \"Economics\",\n \"key_entities\": [\n {\n \"name\": \"Alpha\",\n \"type\": \"organization\"\n },\n {\n \"name\": \"Beta\",\n \"type\": \"organization\"\n }\n ],\n \"presumed_intent\": \"Verify reported figures\",\n \"original_input\": \"Alpha rose 5% in 2024.\",\n \"locations\": null\n}\n", + "repr": "ExtractedClaims(status='ready', claim='Alpha rose 5% in 2024.', identified_claims=[], candidate_claims=[], domain='Economics', key_entities=[ExtractedEntity(name='Alpha', type='organization'), ExtractedEntity(name='Beta', type='organization')], presumed_intent='Verify reported figures', original_input='Alpha rose 5% in 2024.', locations=None)" +} diff --git a/tests/fixtures/parity/expected/extract__ready_several_claims.json b/tests/fixtures/parity/expected/extract__ready_several_claims.json new file mode 100644 index 0000000..91b0781 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__ready_several_claims.json @@ -0,0 +1,51 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "render": "2 claims found:\n 1. Alpha rose 5% in 2024.\n 2. Beta fell 3% last year.\n", + "render_json": "{\n \"status\": \"ready\",\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"identified_claims\": [\n \"Alpha rose 5% in 2024.\",\n \"Beta fell 3% last year.\"\n ],\n \"candidate_claims\": [],\n \"domain\": \"Economics\",\n \"key_entities\": [\n {\n \"name\": \"Alpha\",\n \"type\": \"organization\"\n },\n {\n \"name\": \"Beta\",\n \"type\": \"organization\"\n }\n ],\n \"presumed_intent\": \"Verify reported figures\",\n \"original_input\": \"Alpha rose 5% in 2024. Beta fell 3% last year.\",\n \"locations\": null\n}\n", + "repr": "ExtractedClaims(status='ready', claim='Alpha rose 5% in 2024.', identified_claims=['Alpha rose 5% in 2024.', 'Beta fell 3% last year.'], candidate_claims=[], domain='Economics', key_entities=[ExtractedEntity(name='Alpha', type='organization'), ExtractedEntity(name='Beta', type='organization')], presumed_intent='Verify reported figures', original_input='Alpha rose 5% in 2024. Beta fell 3% last year.', locations=None)" +} diff --git a/tests/fixtures/parity/expected/extract__replay_later_200.json b/tests/fixtures/parity/expected/extract__replay_later_200.json new file mode 100644 index 0000000..91b0781 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__replay_later_200.json @@ -0,0 +1,51 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": null, + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "render": "2 claims found:\n 1. Alpha rose 5% in 2024.\n 2. Beta fell 3% last year.\n", + "render_json": "{\n \"status\": \"ready\",\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"identified_claims\": [\n \"Alpha rose 5% in 2024.\",\n \"Beta fell 3% last year.\"\n ],\n \"candidate_claims\": [],\n \"domain\": \"Economics\",\n \"key_entities\": [\n {\n \"name\": \"Alpha\",\n \"type\": \"organization\"\n },\n {\n \"name\": \"Beta\",\n \"type\": \"organization\"\n }\n ],\n \"presumed_intent\": \"Verify reported figures\",\n \"original_input\": \"Alpha rose 5% in 2024. Beta fell 3% last year.\",\n \"locations\": null\n}\n", + "repr": "ExtractedClaims(status='ready', claim='Alpha rose 5% in 2024.', identified_claims=['Alpha rose 5% in 2024.', 'Beta fell 3% last year.'], candidate_claims=[], domain='Economics', key_entities=[ExtractedEntity(name='Alpha', type='organization'), ExtractedEntity(name='Beta', type='organization')], presumed_intent='Verify reported figures', original_input='Alpha rose 5% in 2024. Beta fell 3% last year.', locations=None)" +} diff --git a/tests/fixtures/parity/expected/extract__url_fetch_502_unreadable.json b/tests/fixtures/parity/expected/extract__url_fetch_502_unreadable.json new file mode 100644 index 0000000..7ce9984 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__url_fetch_502_unreadable.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Extraction failed", + "code": "extraction_failed", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Extraction failed\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Extraction failed", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Extraction failed", + "status": 502 + } + }, + "request_id": "", + "retry_after": null, + "status_code": 502, + "type": "LenzAPIError" + } +} diff --git a/tests/fixtures/parity/expected/extract__url_fetch_503_upstream.json b/tests/fixtures/parity/expected/extract__url_fetch_503_upstream.json new file mode 100644 index 0000000..01e9faf --- /dev/null +++ b/tests/fixtures/parity/expected/extract__url_fetch_503_upstream.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "The page could not be read right now. Please retry shortly.", + "code": "upstream_unavailable", + "doc_url": "https://lenz.io/docs/errors#unavailable", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "The page could not be read right now. Please retry shortly.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "The page could not be read right now. Please retry shortly.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "The page could not be read right now. Please retry shortly.", + "status": 503 + } + }, + "request_id": "", + "retry_after": 90, + "status_code": 503, + "type": "LenzUpstreamUnavailableError" + } +} diff --git a/tests/fixtures/parity/expected/extract__url_input_located.json b/tests/fixtures/parity/expected/extract__url_input_located.json new file mode 100644 index 0000000..d928040 --- /dev/null +++ b/tests/fixtures/parity/expected/extract__url_input_located.json @@ -0,0 +1,67 @@ +{ + "dump": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "end": null, + "start": null, + "text": "Alpha rose 5% in 2024." + } + ] + } + ], + "original_input": "https://example.com/an-article", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "dump_unset": { + "candidate_claims": [], + "claim": "Alpha rose 5% in 2024.", + "domain": "Economics", + "identified_claims": [], + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "locations": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "end": null, + "start": null, + "text": "Alpha rose 5% in 2024." + } + ] + } + ], + "original_input": "https://example.com/an-article", + "presumed_intent": "Verify reported figures", + "status": "ready" + }, + "render": "Claim: Alpha rose 5% in 2024.\n at \"Alpha rose 5% in 2024.\"\n\nVerify it: lenz verify \"Alpha rose 5% in 2024.\"\n", + "render_json": "{\n \"status\": \"ready\",\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"identified_claims\": [],\n \"candidate_claims\": [],\n \"domain\": \"Economics\",\n \"key_entities\": [\n {\n \"name\": \"Alpha\",\n \"type\": \"organization\"\n },\n {\n \"name\": \"Beta\",\n \"type\": \"organization\"\n }\n ],\n \"presumed_intent\": \"Verify reported figures\",\n \"original_input\": \"https://example.com/an-article\",\n \"locations\": [\n {\n \"claim\": \"Alpha rose 5% in 2024.\",\n \"positions\": [\n {\n \"start\": null,\n \"end\": null,\n \"text\": \"Alpha rose 5% in 2024.\"\n }\n ]\n }\n ]\n}\n", + "repr": "ExtractedClaims(status='ready', claim='Alpha rose 5% in 2024.', identified_claims=[], candidate_claims=[], domain='Economics', key_entities=[ExtractedEntity(name='Alpha', type='organization'), ExtractedEntity(name='Beta', type='organization')], presumed_intent='Verify reported figures', original_input='https://example.com/an-article', locations=[ClaimLocation(claim='Alpha rose 5% in 2024.', positions=[Position(start=None, end=None, text='Alpha rose 5% in 2024.')])])" +} diff --git a/tests/fixtures/parity/expected/review__401_no_credentials.json b/tests/fixtures/parity/expected/review__401_no_credentials.json new file mode 100644 index 0000000..e57982a --- /dev/null +++ b/tests/fixtures/parity/expected/review__401_no_credentials.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Unauthorized", + "code": "", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "Unauthorized\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/review__402_no_credits.json b/tests/fixtures/parity/expected/review__402_no_credits.json new file mode 100644 index 0000000..d6661c5 --- /dev/null +++ b/tests/fixtures/parity/expected/review__402_no_credits.json @@ -0,0 +1,28 @@ +{ + "error": { + "cause": "No remaining credits to assess the draft.", + "code": "no_credits", + "cost": 1, + "credit_balance": 100, + "doc_url": "https://lenz.io/docs/billing", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "friendly_text": "No remaining credits to assess the draft.\n Fix: Top up or upgrade at https://lenz.io/plans, or wait for the period reset. See https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "message": "No remaining credits to assess the draft.", + "payload_json": { + "error": { + "code": "no_credits", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "message": "No remaining credits to assess the draft.", + "status": 402, + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } + }, + "remaining": 100, + "request_id": "", + "requested": null, + "resets_at": "2026-10-01T14:07:00+00:00", + "status_code": 402, + "type": "LenzQuotaExceededError", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } +} diff --git a/tests/fixtures/parity/expected/review__402_no_credits_exhausted.json b/tests/fixtures/parity/expected/review__402_no_credits_exhausted.json new file mode 100644 index 0000000..75b0213 --- /dev/null +++ b/tests/fixtures/parity/expected/review__402_no_credits_exhausted.json @@ -0,0 +1,28 @@ +{ + "error": { + "cause": "No remaining credits to assess the draft.", + "code": "no_credits", + "cost": 1, + "credit_balance": 0, + "doc_url": "https://lenz.io/docs/billing", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "friendly_text": "No remaining credits to assess the draft.\n Fix: Top up or upgrade at https://lenz.io/plans, or wait for the period reset. See https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "message": "No remaining credits to assess the draft.", + "payload_json": { + "error": { + "code": "no_credits", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "message": "No remaining credits to assess the draft.", + "status": 402, + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } + }, + "remaining": 0, + "request_id": "", + "requested": null, + "resets_at": "2026-10-01T14:07:00+00:00", + "status_code": 402, + "type": "LenzQuotaExceededError", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } +} diff --git a/tests/fixtures/parity/expected/review__422_blank_text.json b/tests/fixtures/parity/expected/review__422_blank_text.json new file mode 100644 index 0000000..2f05a24 --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_blank_text.json @@ -0,0 +1,30 @@ +{ + "error": { + "cause": "text: send the draft, or one public http(s) URL.", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "text" + ], + "msg": "text: send the draft, or one public http(s) URL." + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "text: send the draft, or one public http(s) URL.\n Fix: Check the request body against the OpenAPI spec.", + "message": "text: send the draft, or one public http(s) URL.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "text: send the draft, or one public http(s) URL.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_citations_options_object.json b/tests/fixtures/parity/expected/review__422_citations_options_object.json new file mode 100644 index 0000000..eb82b86 --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_citations_options_object.json @@ -0,0 +1,31 @@ +{ + "error": { + "cause": "payload.citations: Extra inputs are not permitted", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "citations" + ], + "msg": "Extra inputs are not permitted" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.citations: Extra inputs are not permitted\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.citations: Extra inputs are not permitted", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.citations: Extra inputs are not permitted", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_depth_unknown.json b/tests/fixtures/parity/expected/review__422_depth_unknown.json new file mode 100644 index 0000000..c4709d8 --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_depth_unknown.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "payload.escalate.depth: Input should be 'standard' or 'low'", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "depth" + ], + "msg": "Input should be 'standard' or 'low'" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.escalate.depth: Input should be 'standard' or 'low'\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.escalate.depth: Input should be 'standard' or 'low'", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.escalate.depth: Input should be 'standard' or 'low'", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_invalid_confidence_band.json b/tests/fixtures/parity/expected/review__422_invalid_confidence_band.json new file mode 100644 index 0000000..6d1bc1b --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_invalid_confidence_band.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "payload.escalate.confidence: Unknown confidence band 'certain'; use low, medium or high.", + "code": "invalid_confidence_band", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "confidence" + ], + "msg": "Unknown confidence band 'certain'; use low, medium or high." + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.escalate.confidence: Unknown confidence band 'certain'; use low, medium or high.\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.escalate.confidence: Unknown confidence band 'certain'; use low, medium or high.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.escalate.confidence: Unknown confidence band 'certain'; use low, medium or high.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_invalid_verdict_label.json b/tests/fixtures/parity/expected/review__422_invalid_verdict_label.json new file mode 100644 index 0000000..27f708f --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_invalid_verdict_label.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "payload.escalate.verdicts: Unknown verdict label 'Misleading'; use one of: False, Mostly False, Mixed, Mostly True, True.", + "code": "invalid_verdict_label", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "verdicts" + ], + "msg": "Unknown verdict label 'Misleading'; use one of: False, Mostly False, Mixed, Mostly True, True." + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.escalate.verdicts: Unknown verdict label 'Misleading'; use one of: False, Mostly False, Mixed, Mostly True, True.\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.escalate.verdicts: Unknown verdict label 'Misleading'; use one of: False, Mostly False, Mixed, Mostly True, True.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.escalate.verdicts: Unknown verdict label 'Misleading'; use one of: False, Mostly False, Mixed, Mostly True, True.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_max_assessments_negative.json b/tests/fixtures/parity/expected/review__422_max_assessments_negative.json new file mode 100644 index 0000000..190d110 --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_max_assessments_negative.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "payload.escalate.max_assessments: Input should be greater than or equal to 0", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "max_assessments" + ], + "msg": "Input should be greater than or equal to 0" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.escalate.max_assessments: Input should be greater than or equal to 0\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.escalate.max_assessments: Input should be greater than or equal to 0", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.escalate.max_assessments: Input should be greater than or equal to 0", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_max_citations_negative.json b/tests/fixtures/parity/expected/review__422_max_citations_negative.json new file mode 100644 index 0000000..cf456cf --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_max_citations_negative.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "payload.escalate.max_citations: Input should be greater than or equal to 0", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "max_citations" + ], + "msg": "Input should be greater than or equal to 0" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.escalate.max_citations: Input should be greater than or equal to 0\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.escalate.max_citations: Input should be greater than or equal to 0", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.escalate.max_citations: Input should be greater than or equal to 0", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_max_citations_too_big.json b/tests/fixtures/parity/expected/review__422_max_citations_too_big.json new file mode 100644 index 0000000..4888a1c --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_max_citations_too_big.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "payload.escalate.max_citations: Input should be less than or equal to 20", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "max_citations" + ], + "msg": "Input should be less than or equal to 20" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.escalate.max_citations: Input should be less than or equal to 20\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.escalate.max_citations: Input should be less than or equal to 20", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.escalate.max_citations: Input should be less than or equal to 20", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_max_verifications_too_big.json b/tests/fixtures/parity/expected/review__422_max_verifications_too_big.json new file mode 100644 index 0000000..88ecb6e --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_max_verifications_too_big.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "payload.escalate.max_verifications: Input should be less than or equal to 20", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "max_verifications" + ], + "msg": "Input should be less than or equal to 20" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.escalate.max_verifications: Input should be less than or equal to 20\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.escalate.max_verifications: Input should be less than or equal to 20", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.escalate.max_verifications: Input should be less than or equal to 20", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_text_missing.json b/tests/fixtures/parity/expected/review__422_text_missing.json new file mode 100644 index 0000000..627bead --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_text_missing.json @@ -0,0 +1,31 @@ +{ + "error": { + "cause": "payload.text: Field required", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.text: Field required\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.text: Field required", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.text: Field required", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_text_wrong_type.json b/tests/fixtures/parity/expected/review__422_text_wrong_type.json new file mode 100644 index 0000000..66dd498 --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_text_wrong_type.json @@ -0,0 +1,31 @@ +{ + "error": { + "cause": "payload.text: Input should be a valid string", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Input should be a valid string" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.text: Input should be a valid string\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.text: Input should be a valid string", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.text: Input should be a valid string", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_unknown_escalate_field.json b/tests/fixtures/parity/expected/review__422_unknown_escalate_field.json new file mode 100644 index 0000000..78a92fb --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_unknown_escalate_field.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "payload.escalate.nope: Extra inputs are not permitted", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "nope" + ], + "msg": "Extra inputs are not permitted" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.escalate.nope: Extra inputs are not permitted\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.escalate.nope: Extra inputs are not permitted", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.escalate.nope: Extra inputs are not permitted", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_unknown_top_level_field.json b/tests/fixtures/parity/expected/review__422_unknown_top_level_field.json new file mode 100644 index 0000000..110cec7 --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_unknown_top_level_field.json @@ -0,0 +1,31 @@ +{ + "error": { + "cause": "payload.max_verifications: Extra inputs are not permitted", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "max_verifications" + ], + "msg": "Extra inputs are not permitted" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.max_verifications: Extra inputs are not permitted\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.max_verifications: Extra inputs are not permitted", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.max_verifications: Extra inputs are not permitted", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_unsupported_language.json b/tests/fixtures/parity/expected/review__422_unsupported_language.json new file mode 100644 index 0000000..f15e35e --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_unsupported_language.json @@ -0,0 +1,30 @@ +{ + "error": { + "cause": "language: Unsupported language 'xx'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "language" + ], + "msg": "language: Unsupported language 'xx'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact." + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "language: Unsupported language 'xx'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.\n Fix: Check the request body against the OpenAPI spec.", + "message": "language: Unsupported language 'xx'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "language: Unsupported language 'xx'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_visibility_public.json b/tests/fixtures/parity/expected/review__422_visibility_public.json new file mode 100644 index 0000000..a4c768d --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_visibility_public.json @@ -0,0 +1,31 @@ +{ + "error": { + "cause": "payload.visibility: Input should be 'private' or 'unlisted'", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "visibility" + ], + "msg": "Input should be 'private' or 'unlisted'" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "payload.visibility: Input should be 'private' or 'unlisted'\n Fix: Check the request body against the OpenAPI spec.", + "message": "payload.visibility: Input should be 'private' or 'unlisted'", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "payload.visibility: Input should be 'private' or 'unlisted'", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__422_webhook_secret_missing.json b/tests/fixtures/parity/expected/review__422_webhook_secret_missing.json new file mode 100644 index 0000000..aa5a20c --- /dev/null +++ b/tests/fixtures/parity/expected/review__422_webhook_secret_missing.json @@ -0,0 +1,30 @@ +{ + "error": { + "cause": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.", + "code": "webhook_secret_missing", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "webhook_url" + ], + "msg": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend." + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.\n Fix: Check the request body against the OpenAPI spec.", + "message": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__429_extract_daily_limit.json b/tests/fixtures/parity/expected/review__429_extract_daily_limit.json new file mode 100644 index 0000000..9486b2b --- /dev/null +++ b/tests/fixtures/parity/expected/review__429_extract_daily_limit.json @@ -0,0 +1,25 @@ +{ + "error": { + "cause": "Daily /extract limit of 1000 reached for this account. A review of a URL reads the page like /extract and counts as one /extract call.", + "code": "extract_daily_limit", + "doc_url": "https://lenz.io/docs/rate-limits", + "fix": "Wait Retry-After seconds and retry.", + "friendly_text": "Daily /extract limit of 1000 reached for this account. A review of a URL reads the page like /extract and counts as one /extract call.\n Fix: Wait Retry-After seconds and retry.", + "limit": 1000, + "message": "Daily /extract limit of 1000 reached for this account. A review of a URL reads the page like /extract and counts as one /extract call.", + "payload_json": { + "error": { + "code": "rate_limited", + "fix": "Wait Retry-After seconds and retry.", + "message": "Daily /extract limit of 1000 reached for this account. A review of a URL reads the page like /extract and counts as one /extract call.", + "status": 429 + } + }, + "request_id": "", + "reset_in_seconds": 60, + "retry_after": 60, + "status_code": 429, + "type": "LenzRateLimitError", + "upgrade_url": "https://lenz.io/plans" + } +} diff --git a/tests/fixtures/parity/expected/review__429_review_in_flight.json b/tests/fixtures/parity/expected/review__429_review_in_flight.json new file mode 100644 index 0000000..2d14064 --- /dev/null +++ b/tests/fixtures/parity/expected/review__429_review_in_flight.json @@ -0,0 +1,25 @@ +{ + "error": { + "cause": "This account already has 3 reviews running. Retry when one completes.", + "code": "review_in_flight", + "doc_url": "https://lenz.io/docs/rate-limits", + "fix": "Wait Retry-After seconds and retry.", + "friendly_text": "This account already has 3 reviews running. Retry when one completes.\n Fix: Wait Retry-After seconds and retry.", + "limit": null, + "message": "This account already has 3 reviews running. Retry when one completes.", + "payload_json": { + "error": { + "code": "rate_limited", + "fix": "Wait Retry-After seconds and retry.", + "message": "This account already has 3 reviews running. Retry when one completes.", + "status": 429 + } + }, + "request_id": "", + "reset_in_seconds": null, + "retry_after": 60, + "status_code": 429, + "type": "LenzRateLimitError", + "upgrade_url": "" + } +} diff --git a/tests/fixtures/parity/expected/review__503_capacity.json b/tests/fixtures/parity/expected/review__503_capacity.json new file mode 100644 index 0000000..5384727 --- /dev/null +++ b/tests/fixtures/parity/expected/review__503_capacity.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "doc_url": "https://lenz.io/docs/errors#unavailable", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "status": 503 + } + }, + "request_id": "", + "retry_after": 90, + "status_code": 503, + "type": "LenzUpstreamUnavailableError" + } +} diff --git a/tests/fixtures/parity/expected/review__503_citations_capacity.json b/tests/fixtures/parity/expected/review__503_citations_capacity.json new file mode 100644 index 0000000..5384727 --- /dev/null +++ b/tests/fixtures/parity/expected/review__503_citations_capacity.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "doc_url": "https://lenz.io/docs/errors#unavailable", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "status": 503 + } + }, + "request_id": "", + "retry_after": 90, + "status_code": 503, + "type": "LenzUpstreamUnavailableError" + } +} diff --git a/tests/fixtures/parity/expected/review__delete_not_a_route.json b/tests/fixtures/parity/expected/review__delete_not_a_route.json new file mode 100644 index 0000000..ebe2cee --- /dev/null +++ b/tests/fixtures/parity/expected/review__delete_not_a_route.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "HTTP 405", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "HTTP 405\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 405", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "HTTP 405", + "status": 405 + } + }, + "request_id": "", + "status_code": 405, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/review__get_403_insufficient_scope.json b/tests/fixtures/parity/expected/review__get_403_insufficient_scope.json new file mode 100644 index 0000000..567f3ae --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_403_insufficient_scope.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "The access token does not allow this call.", + "code": "insufficient_scope", + "doc_url": "https://lenz.io/docs/auth", + "fix": "This key doesn't have access to that resource.", + "friendly_text": "The access token does not allow this call.\n Fix: This key doesn't have access to that resource.", + "message": "The access token does not allow this call.", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "This key doesn't have access to that resource.", + "message": "The access token does not allow this call.", + "status": 403 + } + }, + "request_id": "", + "status_code": 403, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/review__get_404_not_found.json b/tests/fixtures/parity/expected/review__get_404_not_found.json new file mode 100644 index 0000000..528e617 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_404_not_found.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Review not found.", + "code": "not_found", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Review not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Review not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Review not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/review__get_404_other_account.json b/tests/fixtures/parity/expected/review__get_404_other_account.json new file mode 100644 index 0000000..528e617 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_404_other_account.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Review not found.", + "code": "not_found", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Review not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Review not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Review not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/review__get_410_purged.json b/tests/fixtures/parity/expected/review__get_410_purged.json new file mode 100644 index 0000000..57658a2 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_410_purged.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "This review is no longer available: its account removes content after a set period.", + "code": "purged", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Its account's retention period removed it. A certificate issued for it is still available.", + "friendly_text": "This review is no longer available: its account removes content after a set period.\n Fix: Its account's retention period removed it. A certificate issued for it is still available.", + "message": "This review is no longer available: its account removes content after a set period.", + "payload_json": { + "error": { + "code": "gone", + "fix": "Its account's retention period removed it. A certificate issued for it is still available.", + "message": "This review is no longer available: its account removes content after a set period.", + "status": 410 + } + }, + "purged_at": "2026-10-01T09:07:00.123456Z", + "request_id": "", + "status_code": 410, + "type": "LenzGoneError" + } +} diff --git a/tests/fixtures/parity/expected/review__get_422_unknown_view.json b/tests/fixtures/parity/expected/review__get_422_unknown_view.json new file mode 100644 index 0000000..7d2cc01 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_422_unknown_view.json @@ -0,0 +1,30 @@ +{ + "error": { + "cause": "view: use full or issues.", + "code": "validation_error", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "query", + "view" + ], + "msg": "view: use full or issues." + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "view: use full or issues.\n Fix: Check the request body against the OpenAPI spec.", + "message": "view: use full or issues.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "view: use full or issues.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__get_assessing.json b/tests/fixtures/parity/expected/review__get_assessing.json new file mode 100644 index 0000000..d03a95c --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_assessing.json @@ -0,0 +1,211 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "running", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": null, + "index": 0, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "running", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": null, + "index": 1, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 10, + "review_id": "d6b2bd72", + "status": "assessing", + "summary": { + "assessments": { + "completed": 0, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "running", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": null, + "index": 0, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "running", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": null, + "index": 1, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 10, + "review_id": "d6b2bd72", + "status": "assessing", + "summary": { + "assessments": { + "completed": 0, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: assessing — 2 claims: 2 not checked · 2 credits charged\n\n[1/2] The EU AI Act took effect in March 2024.\n ? · quick check\n\n[2/2] Water boils at 100 C at sea level.\n ? · quick check\n", + "render_issues": "Review d6b2bd72: assessing — 2 claims: 2 not checked · 2 credits charged\n\nNo issues.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='assessing', outcome=None, created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=2, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=0, failed=0), verifications=None, issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=2), poll_after_seconds=10, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=None, assessment=ReviewAssessment(status='running', verdict=None, confidence=None, rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=None, verification=None, suggested_edits=None), ReviewClaim(index=1, claim='Water boils at 100 C at sea level.', positions=None, result=None, assessment=ReviewAssessment(status='running', verdict=None, confidence=None, rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=None, verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_assessment_rows_full_fields.json b/tests/fixtures/parity/expected/review__get_assessment_rows_full_fields.json new file mode 100644 index 0000000..04bcf67 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_assessment_rows_full_fields.json @@ -0,0 +1,331 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": "One reviewer read the claim as about the entry into force.", + "error_code": null, + "failure": null, + "hint": "This text holds more than one claim.", + "identified_claims": [ + "The EU AI Act took effect in 2024.", + "It took effect in March." + ], + "rationale": "Two reviewers found the date wrong.", + "status": "completed", + "suggested_rewrite": "The EU AI Act entered into force in August 2024.", + "verdict": "False", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "cap", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "assessment", + "verdict": "False" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": "timeout", + "failure": { + "docs_url": null, + "failure_class": "upstream_unavailable", + "failure_reason": "timeout", + "hint": "The check ran out of time. Retry it; nothing was charged.", + "retryable": true + }, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "failed", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": null, + "index": 1, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 1, + "failure": { + "docs_url": null, + "failure_class": "upstream_unavailable", + "failure_reason": "timeout", + "hint": "The check ran out of time. Retry it; nothing was charged.", + "retryable": true + }, + "stage": "assessment" + } + ], + "issues": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "cap", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": null, + "rationale": "Two reviewers found the date wrong.", + "source": "assessment", + "suggested_edits": null, + "suggested_rewrite": "The EU AI Act entered into force in August 2024.", + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": null, + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "incomplete", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 0, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 1 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 1, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": "One reviewer read the claim as about the entry into force.", + "error_code": null, + "failure": null, + "hint": "This text holds more than one claim.", + "identified_claims": [ + "The EU AI Act took effect in 2024.", + "It took effect in March." + ], + "rationale": "Two reviewers found the date wrong.", + "status": "completed", + "suggested_rewrite": "The EU AI Act entered into force in August 2024.", + "verdict": "False", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "cap", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "assessment", + "verdict": "False" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": "timeout", + "failure": { + "docs_url": null, + "failure_class": "upstream_unavailable", + "failure_reason": "timeout", + "hint": "The check ran out of time. Retry it; nothing was charged.", + "retryable": true + }, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "failed", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": null, + "index": 1, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 1, + "failure": { + "docs_url": null, + "failure_class": "upstream_unavailable", + "failure_reason": "timeout", + "hint": "The check ran out of time. Retry it; nothing was charged.", + "retryable": true + }, + "stage": "assessment" + } + ], + "issues": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "cap", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": null, + "rationale": "Two reviewers found the date wrong.", + "source": "assessment", + "suggested_edits": null, + "suggested_rewrite": "The EU AI Act entered into force in August 2024.", + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": null, + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "incomplete", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 0, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 1 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 1, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: incomplete — 2 claims: 1 issue, 1 failed · 2 credits charged\n\n[1/2] The EU AI Act took effect in March 2024.\n False (high) · quick check\n Two reviewers found the date wrong.\n Not deep-checked (cap).\n\n[2/2] The Eiffel Tower is in Berlin.\n Quick check failed: The check ran out of time. Retry it; nothing was charged.\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_issues": "Review d6b2bd72: incomplete — 2 claims: 1 issue, 1 failed · 2 credits charged\n\n[1/2] The EU AI Act took effect in March 2024.\n False (high) · quick check\n Two reviewers found the date wrong.\n Suggested rewrite: The EU AI Act entered into force in August 2024.\n Not deep-checked (cap).\n\n[2/2] The Eiffel Tower is in Berlin.\n Assessment failed: The check ran out of time. Retry it; nothing was charged.\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='incomplete', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=0, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=2, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=1), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=1, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=2), poll_after_seconds=None, issues=[ReviewIssue(claim_index=0, claim='The EU AI Act took effect in March 2024.', verified_claim=None, verdict='False', confidence='high', source='assessment', verification_id=None, verification_status=None, verification_url=None, url=None, escalation=Escalation(matched_rules=['verdict'], disposition='cap'), key_finding=None, rationale='Two reviewers found the date wrong.', suggested_rewrite='The EU AI Act entered into force in August 2024.', failure=None, suggested_edits=None)], failures=[ReviewFailure(claim_index=1, claim='The Eiffel Tower is in Berlin.', stage='assessment', failure=FailureBlock(failure_reason='timeout', failure_class='upstream_unavailable', retryable=True, hint='The check ran out of time. Retry it; nothing was charged.', docs_url=None))], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='False', confidence='high', source='assessment', is_issue=True), assessment=ReviewAssessment(status='completed', verdict='False', confidence='high', rationale='Two reviewers found the date wrong.', dissent='One reviewer read the claim as about the entry into force.', verification_url=None, error_code=None, identified_claims=['The EU AI Act took effect in 2024.', 'It took effect in March.'], hint='This text holds more than one claim.', suggested_rewrite='The EU AI Act entered into force in August 2024.', failure=None), escalation=Escalation(matched_rules=['verdict'], disposition='cap'), verification=None, suggested_edits=None), ReviewClaim(index=1, claim='The Eiffel Tower is in Berlin.', positions=None, result=None, assessment=ReviewAssessment(status='failed', verdict=None, confidence=None, rationale=None, dissent=None, verification_url=None, error_code='timeout', identified_claims=[], hint=None, suggested_rewrite=None, failure=FailureBlock(failure_reason='timeout', failure_class='upstream_unavailable', retryable=True, hint='The check ran out of time. Retry it; nothing was charged.', docs_url=None)), escalation=None, verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_clean.json b/tests/fixtures/parity/expected/review__get_citations_clean.json new file mode 100644 index 0000000..403f0e1 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_clean.json @@ -0,0 +1,357 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 3 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 3 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 3 credits charged\n\n[1/1] The EU AI Act took effect in March 2024.\n True (high) · quick check\n\n2 sources cited in your draft\n2 checked.\n", + "render_issues": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 3 credits charged\n\nNo issues.\n\n2 sources cited in your draft\n2 checked.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=20, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=2, citations_selected=2, citation_limit=20, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=2, unchecked=0, failed=0), citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=3), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[ReviewCitation(index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None)), ReviewCitation(index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=Position(start=111, end=178, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.org/statement', page_published_date=None, page_language='en', source_url='https://example.org/statement', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_failed_and_unchecked.json b/tests/fixtures/parity/expected/review__get_citations_failed_and_unchecked.json new file mode 100644 index 0000000..b12ff7d --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_failed_and_unchecked.json @@ -0,0 +1,389 @@ +{ + "dump": { + "citation_failures": [ + { + "citation_index": 0, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#internal", + "failure_class": "internal", + "failure_reason": "internal", + "hint": "The check failed on our side. Try again later.", + "retryable": false + }, + "reference": "a report from the ministry" + } + ], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#internal", + "failure_class": "internal", + "failure_reason": "internal", + "hint": "The check failed on our side. Try again later.", + "retryable": false + }, + "hint": "The check failed on our side. Try again later.", + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "failed", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": null, + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "unchecked", + "unchecked_reason": "no_text" + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "unchecked", + "is_issue": false, + "source": null + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "incomplete", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 0, + "failed": 1, + "unchecked": 1 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [ + { + "citation_index": 0, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#internal", + "failure_class": "internal", + "failure_reason": "internal", + "hint": "The check failed on our side. Try again later.", + "retryable": false + }, + "reference": "a report from the ministry" + } + ], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#internal", + "failure_class": "internal", + "failure_reason": "internal", + "hint": "The check failed on our side. Try again later.", + "retryable": false + }, + "hint": "The check failed on our side. Try again later.", + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "failed", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": null, + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "unchecked", + "unchecked_reason": "no_text" + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "unchecked", + "is_issue": false, + "source": null + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "incomplete", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 0, + "failed": 1, + "unchecked": 1 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: incomplete — 1 claim: 1 true or mostly true · 1 credit charged\n\n[1/1] The EU AI Act took effect in March 2024.\n True (high) · quick check\n\n2 sources cited in your draft\n2 could not be checked.\n\n[source 1/2] Could not be checked this time.\n https://example.gov/report-2024\n The check failed on our side. Try again later.\n\nCheck these by hand (Lenz could not check them)\n[source 2/2] The page gave no text to read.\n https://example.org/statement\n", + "render_issues": "Review d6b2bd72: incomplete — 1 claim: 1 true or mostly true · 1 credit charged\n\n2 sources cited in your draft\n2 could not be checked.\n\n[source 1/2] Could not be checked this time.\n https://example.gov/report-2024\n The check failed on our side. Try again later.\n\nCheck these by hand (Lenz could not check them)\n[source 2/2] The page gave no text to read.\n https://example.org/statement\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='incomplete', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=20, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=2, citations_selected=2, citation_limit=20, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=0, unchecked=1, failed=1), citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=1), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[ReviewCitationFailure(citation_index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, failure=FailureBlock(failure_reason='internal', failure_class='internal', retryable=False, hint='The check failed on our side. Try again later.', docs_url='https://lenz.io/docs/errors#internal'))], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[ReviewCitation(index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), result=None, check=ReviewCitationCheck(status='failed', page_read=None, page_title=None, page_published_date=None, page_language=None, source_url=None, source_version=None, support=None, snippet=None, rationale=None, quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint='The check failed on our side. Try again later.', failure=FailureBlock(failure_reason='internal', failure_class='internal', retryable=False, hint='The check failed on our side. Try again later.', docs_url='https://lenz.io/docs/errors#internal'))), ReviewCitation(index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=Position(start=111, end=178, text=None), result=ReviewCitationResult(finding='unchecked', source=None, is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.org/statement', page_published_date=None, page_language='en', source_url='https://example.org/statement', source_version=None, support='unchecked', snippet=None, rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason='no_text', hint=None, failure=None))])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_issue_full.json b/tests/fixtures/parity/expected/review__get_citations_issue_full.json new file mode 100644 index 0000000..558e623 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_issue_full.json @@ -0,0 +1,401 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [ + { + "citation_index": 0, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": null, + "finding": "contradicted", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "rationale": "The page states it.", + "reference": "a report from the ministry", + "snippet": "The source says so.", + "source": "support", + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + } + ], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "contradicted", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "contradicted", + "is_issue": true, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 3 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "issues_found", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 1, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [ + { + "citation_index": 0, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": null, + "finding": "contradicted", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "rationale": "The page states it.", + "reference": "a report from the ministry", + "snippet": "The source says so.", + "source": "support", + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + } + ], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "contradicted", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "contradicted", + "is_issue": true, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 3 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "issues_found", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 1, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 1, + "render": "Review d6b2bd72: issues found — 1 claim: 1 true or mostly true · 3 credits charged\n\n[1/1] The EU AI Act took effect in March 2024.\n True (high) · quick check\n\n2 sources cited in your draft\n2 checked, 1 with a problem.\n\n[source 1/2] Contradicted\n Unemployment fell to 4.1% in 2024, according to a report from the ministry.\n https://example.gov/report-2024\n The source says:\n “The source says so.”\n Reviewer's note: The page states it.\n\nA reviewer's note is reasoning, not a checked source; the quoted passage is from the page.\n", + "render_issues": "Review d6b2bd72: issues found — 1 claim: 1 true or mostly true · 3 credits charged\n\n2 sources cited in your draft\n2 checked, 1 with a problem.\n\n[source 1/2] Contradicted\n Unemployment fell to 4.1% in 2024, according to a report from the ministry.\n https://example.gov/report-2024\n The source says:\n “The source says so.”\n Reviewer's note: The page states it.\n\nA reviewer's note is reasoning, not a checked source; the quoted passage is from the page.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='issues_found', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=20, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=2, citations_selected=2, citation_limit=20, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=2, unchecked=0, failed=0), citation_issues=1, citations_skipped=None), credits=ReviewCredits(charged=3), poll_after_seconds=None, issues=[], failures=[], citation_issues=[ReviewCitationIssue(citation_index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), finding='contradicted', source='support', snippet='The source says so.', rationale='The page states it.', missing_quote=None, metadata_differences=[], page_title='Page at https://example.gov/report-2024', failure=None)], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[ReviewCitation(index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), result=ReviewCitationResult(finding='contradicted', source='support', is_issue=True), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='contradicted', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None)), ReviewCitation(index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=Position(start=111, end=178, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.org/statement', page_published_date=None, page_language='en', source_url='https://example.org/statement', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_issue_issues_view.json b/tests/fixtures/parity/expected/review__get_citations_issue_issues_view.json new file mode 100644 index 0000000..99f5e5f --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_issue_issues_view.json @@ -0,0 +1,179 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [ + { + "citation_index": 0, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": null, + "finding": "contradicted", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "rationale": "The page states it.", + "reference": "a report from the ministry", + "snippet": "The source says so.", + "source": "support", + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + } + ], + "citations": [], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 3 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "issues_found", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 1, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "issues" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [ + { + "citation_index": 0, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": null, + "finding": "contradicted", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "rationale": "The page states it.", + "reference": "a report from the ministry", + "snippet": "The source says so.", + "source": "support", + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 3 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "issues_found", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 1, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "issues" + }, + "exit_code": 1, + "render": "Review d6b2bd72: issues found — 1 claim: 1 not checked · 3 credits charged\n\n2 sources cited in your draft\n2 checked, 1 with a problem.\n\n[source 1/2] Contradicted\n Unemployment fell to 4.1% in 2024, according to a report from the ministry.\n https://example.gov/report-2024\n The source says:\n “The source says so.”\n Reviewer's note: The page states it.\n\nA reviewer's note is reasoning, not a checked source; the quoted passage is from the page.\n", + "render_issues": "Review d6b2bd72: issues found — 1 claim: 1 not checked · 3 credits charged\n\n2 sources cited in your draft\n2 checked, 1 with a problem.\n\n[source 1/2] Contradicted\n Unemployment fell to 4.1% in 2024, according to a report from the ministry.\n https://example.gov/report-2024\n The source says:\n “The source says so.”\n Reviewer's note: The page states it.\n\nA reviewer's note is reasoning, not a checked source; the quoted passage is from the page.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='issues', status='completed', outcome='issues_found', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=20, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=2, citations_selected=2, citation_limit=20, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=2, unchecked=0, failed=0), citation_issues=1, citations_skipped=None), credits=ReviewCredits(charged=3), poll_after_seconds=None, issues=[], failures=[], citation_issues=[ReviewCitationIssue(citation_index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), finding='contradicted', source='support', snippet='The source says so.', rationale='The page states it.', missing_quote=None, metadata_differences=[], page_title='Page at https://example.gov/report-2024', failure=None)], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_limit_exactly_at_limit.json b/tests/fixtures/parity/expected/review__get_citations_limit_exactly_at_limit.json new file mode 100644 index 0000000..d8c2878 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_limit_exactly_at_limit.json @@ -0,0 +1,357 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 3 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 2, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 3 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 2, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 3 credits charged\n\n[1/1] The EU AI Act took effect in March 2024.\n True (high) · quick check\n\n2 sources cited in your draft\n2 checked.\n", + "render_issues": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 3 credits charged\n\nNo issues.\n\n2 sources cited in your draft\n2 checked.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=2, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=2, citations_selected=2, citation_limit=2, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=2, unchecked=0, failed=0), citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=3), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[ReviewCitation(index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None)), ReviewCitation(index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=Position(start=111, end=178, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.org/statement', page_published_date=None, page_language='en', source_url='https://example.org/statement', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_limit_reached.json b/tests/fixtures/parity/expected/review__get_citations_limit_reached.json new file mode 100644 index 0000000..8a1c54a --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_limit_reached.json @@ -0,0 +1,305 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [ + { + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "reference": "a statement", + "sentence": "The agency said so in a statement." + } + ], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 1, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 1, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 1, + "citation_limit_reached": true, + "citations_found": 2, + "citations_selected": 1, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [ + { + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "reference": "a statement", + "sentence": "The agency said so in a statement." + } + ], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 1, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 1, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 1, + "citation_limit_reached": true, + "citations_found": 2, + "citations_selected": 1, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 2 credits charged\n\n[1/1] The EU AI Act took effect in March 2024.\n True (high) · quick check\n\n2 sources cited in your draft\n1 checked.\n1 more was not checked: one check covers 1.\n\n1 more citation was found but not checked.\n", + "render_issues": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 2 credits charged\n\nNo issues.\n\n2 sources cited in your draft\n1 checked.\n1 more was not checked: one check covers 1.\n\n1 more citation was found but not checked.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=1, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=2, citations_selected=1, citation_limit=1, citation_limit_reached=True, citation_checks=ReviewCitationCheckCounts(checked=1, unchecked=0, failed=0), citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=2), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[ReviewMoreCitation(index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, sentence='The agency said so in a statement.', position=Position(start=111, end=178, text=None))], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[ReviewCitation(index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_no_claim_but_citations.json b/tests/fixtures/parity/expected/review__get_citations_no_claim_but_citations.json new file mode 100644 index 0000000..d2bf7e8 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_no_claim_but_citations.json @@ -0,0 +1,295 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 0, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 0, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 0, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 0, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — no claims checked · 2 credits charged\n\n2 sources cited in your draft\n2 checked.\n", + "render_issues": "Review d6b2bd72: clean — no claims checked · 2 credits charged\n\nNo issues.\n\n2 sources cited in your draft\n2 checked.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=20, suggest_edits=False), summary=ReviewSummary(claims_selected=0, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=0, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=2, citations_selected=2, citation_limit=20, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=2, unchecked=0, failed=0), citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=2), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[], citations=[ReviewCitation(index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None)), ReviewCitation(index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=Position(start=111, end=178, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.org/statement', page_published_date=None, page_language='en', source_url='https://example.org/statement', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_no_claim_no_citation.json b/tests/fixtures/parity/expected/review__get_citations_no_claim_no_citation.json new file mode 100644 index 0000000..74da78d --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_no_claim_no_citation.json @@ -0,0 +1,127 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "failure_class": "invalid_input", + "failure_reason": "no_claim", + "hint": "No factual statement that can be checked against evidence was found in the input. Send one factual claim, or run the text through /extract to enumerate its claims.", + "retryable": false + }, + "failures": [], + "issues": [], + "language": "en", + "more_citations": null, + "more_claim_locations": null, + "more_claims": null, + "outcome": "unchecked", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "failed", + "summary": { + "assessments": null, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": null, + "claims_selected": null, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "failure_class": "invalid_input", + "failure_reason": "no_claim", + "hint": "No factual statement that can be checked against evidence was found in the input. Send one factual claim, or run the text through /extract to enumerate its claims.", + "retryable": false + }, + "failures": [], + "issues": [], + "language": "en", + "more_citations": null, + "more_claim_locations": null, + "more_claims": null, + "outcome": "unchecked", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "failed", + "summary": { + "assessments": null, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": null, + "claims_selected": null, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: unchecked — no claims checked · 0 credits charged\nFailed: No factual statement that can be checked against evidence was found in the input. Send one factual claim, or run\nthe text through /extract to enumerate its claims.\n", + "render_issues": "Review d6b2bd72: unchecked — no claims checked · 0 credits charged\nFailed: No factual statement that can be checked against evidence was found in the input. Send one factual claim, or run\nthe text through /extract to enumerate its claims.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='failed', outcome='unchecked', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=20, suggest_edits=False), summary=ReviewSummary(claims_selected=None, claim_limit=20, claim_limit_reached=None, input_truncated=False, assessments=None, verifications=None, issues=0, citations_found=None, citations_selected=None, citation_limit=20, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=0), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=None, more_claim_locations=None, more_citations=None, failure=FailureBlock(failure_reason='no_claim', failure_class='invalid_input', retryable=False, hint='No factual statement that can be checked against evidence was found in the input. Send one factual claim, or run the text through /extract to enumerate its claims.', docs_url='https://lenz.io/docs/errors#invalid-input'), claims=[], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_not_asked.json b/tests/fixtures/parity/expected/review__get_citations_not_asked.json new file mode 100644 index 0000000..b0e08d1 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_not_asked.json @@ -0,0 +1,191 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 1 credit charged\n\n[1/1] The EU AI Act took effect in March 2024.\n True (high) · quick check\n", + "render_issues": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 1 credit charged\n\nNo issues.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=1), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_only.json b/tests/fixtures/parity/expected/review__get_citations_only.json new file mode 100644 index 0000000..7b79f80 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_only.json @@ -0,0 +1,309 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "positions": null + } + ], + "more_claims": [ + "The EU AI Act took effect in March 2024." + ], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 0, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 0, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 0, + "claim_limit_reached": true, + "claims_selected": 0, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "positions": null + } + ], + "more_claims": [ + "The EU AI Act took effect in March 2024." + ], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 0, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 0, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 0, + "claim_limit_reached": true, + "claims_selected": 0, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — no claims checked · 2 credits charged\n\n2 sources cited in your draft\n2 checked.\n\n1 more claim was found but not checked.\n", + "render_issues": "Review d6b2bd72: clean — no claims checked · 2 credits charged\n\nNo issues.\n\n2 sources cited in your draft\n2 checked.\n\n1 more claim was found but not checked.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=0, max_verifications=5, depth='standard', max_citations=20, suggest_edits=False), summary=ReviewSummary(claims_selected=0, claim_limit=0, claim_limit_reached=True, input_truncated=False, assessments=ReviewAssessmentCounts(completed=0, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=2, citations_selected=2, citation_limit=20, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=2, unchecked=0, failed=0), citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=2), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=['The EU AI Act took effect in March 2024.'], more_claim_locations=[ClaimLocation(claim='The EU AI Act took effect in March 2024.', positions=None)], more_citations=[], failure=None, claims=[], citations=[ReviewCitation(index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None)), ReviewCitation(index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=Position(start=111, end=178, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.org/statement', page_published_date=None, page_language='en', source_url='https://example.org/statement', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_partly_supported.json b/tests/fixtures/parity/expected/review__get_citations_partly_supported.json new file mode 100644 index 0000000..144016b --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_partly_supported.json @@ -0,0 +1,357 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "partly_supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "partly_supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 3 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "partly_supported", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": { + "end": 110, + "start": 0, + "text": null + }, + "quotes": [], + "reference": "a report from the ministry", + "result": { + "finding": "partly_supported", + "is_issue": false, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": { + "end": 178, + "start": 111, + "text": null + }, + "quotes": [], + "reference": "a statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 3 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 3 credits charged\n\n[1/1] The EU AI Act took effect in March 2024.\n True (high) · quick check\n\n2 sources cited in your draft\n2 checked.\n", + "render_issues": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 3 credits charged\n\nNo issues.\n\n2 sources cited in your draft\n2 checked.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=20, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=2, citations_selected=2, citation_limit=20, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=2, unchecked=0, failed=0), citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=3), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[ReviewCitation(index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement='Unemployment fell to 4.1% in 2024, according to a report from the ministry.', quotes=[], position=Position(start=0, end=110, text=None), result=ReviewCitationResult(finding='partly_supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.gov/report-2024', page_published_date=None, page_language='en', source_url='https://example.gov/report-2024', source_version=None, support='partly_supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None)), ReviewCitation(index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, statement='The agency said so in a statement.', quotes=[], position=Position(start=111, end=178, text=None), result=ReviewCitationResult(finding='supported', source='support', is_issue=False), check=ReviewCitationCheck(status='completed', page_read='full', page_title='Page at https://example.org/statement', page_published_date=None, page_language='en', source_url='https://example.org/statement', source_version=None, support='supported', snippet='The source says so.', rationale='The page states it.', quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_running.json b/tests/fixtures/parity/expected/review__get_citations_running.json new file mode 100644 index 0000000..acc4c84 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_running.json @@ -0,0 +1,325 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "pending", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "a report from the ministry", + "result": null, + "statement": null + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "pending", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "a statement", + "result": null, + "statement": null + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 15, + "review_id": "d6b2bd72", + "status": "verifying", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 0, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "pending", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "a report from the ministry", + "result": null, + "statement": null + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": null, + "page_published_date": null, + "page_read": null, + "page_title": null, + "quote": null, + "rationale": null, + "registered": null, + "snippet": null, + "source_url": null, + "source_version": null, + "status": "pending", + "support": null, + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "a statement", + "result": null, + "statement": null + } + ], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 15, + "review_id": "d6b2bd72", + "status": "verifying", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": { + "checked": 0, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: verifying — 1 claim: 1 true or mostly true · 1 credit charged\n\n[1/1] The EU AI Act took effect in March 2024.\n True (high) · quick check\n\n2 sources cited in your draft\nLenz checks each one: does the source say what your draft says it does.\n", + "render_issues": "Review d6b2bd72: verifying — 1 claim: 1 true or mostly true · 1 credit charged\n\nNo issues.\n\n2 sources cited in your draft\nLenz checks each one: does the source say what your draft says it does.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='verifying', outcome=None, created_at='2026-10-01T09:07:00.123456Z', completed_at=None, language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=20, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=2, citations_selected=2, citation_limit=20, citation_limit_reached=False, citation_checks=ReviewCitationCheckCounts(checked=0, unchecked=0, failed=0), citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=1), poll_after_seconds=15, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[ReviewCitation(index=0, reference='a report from the ministry', cited_url='https://example.gov/report-2024', doi=None, statement=None, quotes=[], position=None, result=None, check=ReviewCitationCheck(status='pending', page_read=None, page_title=None, page_published_date=None, page_language=None, source_url=None, source_version=None, support=None, snippet=None, rationale=None, quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None)), ReviewCitation(index=1, reference='a statement', cited_url='https://example.org/statement', doi=None, statement=None, quotes=[], position=None, result=None, check=ReviewCitationCheck(status='pending', page_read=None, page_title=None, page_published_date=None, page_language=None, source_url=None, source_version=None, support=None, snippet=None, rationale=None, quote=None, missing_quote=None, doi_registered=None, metadata=None, metadata_differences=[], registered=None, unchecked_reason=None, hint=None, failure=None))])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_skipped_switched_off.json b/tests/fixtures/parity/expected/review__get_citations_skipped_switched_off.json new file mode 100644 index 0000000..bac0fa1 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_skipped_switched_off.json @@ -0,0 +1,191 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": "switched_off", + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": "switched_off", + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 1 credit charged\n\n[1/1] The EU AI Act took effect in March 2024.\n True (high) · quick check\n", + "render_issues": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 1 credit charged\n\nNo issues.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=20, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=None, citations_selected=None, citation_limit=20, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped='switched_off'), credits=ReviewCredits(charged=1), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_citations_skipped_url_input.json b/tests/fixtures/parity/expected/review__get_citations_skipped_url_input.json new file mode 100644 index 0000000..f74fcd2 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_citations_skipped_url_input.json @@ -0,0 +1,127 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": null, + "retryable": true + }, + "failures": [], + "issues": [], + "language": "en", + "more_citations": null, + "more_claim_locations": null, + "more_claims": null, + "outcome": "unchecked", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "failed", + "summary": { + "assessments": null, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": "url_input", + "claim_limit": 20, + "claim_limit_reached": null, + "claims_selected": null, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": null, + "retryable": true + }, + "failures": [], + "issues": [], + "language": "en", + "more_citations": null, + "more_claim_locations": null, + "more_claims": null, + "outcome": "unchecked", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 20, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "failed", + "summary": { + "assessments": null, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": "url_input", + "claim_limit": 20, + "claim_limit_reached": null, + "claims_selected": null, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: unchecked — no claims checked · 0 credits charged\nFailed: upstream_unavailable\n\nSources on a linked page are not checked. Paste the page's text instead to check them.\n", + "render_issues": "Review d6b2bd72: unchecked — no claims checked · 0 credits charged\nFailed: upstream_unavailable\n\nSources on a linked page are not checked. Paste the page's text instead to check them.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='failed', outcome='unchecked', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=20, suggest_edits=False), summary=ReviewSummary(claims_selected=None, claim_limit=20, claim_limit_reached=None, input_truncated=False, assessments=None, verifications=None, issues=0, citations_found=None, citations_selected=None, citation_limit=20, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped='url_input'), credits=ReviewCredits(charged=0), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=None, more_claim_locations=None, more_citations=None, failure=FailureBlock(failure_reason='upstream_unavailable', failure_class='upstream_unavailable', retryable=True, hint=None, docs_url='https://lenz.io/docs/errors#upstream-unavailable'), claims=[], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_claim_limit_not_reached.json b/tests/fixtures/parity/expected/review__get_claim_limit_not_reached.json new file mode 100644 index 0000000..b544e5b --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_claim_limit_not_reached.json @@ -0,0 +1,251 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 3, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 3, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 3, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 3, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 2 claims: 2 true or mostly true · 2 credits charged\n\n[1/2] The EU AI Act took effect in March 2024.\n True (high) · quick check\n\n[2/2] Water boils at 100 C at sea level.\n True (high) · quick check\n", + "render_issues": "Review d6b2bd72: clean — 2 claims: 2 true or mostly true · 2 credits charged\n\nNo issues.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=3, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=2, claim_limit=3, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=2, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=2), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None), ReviewClaim(index=1, claim='Water boils at 100 C at sea level.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_claim_limit_reached_exact.json b/tests/fixtures/parity/expected/review__get_claim_limit_reached_exact.json new file mode 100644 index 0000000..d282376 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_claim_limit_reached_exact.json @@ -0,0 +1,251 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 2, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 2, + "claim_limit_reached": true, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 2, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 2, + "claim_limit_reached": true, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 2 claims: 2 true or mostly true · 2 credits charged\n\n[1/2] The EU AI Act took effect in March 2024.\n True (high) · quick check\n\n[2/2] Water boils at 100 C at sea level.\n True (high) · quick check\n", + "render_issues": "Review d6b2bd72: clean — 2 claims: 2 true or mostly true · 2 credits charged\n\nNo issues.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=2, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=2, claim_limit=2, claim_limit_reached=True, input_truncated=False, assessments=ReviewAssessmentCounts(completed=2, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=2), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None), ReviewClaim(index=1, claim='Water boils at 100 C at sea level.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_completed_assess_only.json b/tests/fixtures/parity/expected/review__get_completed_assess_only.json new file mode 100644 index 0000000..ffc8ab2 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_completed_assess_only.json @@ -0,0 +1,303 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "cap", + "matched_rules": [ + "verdict" + ] + }, + "index": 1, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "assessment", + "verdict": "False" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 1, + "confidence": "high", + "escalation": { + "disposition": "cap", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": null, + "rationale": null, + "source": "assessment", + "suggested_edits": null, + "suggested_rewrite": null, + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": null, + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "issues_found", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 0, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 1, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "cap", + "matched_rules": [ + "verdict" + ] + }, + "index": 1, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "assessment", + "verdict": "False" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 1, + "confidence": "high", + "escalation": { + "disposition": "cap", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": null, + "rationale": null, + "source": "assessment", + "suggested_edits": null, + "suggested_rewrite": null, + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": null, + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "issues_found", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 0, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 1, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 1, + "render": "Review d6b2bd72: issues found — 2 claims: 1 issue, 1 true or mostly true · 2 credits charged\n\n[1/2] The EU AI Act took effect in March 2024.\n True (high) · quick check\n\n[2/2] The Eiffel Tower is in Berlin.\n False (high) · quick check\n Not deep-checked (cap).\n", + "render_issues": "Review d6b2bd72: issues found — 2 claims: 1 issue, 1 true or mostly true · 2 credits charged\n\n[2/2] The Eiffel Tower is in Berlin.\n False (high) · quick check\n Not deep-checked (cap).\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='issues_found', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=0, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=2, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=2, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=1, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=2), poll_after_seconds=None, issues=[ReviewIssue(claim_index=1, claim='The Eiffel Tower is in Berlin.', verified_claim=None, verdict='False', confidence='high', source='assessment', verification_id=None, verification_status=None, verification_url=None, url=None, escalation=Escalation(matched_rules=['verdict'], disposition='cap'), key_finding=None, rationale=None, suggested_rewrite=None, failure=None, suggested_edits=None)], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None), ReviewClaim(index=1, claim='The Eiffel Tower is in Berlin.', positions=None, result=ReviewResult(verdict='False', confidence='high', source='assessment', is_issue=True), assessment=ReviewAssessment(status='completed', verdict='False', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=['verdict'], disposition='cap'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_completed_clean.json b/tests/fixtures/parity/expected/review__get_completed_clean.json new file mode 100644 index 0000000..9ff4a6b --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_completed_clean.json @@ -0,0 +1,251 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Paris is the capital of France.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Paris is the capital of France.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 2 claims: 2 true or mostly true · 2 credits charged\n\n[1/2] The EU AI Act took effect in March 2024.\n True (high) · quick check\n\n[2/2] Paris is the capital of France.\n True (high) · quick check\n", + "render_issues": "Review d6b2bd72: clean — 2 claims: 2 true or mostly true · 2 credits charged\n\nNo issues.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=2, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=2, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=2), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None), ReviewClaim(index=1, claim='Paris is the capital of France.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_completed_issues_all_verified.json b/tests/fixtures/parity/expected/review__get_completed_issues_all_verified.json new file mode 100644 index 0000000..80599b7 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_completed_issues_all_verified.json @@ -0,0 +1,513 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "medium", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "Mostly False", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "verification", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": "The EU AI Act took effect in March 2024.", + "confidence": "high", + "content_status": "available", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "Summary for The EU AI Act took effect in March 2024.", + "failure": null, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "language": "en", + "lenz_score": 2, + "modified_at": null, + "status": "completed", + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "visibility": "private", + "warnings": [ + "w1" + ] + } + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 1, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "verification", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "high", + "content_status": "available", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "language": "en", + "lenz_score": 2, + "modified_at": null, + "status": "completed", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "url": "https://lenz.io/c/the-earth-is-round-4d44dfaf", + "verdict": "False", + "verification_id": "4d44dfaf", + "verification_url": "https://lenz.io/api/v1/verifications/4d44dfaf", + "visibility": "private", + "warnings": [ + "w1" + ] + } + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Paris is the capital of France.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 2, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 23 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "rationale": null, + "source": "verification", + "suggested_edits": null, + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + }, + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 1, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "source": "verification", + "suggested_edits": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "url": "https://lenz.io/c/the-earth-is-round-4d44dfaf", + "verdict": "False", + "verification_id": "4d44dfaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/4d44dfaf", + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "issues_found", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 3, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 3, + "input_truncated": false, + "issues": 2, + "verifications": { + "completed": 2, + "failed": 0, + "planned": 2 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "medium", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "Mostly False", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "verification", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": "The EU AI Act took effect in March 2024.", + "confidence": "high", + "content_status": "available", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "Summary for The EU AI Act took effect in March 2024.", + "failure": null, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "language": "en", + "lenz_score": 2, + "modified_at": null, + "status": "completed", + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "visibility": "private", + "warnings": [ + "w1" + ] + } + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 1, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "verification", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "high", + "content_status": "available", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "language": "en", + "lenz_score": 2, + "modified_at": null, + "status": "completed", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "url": "https://lenz.io/c/the-earth-is-round-4d44dfaf", + "verdict": "False", + "verification_id": "4d44dfaf", + "verification_url": "https://lenz.io/api/v1/verifications/4d44dfaf", + "visibility": "private", + "warnings": [ + "w1" + ] + } + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Paris is the capital of France.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 2, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 23 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "rationale": null, + "source": "verification", + "suggested_edits": null, + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + }, + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 1, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "source": "verification", + "suggested_edits": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "url": "https://lenz.io/c/the-earth-is-round-4d44dfaf", + "verdict": "False", + "verification_id": "4d44dfaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/4d44dfaf", + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "issues_found", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 3, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 3, + "input_truncated": false, + "issues": 2, + "verifications": { + "completed": 2, + "failed": 0, + "planned": 2 + } + }, + "view": "full" + }, + "exit_code": 1, + "render": "Review d6b2bd72: issues found — 3 claims: 2 issues, 1 true or mostly true · 2 of 2 deep-checked · 23 credits charged\n\n[1/3] The EU AI Act took effect in March 2024.\n False (high) · deep check\n Finding for The EU AI Act took effect in March 2024.\n Suggested rewrite: Fixed: The EU AI Act took effect in March 2024.\n https://lenz.io/c/the-earth-is-round-68ca4aaf\n\n[2/3] The Eiffel Tower is in Berlin.\n False (high) · deep check\n Finding for The Eiffel Tower is in Berlin.\n Suggested rewrite: Fixed: The Eiffel Tower is in Berlin.\n https://lenz.io/c/the-earth-is-round-4d44dfaf\n\n[3/3] Paris is the capital of France.\n True (high) · quick check\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_issues": "Review d6b2bd72: issues found — 3 claims: 2 issues, 1 true or mostly true · 2 of 2 deep-checked · 23 credits charged\n\n[1/3] The EU AI Act took effect in March 2024.\n False (high) · deep check\n Finding for The EU AI Act took effect in March 2024.\n Suggested rewrite: Fixed: The EU AI Act took effect in March 2024.\n https://lenz.io/c/the-earth-is-round-68ca4aaf\n\n[2/3] The Eiffel Tower is in Berlin.\n False (high) · deep check\n Finding for The Eiffel Tower is in Berlin.\n Suggested rewrite: Fixed: The Eiffel Tower is in Berlin.\n https://lenz.io/c/the-earth-is-round-4d44dfaf\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='issues_found', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=3, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=3, failed=0), verifications=ReviewVerificationCounts(planned=2, completed=2, failed=0), issues=2, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=23), poll_after_seconds=None, issues=[ReviewIssue(claim_index=0, claim='The EU AI Act took effect in March 2024.', verified_claim=None, verdict='False', confidence='high', source='verification', verification_id='68ca4aaf', verification_status='completed', verification_url='https://lenz.io/api/v1/verifications/68ca4aaf', url='https://lenz.io/c/the-earth-is-round-68ca4aaf', escalation=Escalation(matched_rules=['verdict'], disposition='planned'), key_finding='Finding for The EU AI Act took effect in March 2024.', rationale=None, suggested_rewrite='Fixed: The EU AI Act took effect in March 2024.', failure=None, suggested_edits=None), ReviewIssue(claim_index=1, claim='The Eiffel Tower is in Berlin.', verified_claim=None, verdict='False', confidence='high', source='verification', verification_id='4d44dfaf', verification_status='completed', verification_url='https://lenz.io/api/v1/verifications/4d44dfaf', url='https://lenz.io/c/the-earth-is-round-4d44dfaf', escalation=Escalation(matched_rules=['verdict'], disposition='planned'), key_finding='Finding for The Eiffel Tower is in Berlin.', rationale=None, suggested_rewrite='Fixed: The Eiffel Tower is in Berlin.', failure=None, suggested_edits=None)], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='False', confidence='high', source='verification', is_issue=True), assessment=ReviewAssessment(status='completed', verdict='Mostly False', confidence='medium', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=['verdict'], disposition='planned'), verification=ReviewVerification(status='completed', content_status='available', verification_id='68ca4aaf', task_id='7cff18da2d979d6370e54a160be121ad', claim='The EU AI Act took effect in March 2024.', language='en', visibility='private', depth='standard', domain='', entities=[], verdict='False', confidence='high', lenz_score=2, key_finding='Finding for The EU AI Act took effect in March 2024.', executive_summary='Summary for The EU AI Act took effect in March 2024.', suggested_rewrite='Fixed: The EU AI Act took effect in March 2024.', warnings=['w1'], created_at='2026-10-01T09:14:00.123456+00:00', modified_at=None, verification_url='https://lenz.io/api/v1/verifications/68ca4aaf', url='https://lenz.io/c/the-earth-is-round-68ca4aaf', failure=None), suggested_edits=None), ReviewClaim(index=1, claim='The Eiffel Tower is in Berlin.', positions=None, result=ReviewResult(verdict='False', confidence='high', source='verification', is_issue=True), assessment=ReviewAssessment(status='completed', verdict='False', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=['verdict'], disposition='planned'), verification=ReviewVerification(status='completed', content_status='available', verification_id='4d44dfaf', task_id='0b92b443eb69b9c71434fdc64f2ca8be', claim='The Eiffel Tower is in Berlin.', language='en', visibility='private', depth='standard', domain='', entities=[], verdict='False', confidence='high', lenz_score=2, key_finding='Finding for The Eiffel Tower is in Berlin.', executive_summary='Summary for The Eiffel Tower is in Berlin.', suggested_rewrite='Fixed: The Eiffel Tower is in Berlin.', warnings=['w1'], created_at='2026-10-01T09:14:00.123456+00:00', modified_at=None, verification_url='https://lenz.io/api/v1/verifications/4d44dfaf', url='https://lenz.io/c/the-earth-is-round-4d44dfaf', failure=None), suggested_edits=None), ReviewClaim(index=2, claim='Paris is the capital of France.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_completed_issues_full.json b/tests/fixtures/parity/expected/review__get_completed_issues_full.json new file mode 100644 index 0000000..58214d0 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_completed_issues_full.json @@ -0,0 +1,615 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "medium", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "Mostly False", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "verification", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": "The EU AI Act took effect in March 2024.", + "confidence": "high", + "content_status": "available", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "Summary for The EU AI Act took effect in March 2024.", + "failure": null, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "language": "en", + "lenz_score": 2, + "modified_at": null, + "status": "completed", + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "visibility": "private", + "warnings": [ + "w1" + ] + } + }, + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": "upstream_unavailable", + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "failed", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": null, + "index": 1, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 2, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "assessment", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": null, + "confidence": null, + "content_status": "available", + "created_at": null, + "depth": null, + "domain": null, + "entities": [], + "executive_summary": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence", + "failure_class": "insufficient_evidence", + "failure_reason": "research_empty", + "hint": null, + "retryable": false + }, + "key_finding": null, + "language": null, + "lenz_score": null, + "modified_at": null, + "status": "failed", + "suggested_rewrite": null, + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "url": null, + "verdict": null, + "verification_id": null, + "verification_url": null, + "visibility": null, + "warnings": [] + } + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Paris is the capital of France.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 3, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 13 + }, + "failure": null, + "failures": [ + { + "claim": "Water boils at 100 C at sea level.", + "claim_index": 1, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "stage": "assessment" + } + ], + "issues": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "rationale": null, + "source": "verification", + "suggested_edits": null, + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + }, + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 2, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence", + "failure_class": "insufficient_evidence", + "failure_reason": "research_empty", + "hint": null, + "retryable": false + }, + "key_finding": null, + "rationale": null, + "source": "assessment", + "suggested_edits": null, + "suggested_rewrite": null, + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": "failed", + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "incomplete", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 3, + "failed": 1 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 4, + "input_truncated": false, + "issues": 2, + "verifications": { + "completed": 1, + "failed": 1, + "planned": 2 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "medium", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "Mostly False", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "verification", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": "The EU AI Act took effect in March 2024.", + "confidence": "high", + "content_status": "available", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "Summary for The EU AI Act took effect in March 2024.", + "failure": null, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "language": "en", + "lenz_score": 2, + "modified_at": null, + "status": "completed", + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "visibility": "private", + "warnings": [ + "w1" + ] + } + }, + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": "upstream_unavailable", + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "failed", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": null, + "index": 1, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 2, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "assessment", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": null, + "confidence": null, + "content_status": "available", + "created_at": null, + "depth": null, + "domain": null, + "entities": [], + "executive_summary": null, + "failure": { + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence", + "failure_class": "insufficient_evidence", + "failure_reason": "research_empty", + "hint": null, + "retryable": false + }, + "key_finding": null, + "language": null, + "lenz_score": null, + "modified_at": null, + "status": "failed", + "suggested_rewrite": null, + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "url": null, + "verdict": null, + "verification_id": null, + "verification_url": null, + "visibility": null, + "warnings": [] + } + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Paris is the capital of France.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 3, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 13 + }, + "failure": null, + "failures": [ + { + "claim": "Water boils at 100 C at sea level.", + "claim_index": 1, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "stage": "assessment" + } + ], + "issues": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "rationale": null, + "source": "verification", + "suggested_edits": null, + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + }, + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 2, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence", + "failure_class": "insufficient_evidence", + "failure_reason": "research_empty", + "hint": null, + "retryable": false + }, + "key_finding": null, + "rationale": null, + "source": "assessment", + "suggested_edits": null, + "suggested_rewrite": null, + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": "failed", + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "incomplete", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 3, + "failed": 1 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 4, + "input_truncated": false, + "issues": 2, + "verifications": { + "completed": 1, + "failed": 1, + "planned": 2 + } + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: incomplete — 4 claims: 2 issues, 1 true or mostly true, 1 failed · 1 of 2 deep-checked · 13 credits \ncharged\n\n[1/4] The EU AI Act took effect in March 2024.\n False (high) · deep check\n Finding for The EU AI Act took effect in March 2024.\n Suggested rewrite: Fixed: The EU AI Act took effect in March 2024.\n https://lenz.io/c/the-earth-is-round-68ca4aaf\n\n[2/4] Water boils at 100 C at sea level.\n Quick check failed: A model provider was unavailable for this item. Retry it; nothing was charged.\n\n[3/4] The Eiffel Tower is in Berlin.\n False (high) · quick check\n Deep check failed: The deep check failed.\n\n[4/4] Paris is the capital of France.\n True (high) · quick check\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_issues": "Review d6b2bd72: incomplete — 4 claims: 2 issues, 1 true or mostly true, 1 failed · 1 of 2 deep-checked · 13 credits \ncharged\n\n[1/4] The EU AI Act took effect in March 2024.\n False (high) · deep check\n Finding for The EU AI Act took effect in March 2024.\n Suggested rewrite: Fixed: The EU AI Act took effect in March 2024.\n https://lenz.io/c/the-earth-is-round-68ca4aaf\n\n[3/4] The Eiffel Tower is in Berlin.\n False (high) · quick check\n Deep check failed: research_empty\n\n[2/4] Water boils at 100 C at sea level.\n Assessment failed: A model provider was unavailable for this item. Retry it; nothing was charged.\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='incomplete', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=4, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=3, failed=1), verifications=ReviewVerificationCounts(planned=2, completed=1, failed=1), issues=2, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=13), poll_after_seconds=None, issues=[ReviewIssue(claim_index=0, claim='The EU AI Act took effect in March 2024.', verified_claim=None, verdict='False', confidence='high', source='verification', verification_id='68ca4aaf', verification_status='completed', verification_url='https://lenz.io/api/v1/verifications/68ca4aaf', url='https://lenz.io/c/the-earth-is-round-68ca4aaf', escalation=Escalation(matched_rules=['verdict'], disposition='planned'), key_finding='Finding for The EU AI Act took effect in March 2024.', rationale=None, suggested_rewrite='Fixed: The EU AI Act took effect in March 2024.', failure=None, suggested_edits=None), ReviewIssue(claim_index=2, claim='The Eiffel Tower is in Berlin.', verified_claim=None, verdict='False', confidence='high', source='assessment', verification_id=None, verification_status='failed', verification_url=None, url=None, escalation=Escalation(matched_rules=['verdict'], disposition='planned'), key_finding=None, rationale=None, suggested_rewrite=None, failure=FailureBlock(failure_reason='research_empty', failure_class='insufficient_evidence', retryable=False, hint=None, docs_url='https://lenz.io/docs/errors#insufficient-evidence'), suggested_edits=None)], failures=[ReviewFailure(claim_index=1, claim='Water boils at 100 C at sea level.', stage='assessment', failure=FailureBlock(failure_reason='upstream_unavailable', failure_class='upstream_unavailable', retryable=True, hint='A model provider was unavailable for this item. Retry it; nothing was charged.', docs_url='https://lenz.io/docs/errors#upstream-unavailable'))], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='False', confidence='high', source='verification', is_issue=True), assessment=ReviewAssessment(status='completed', verdict='Mostly False', confidence='medium', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=['verdict'], disposition='planned'), verification=ReviewVerification(status='completed', content_status='available', verification_id='68ca4aaf', task_id='7cff18da2d979d6370e54a160be121ad', claim='The EU AI Act took effect in March 2024.', language='en', visibility='private', depth='standard', domain='', entities=[], verdict='False', confidence='high', lenz_score=2, key_finding='Finding for The EU AI Act took effect in March 2024.', executive_summary='Summary for The EU AI Act took effect in March 2024.', suggested_rewrite='Fixed: The EU AI Act took effect in March 2024.', warnings=['w1'], created_at='2026-10-01T09:14:00.123456+00:00', modified_at=None, verification_url='https://lenz.io/api/v1/verifications/68ca4aaf', url='https://lenz.io/c/the-earth-is-round-68ca4aaf', failure=None), suggested_edits=None), ReviewClaim(index=1, claim='Water boils at 100 C at sea level.', positions=None, result=None, assessment=ReviewAssessment(status='failed', verdict=None, confidence=None, rationale=None, dissent=None, verification_url=None, error_code='upstream_unavailable', identified_claims=[], hint=None, suggested_rewrite=None, failure=FailureBlock(failure_reason='upstream_unavailable', failure_class='upstream_unavailable', retryable=True, hint='A model provider was unavailable for this item. Retry it; nothing was charged.', docs_url='https://lenz.io/docs/errors#upstream-unavailable')), escalation=None, verification=None, suggested_edits=None), ReviewClaim(index=2, claim='The Eiffel Tower is in Berlin.', positions=None, result=ReviewResult(verdict='False', confidence='high', source='assessment', is_issue=True), assessment=ReviewAssessment(status='completed', verdict='False', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=['verdict'], disposition='planned'), verification=ReviewVerification(status='failed', content_status='available', verification_id=None, task_id='0b92b443eb69b9c71434fdc64f2ca8be', claim=None, language=None, visibility=None, depth=None, domain=None, entities=[], verdict=None, confidence=None, lenz_score=None, key_finding=None, executive_summary=None, suggested_rewrite=None, warnings=[], created_at=None, modified_at=None, verification_url=None, url=None, failure=FailureBlock(failure_reason='research_empty', failure_class='insufficient_evidence', retryable=False, hint=None, docs_url='https://lenz.io/docs/errors#insufficient-evidence')), suggested_edits=None), ReviewClaim(index=3, claim='Paris is the capital of France.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_completed_issues_view_issues.json b/tests/fixtures/parity/expected/review__get_completed_issues_view_issues.json new file mode 100644 index 0000000..ecbfeda --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_completed_issues_view_issues.json @@ -0,0 +1,259 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 13 + }, + "failure": null, + "failures": [ + { + "claim": "Water boils at 100 C at sea level.", + "claim_index": 1, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "stage": "assessment" + } + ], + "issues": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "rationale": null, + "source": "verification", + "suggested_edits": null, + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + }, + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 2, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence", + "failure_class": "insufficient_evidence", + "failure_reason": "research_empty", + "hint": null, + "retryable": false + }, + "key_finding": null, + "rationale": null, + "source": "assessment", + "suggested_edits": null, + "suggested_rewrite": null, + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": "failed", + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "incomplete", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 3, + "failed": 1 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 4, + "input_truncated": false, + "issues": 2, + "verifications": { + "completed": 1, + "failed": 1, + "planned": 2 + } + }, + "view": "issues" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 13 + }, + "failure": null, + "failures": [ + { + "claim": "Water boils at 100 C at sea level.", + "claim_index": 1, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "stage": "assessment" + } + ], + "issues": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "rationale": null, + "source": "verification", + "suggested_edits": null, + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + }, + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 2, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence", + "failure_class": "insufficient_evidence", + "failure_reason": "research_empty", + "hint": null, + "retryable": false + }, + "key_finding": null, + "rationale": null, + "source": "assessment", + "suggested_edits": null, + "suggested_rewrite": null, + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": "failed", + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "incomplete", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 3, + "failed": 1 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 4, + "input_truncated": false, + "issues": 2, + "verifications": { + "completed": 1, + "failed": 1, + "planned": 2 + } + }, + "view": "issues" + }, + "exit_code": 2, + "render": "Review d6b2bd72: incomplete — 4 claims: 2 issues, 1 failed, 1 not checked · 1 of 2 deep-checked · 13 credits charged\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_issues": "Review d6b2bd72: incomplete — 4 claims: 2 issues, 1 failed, 1 not checked · 1 of 2 deep-checked · 13 credits charged\n\n[1/4] The EU AI Act took effect in March 2024.\n False (high) · deep check\n Finding for The EU AI Act took effect in March 2024.\n Suggested rewrite: Fixed: The EU AI Act took effect in March 2024.\n https://lenz.io/c/the-earth-is-round-68ca4aaf\n\n[3/4] The Eiffel Tower is in Berlin.\n False (high) · quick check\n Deep check failed: research_empty\n\n[2/4] Water boils at 100 C at sea level.\n Assessment failed: A model provider was unavailable for this item. Retry it; nothing was charged.\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='issues', status='completed', outcome='incomplete', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=4, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=3, failed=1), verifications=ReviewVerificationCounts(planned=2, completed=1, failed=1), issues=2, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=13), poll_after_seconds=None, issues=[ReviewIssue(claim_index=0, claim='The EU AI Act took effect in March 2024.', verified_claim=None, verdict='False', confidence='high', source='verification', verification_id='68ca4aaf', verification_status='completed', verification_url='https://lenz.io/api/v1/verifications/68ca4aaf', url='https://lenz.io/c/the-earth-is-round-68ca4aaf', escalation=Escalation(matched_rules=['verdict'], disposition='planned'), key_finding='Finding for The EU AI Act took effect in March 2024.', rationale=None, suggested_rewrite='Fixed: The EU AI Act took effect in March 2024.', failure=None, suggested_edits=None), ReviewIssue(claim_index=2, claim='The Eiffel Tower is in Berlin.', verified_claim=None, verdict='False', confidence='high', source='assessment', verification_id=None, verification_status='failed', verification_url=None, url=None, escalation=Escalation(matched_rules=['verdict'], disposition='planned'), key_finding=None, rationale=None, suggested_rewrite=None, failure=FailureBlock(failure_reason='research_empty', failure_class='insufficient_evidence', retryable=False, hint=None, docs_url='https://lenz.io/docs/errors#insufficient-evidence'), suggested_edits=None)], failures=[ReviewFailure(claim_index=1, claim='Water boils at 100 C at sea level.', stage='assessment', failure=FailureBlock(failure_reason='upstream_unavailable', failure_class='upstream_unavailable', retryable=True, hint='A model provider was unavailable for this item. Retry it; nothing was charged.', docs_url='https://lenz.io/docs/errors#upstream-unavailable'))], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_completed_positions.json b/tests/fixtures/parity/expected/review__get_completed_positions.json new file mode 100644 index 0000000..b438323 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_completed_positions.json @@ -0,0 +1,275 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": [ + { + "end": 40, + "start": 0, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": [ + { + "end": 89, + "start": 55, + "text": "Water boils at 100 C at sea level." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": [ + { + "end": 40, + "start": 0, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": [ + { + "end": 89, + "start": 55, + "text": "Water boils at 100 C at sea level." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 2 claims: 2 true or mostly true · 2 credits charged\n\n[1/2] The EU AI Act took effect in March 2024. · at 0-40\n True (high) · quick check\n\n[2/2] Water boils at 100 C at sea level. · at 55-89\n True (high) · quick check\n", + "render_issues": "Review d6b2bd72: clean — 2 claims: 2 true or mostly true · 2 credits charged\n\nNo issues.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=2, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=2, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=2), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=[Position(start=0, end=40, text='The EU AI Act took effect in March 2024.')], result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None), ReviewClaim(index=1, claim='Water boils at 100 C at sea level.', positions=[Position(start=55, end=89, text='Water boils at 100 C at sea level.')], result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_completed_recovered_claim.json b/tests/fixtures/parity/expected/review__get_completed_recovered_claim.json new file mode 100644 index 0000000..ee17c63 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_completed_recovered_claim.json @@ -0,0 +1,191 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Orbit Motors stock increased by 40% in 2022.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": [], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Orbit Motors stock increased by 40% in 2022.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": [], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 1 credit charged\n\n[1/1] Orbit Motors stock increased by 40% in 2022.\n True (high) · quick check\n", + "render_issues": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 1 credit charged\n\nNo issues.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=1), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='Orbit Motors stock increased by 40% in 2022.', positions=[], result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_completed_with_untraced_claim.json b/tests/fixtures/parity/expected/review__get_completed_with_untraced_claim.json new file mode 100644 index 0000000..a57ad21 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_completed_with_untraced_claim.json @@ -0,0 +1,275 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": [ + { + "end": 40, + "start": 0, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": [ + { + "end": 84, + "start": 50, + "text": "Water boils at 100 C at sea level." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": [ + { + "end": 40, + "start": 0, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": [ + { + "end": 84, + "start": 50, + "text": "Water boils at 100 C at sea level." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 2 claims: 2 true or mostly true · 2 credits charged\n\n[1/2] The EU AI Act took effect in March 2024. · at 0-40\n True (high) · quick check\n\n[2/2] Water boils at 100 C at sea level. · at 50-84\n True (high) · quick check\n", + "render_issues": "Review d6b2bd72: clean — 2 claims: 2 true or mostly true · 2 credits charged\n\nNo issues.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=2, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=2, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=2), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=[Position(start=0, end=40, text='The EU AI Act took effect in March 2024.')], result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None), ReviewClaim(index=1, claim='Water boils at 100 C at sea level.', positions=[Position(start=50, end=84, text='Water boils at 100 C at sea level.')], result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_during_quick_check.json b/tests/fixtures/parity/expected/review__get_during_quick_check.json new file mode 100644 index 0000000..f321920 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_during_quick_check.json @@ -0,0 +1,167 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "running", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": null, + "index": 0, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 10, + "review_id": "d6b2bd72", + "status": "assessing", + "summary": { + "assessments": { + "completed": 0, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "running", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": null, + "index": 0, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 10, + "review_id": "d6b2bd72", + "status": "assessing", + "summary": { + "assessments": { + "completed": 0, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: assessing — 1 claim: 1 not checked · 1 credit charged\n\n[1/1] The EU AI Act took effect in March 2024.\n ? · quick check\n", + "render_issues": "Review d6b2bd72: assessing — 1 claim: 1 not checked · 1 credit charged\n\nNo issues.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='assessing', outcome=None, created_at='2026-10-01T09:07:00.123456Z', completed_at=None, language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=0, failed=0), verifications=None, issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=1), poll_after_seconds=10, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=None, assessment=ReviewAssessment(status='running', verdict=None, confidence=None, rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=None, verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_failed_every_assessment_failed.json b/tests/fixtures/parity/expected/review__get_failed_every_assessment_failed.json new file mode 100644 index 0000000..d7ffa8d --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_failed_every_assessment_failed.json @@ -0,0 +1,305 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": "upstream_unavailable", + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "failed", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": null, + "index": 0, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": "upstream_unavailable", + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "failed", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": null, + "index": 1, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "assessment_failed", + "hint": "No claim could be assessed. Retry the review with a new Idempotency-Key; nothing was charged.", + "retryable": true + }, + "failures": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 0, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "stage": "assessment" + }, + { + "claim": "Water boils at 100 C at sea level.", + "claim_index": 1, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "stage": "assessment" + } + ], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "incomplete", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "failed", + "summary": { + "assessments": { + "completed": 0, + "failed": 2 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": "upstream_unavailable", + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "failed", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": null, + "index": 0, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": null, + "dissent": null, + "error_code": "upstream_unavailable", + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "failed", + "suggested_rewrite": null, + "verdict": null, + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": null, + "index": 1, + "positions": null, + "result": null, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "assessment_failed", + "hint": "No claim could be assessed. Retry the review with a new Idempotency-Key; nothing was charged.", + "retryable": true + }, + "failures": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 0, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "stage": "assessment" + }, + { + "claim": "Water boils at 100 C at sea level.", + "claim_index": 1, + "failure": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable", + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "retryable": true + }, + "stage": "assessment" + } + ], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "incomplete", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "failed", + "summary": { + "assessments": { + "completed": 0, + "failed": 2 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: incomplete — 2 claims: 2 failed · 0 credits charged\nFailed: No claim could be assessed. Retry the review with a new Idempotency-Key; nothing was charged.\n\n[1/2] The EU AI Act took effect in March 2024.\n Quick check failed: A model provider was unavailable for this item. Retry it; nothing was charged.\n\n[2/2] Water boils at 100 C at sea level.\n Quick check failed: A model provider was unavailable for this item. Retry it; nothing was charged.\n", + "render_issues": "Review d6b2bd72: incomplete — 2 claims: 2 failed · 0 credits charged\nFailed: No claim could be assessed. Retry the review with a new Idempotency-Key; nothing was charged.\n\n[1/2] The EU AI Act took effect in March 2024.\n Assessment failed: A model provider was unavailable for this item. Retry it; nothing was charged.\n\n[2/2] Water boils at 100 C at sea level.\n Assessment failed: A model provider was unavailable for this item. Retry it; nothing was charged.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='failed', outcome='incomplete', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=2, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=0, failed=2), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=0), poll_after_seconds=None, issues=[], failures=[ReviewFailure(claim_index=0, claim='The EU AI Act took effect in March 2024.', stage='assessment', failure=FailureBlock(failure_reason='upstream_unavailable', failure_class='upstream_unavailable', retryable=True, hint='A model provider was unavailable for this item. Retry it; nothing was charged.', docs_url='https://lenz.io/docs/errors#upstream-unavailable')), ReviewFailure(claim_index=1, claim='Water boils at 100 C at sea level.', stage='assessment', failure=FailureBlock(failure_reason='upstream_unavailable', failure_class='upstream_unavailable', retryable=True, hint='A model provider was unavailable for this item. Retry it; nothing was charged.', docs_url='https://lenz.io/docs/errors#upstream-unavailable'))], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=FailureBlock(failure_reason='assessment_failed', failure_class='upstream_unavailable', retryable=True, hint='No claim could be assessed. Retry the review with a new Idempotency-Key; nothing was charged.', docs_url='https://lenz.io/docs/errors#upstream-unavailable'), claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=None, assessment=ReviewAssessment(status='failed', verdict=None, confidence=None, rationale=None, dissent=None, verification_url=None, error_code='upstream_unavailable', identified_claims=[], hint=None, suggested_rewrite=None, failure=FailureBlock(failure_reason='upstream_unavailable', failure_class='upstream_unavailable', retryable=True, hint='A model provider was unavailable for this item. Retry it; nothing was charged.', docs_url='https://lenz.io/docs/errors#upstream-unavailable')), escalation=None, verification=None, suggested_edits=None), ReviewClaim(index=1, claim='Water boils at 100 C at sea level.', positions=None, result=None, assessment=ReviewAssessment(status='failed', verdict=None, confidence=None, rationale=None, dissent=None, verification_url=None, error_code='upstream_unavailable', identified_claims=[], hint=None, suggested_rewrite=None, failure=FailureBlock(failure_reason='upstream_unavailable', failure_class='upstream_unavailable', retryable=True, hint='A model provider was unavailable for this item. Retry it; nothing was charged.', docs_url='https://lenz.io/docs/errors#upstream-unavailable')), escalation=None, verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_failed_no_claim.json b/tests/fixtures/parity/expected/review__get_failed_no_claim.json new file mode 100644 index 0000000..831acdf --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_failed_no_claim.json @@ -0,0 +1,127 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "failure_class": "invalid_input", + "failure_reason": "no_claim", + "hint": "The text is a greeting, not a statement about the world. Send one factual claim, or run the text through /extract to enumerate its claims.", + "retryable": false + }, + "failures": [], + "issues": [], + "language": "en", + "more_citations": null, + "more_claim_locations": null, + "more_claims": null, + "outcome": "unchecked", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "failed", + "summary": { + "assessments": null, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": null, + "claims_selected": null, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "failure_class": "invalid_input", + "failure_reason": "no_claim", + "hint": "The text is a greeting, not a statement about the world. Send one factual claim, or run the text through /extract to enumerate its claims.", + "retryable": false + }, + "failures": [], + "issues": [], + "language": "en", + "more_citations": null, + "more_claim_locations": null, + "more_claims": null, + "outcome": "unchecked", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "failed", + "summary": { + "assessments": null, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": null, + "claims_selected": null, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: unchecked — no claims checked · 0 credits charged\nFailed: The text is a greeting, not a statement about the world. Send one factual claim, or run the text through \n/extract to enumerate its claims.\n", + "render_issues": "Review d6b2bd72: unchecked — no claims checked · 0 credits charged\nFailed: The text is a greeting, not a statement about the world. Send one factual claim, or run the text through \n/extract to enumerate its claims.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='failed', outcome='unchecked', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=None, claim_limit=20, claim_limit_reached=None, input_truncated=False, assessments=None, verifications=None, issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=0), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=None, more_claim_locations=None, more_citations=None, failure=FailureBlock(failure_reason='no_claim', failure_class='invalid_input', retryable=False, hint='The text is a greeting, not a statement about the world. Send one factual claim, or run the text through /extract to enumerate its claims.', docs_url='https://lenz.io/docs/errors#invalid-input'), claims=[], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_failed_no_claim_untraced.json b/tests/fixtures/parity/expected/review__get_failed_no_claim_untraced.json new file mode 100644 index 0000000..c371358 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_failed_no_claim_untraced.json @@ -0,0 +1,127 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "failure_class": "invalid_input", + "failure_reason": "no_claim", + "hint": "None of the claims found in the text could be traced back to it. Send one factual claim, or run the text through /extract to enumerate its claims.", + "retryable": false + }, + "failures": [], + "issues": [], + "language": "en", + "more_citations": null, + "more_claim_locations": null, + "more_claims": null, + "outcome": "unchecked", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "failed", + "summary": { + "assessments": null, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": null, + "claims_selected": null, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "failure_class": "invalid_input", + "failure_reason": "no_claim", + "hint": "None of the claims found in the text could be traced back to it. Send one factual claim, or run the text through /extract to enumerate its claims.", + "retryable": false + }, + "failures": [], + "issues": [], + "language": "en", + "more_citations": null, + "more_claim_locations": null, + "more_claims": null, + "outcome": "unchecked", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "failed", + "summary": { + "assessments": null, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": null, + "claims_selected": null, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: unchecked — no claims checked · 0 credits charged\nFailed: None of the claims found in the text could be traced back to it. Send one factual claim, or run the text through\n/extract to enumerate its claims.\n", + "render_issues": "Review d6b2bd72: unchecked — no claims checked · 0 credits charged\nFailed: None of the claims found in the text could be traced back to it. Send one factual claim, or run the text through\n/extract to enumerate its claims.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='failed', outcome='unchecked', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=None, claim_limit=20, claim_limit_reached=None, input_truncated=False, assessments=None, verifications=None, issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=0), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=None, more_claim_locations=None, more_citations=None, failure=FailureBlock(failure_reason='no_claim', failure_class='invalid_input', retryable=False, hint='None of the claims found in the text could be traced back to it. Send one factual claim, or run the text through /extract to enumerate its claims.', docs_url='https://lenz.io/docs/errors#invalid-input'), claims=[], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_more_claims.json b/tests/fixtures/parity/expected/review__get_more_claims.json new file mode 100644 index 0000000..aa3064b --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_more_claims.json @@ -0,0 +1,301 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": [ + { + "end": 40, + "start": 0, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": [ + { + "end": 84, + "start": 50, + "text": "Water boils at 100 C at sea level." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "positions": [ + { + "end": 121, + "start": 91, + "text": "The Eiffel Tower is in Berlin." + } + ] + } + ], + "more_claims": [ + "The Eiffel Tower is in Berlin." + ], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 2, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 2, + "claim_limit_reached": true, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": [ + { + "end": 40, + "start": 0, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": [ + { + "end": 84, + "start": 50, + "text": "Water boils at 100 C at sea level." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "positions": [ + { + "end": 121, + "start": 91, + "text": "The Eiffel Tower is in Berlin." + } + ] + } + ], + "more_claims": [ + "The Eiffel Tower is in Berlin." + ], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 2, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 2, + "claim_limit_reached": true, + "claims_selected": 2, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 2 claims: 2 true or mostly true · 2 credits charged\n\n[1/2] The EU AI Act took effect in March 2024. · at 0-40\n True (high) · quick check\n\n[2/2] Water boils at 100 C at sea level. · at 50-84\n True (high) · quick check\n\n1 more claim was found but not checked.\n", + "render_issues": "Review d6b2bd72: clean — 2 claims: 2 true or mostly true · 2 credits charged\n\nNo issues.\n\n1 more claim was found but not checked.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=2, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=2, claim_limit=2, claim_limit_reached=True, input_truncated=False, assessments=ReviewAssessmentCounts(completed=2, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=2), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=['The Eiffel Tower is in Berlin.'], more_claim_locations=[ClaimLocation(claim='The Eiffel Tower is in Berlin.', positions=[Position(start=91, end=121, text='The Eiffel Tower is in Berlin.')])], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=[Position(start=0, end=40, text='The EU AI Act took effect in March 2024.')], result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None), ReviewClaim(index=1, claim='Water boils at 100 C at sea level.', positions=[Position(start=50, end=84, text='Water boils at 100 C at sea level.')], result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_nested_verification_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/expected/review__get_nested_verification_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..71085d6 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_nested_verification_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,293 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "verification", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "high", + "content_status": "available", + "created_at": "2026-10-01T23:55:00.123456+00:00", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "language": "en", + "lenz_score": 2, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "status": "completed", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "visibility": "private", + "warnings": [ + "w1" + ] + } + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 11 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "source": "verification", + "suggested_edits": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "issues_found", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 1, + "verifications": { + "completed": 1, + "failed": 0, + "planned": 1 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "verification", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "high", + "content_status": "available", + "created_at": "2026-10-01T23:55:00.123456+00:00", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "language": "en", + "lenz_score": 2, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "status": "completed", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "visibility": "private", + "warnings": [ + "w1" + ] + } + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 11 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "source": "verification", + "suggested_edits": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "issues_found", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 1, + "verifications": { + "completed": 1, + "failed": 0, + "planned": 1 + } + }, + "view": "full" + }, + "exit_code": 1, + "render": "Review d6b2bd72: issues found — 1 claim: 1 issue · 1 of 1 deep-checked · 11 credits charged\n\n[1/1] The Eiffel Tower is in Berlin.\n False (high) · deep check\n Finding for The Eiffel Tower is in Berlin.\n Suggested rewrite: Fixed: The Eiffel Tower is in Berlin.\n https://lenz.io/c/the-earth-is-round-68ca4aaf\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_issues": "Review d6b2bd72: issues found — 1 claim: 1 issue · 1 of 1 deep-checked · 11 credits charged\n\n[1/1] The Eiffel Tower is in Berlin.\n False (high) · deep check\n Finding for The Eiffel Tower is in Berlin.\n Suggested rewrite: Fixed: The Eiffel Tower is in Berlin.\n https://lenz.io/c/the-earth-is-round-68ca4aaf\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='issues_found', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=1, completed=1, failed=0), issues=1, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=11), poll_after_seconds=None, issues=[ReviewIssue(claim_index=0, claim='The Eiffel Tower is in Berlin.', verified_claim=None, verdict='False', confidence='high', source='verification', verification_id='68ca4aaf', verification_status='completed', verification_url='https://lenz.io/api/v1/verifications/68ca4aaf', url='https://lenz.io/c/the-earth-is-round-68ca4aaf', escalation=Escalation(matched_rules=['verdict'], disposition='planned'), key_finding='Finding for The Eiffel Tower is in Berlin.', rationale=None, suggested_rewrite='Fixed: The Eiffel Tower is in Berlin.', failure=None, suggested_edits=None)], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The Eiffel Tower is in Berlin.', positions=None, result=ReviewResult(verdict='False', confidence='high', source='verification', is_issue=True), assessment=ReviewAssessment(status='completed', verdict='False', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=['verdict'], disposition='planned'), verification=ReviewVerification(status='completed', content_status='available', verification_id='68ca4aaf', task_id='7cff18da2d979d6370e54a160be121ad', claim='The Eiffel Tower is in Berlin.', language='en', visibility='private', depth='standard', domain='', entities=[], verdict='False', confidence='high', lenz_score=2, key_finding='Finding for The Eiffel Tower is in Berlin.', executive_summary='Summary for The Eiffel Tower is in Berlin.', suggested_rewrite='Fixed: The Eiffel Tower is in Berlin.', warnings=['w1'], created_at='2026-10-01T23:55:00.123456+00:00', modified_at='2026-10-02T00:03:00.123456+00:00', verification_url='https://lenz.io/api/v1/verifications/68ca4aaf', url='https://lenz.io/c/the-earth-is-round-68ca4aaf', failure=None), suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_nested_verification_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/expected/review__get_nested_verification_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..554926b --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_nested_verification_modified_at_same_day_hours_apart.json @@ -0,0 +1,293 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "verification", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "high", + "content_status": "available", + "created_at": "2026-10-01T08:00:00.123456+00:00", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "language": "en", + "lenz_score": 2, + "modified_at": null, + "status": "completed", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "visibility": "private", + "warnings": [ + "w1" + ] + } + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 11 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "source": "verification", + "suggested_edits": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "issues_found", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 1, + "verifications": { + "completed": 1, + "failed": 0, + "planned": 1 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "verification", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "high", + "content_status": "available", + "created_at": "2026-10-01T08:00:00.123456+00:00", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "language": "en", + "lenz_score": 2, + "modified_at": null, + "status": "completed", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "visibility": "private", + "warnings": [ + "w1" + ] + } + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 11 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "source": "verification", + "suggested_edits": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "issues_found", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 1, + "verifications": { + "completed": 1, + "failed": 0, + "planned": 1 + } + }, + "view": "full" + }, + "exit_code": 1, + "render": "Review d6b2bd72: issues found — 1 claim: 1 issue · 1 of 1 deep-checked · 11 credits charged\n\n[1/1] The Eiffel Tower is in Berlin.\n False (high) · deep check\n Finding for The Eiffel Tower is in Berlin.\n Suggested rewrite: Fixed: The Eiffel Tower is in Berlin.\n https://lenz.io/c/the-earth-is-round-68ca4aaf\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_issues": "Review d6b2bd72: issues found — 1 claim: 1 issue · 1 of 1 deep-checked · 11 credits charged\n\n[1/1] The Eiffel Tower is in Berlin.\n False (high) · deep check\n Finding for The Eiffel Tower is in Berlin.\n Suggested rewrite: Fixed: The Eiffel Tower is in Berlin.\n https://lenz.io/c/the-earth-is-round-68ca4aaf\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='issues_found', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=1, completed=1, failed=0), issues=1, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=11), poll_after_seconds=None, issues=[ReviewIssue(claim_index=0, claim='The Eiffel Tower is in Berlin.', verified_claim=None, verdict='False', confidence='high', source='verification', verification_id='68ca4aaf', verification_status='completed', verification_url='https://lenz.io/api/v1/verifications/68ca4aaf', url='https://lenz.io/c/the-earth-is-round-68ca4aaf', escalation=Escalation(matched_rules=['verdict'], disposition='planned'), key_finding='Finding for The Eiffel Tower is in Berlin.', rationale=None, suggested_rewrite='Fixed: The Eiffel Tower is in Berlin.', failure=None, suggested_edits=None)], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The Eiffel Tower is in Berlin.', positions=None, result=ReviewResult(verdict='False', confidence='high', source='verification', is_issue=True), assessment=ReviewAssessment(status='completed', verdict='False', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=['verdict'], disposition='planned'), verification=ReviewVerification(status='completed', content_status='available', verification_id='68ca4aaf', task_id='7cff18da2d979d6370e54a160be121ad', claim='The Eiffel Tower is in Berlin.', language='en', visibility='private', depth='standard', domain='', entities=[], verdict='False', confidence='high', lenz_score=2, key_finding='Finding for The Eiffel Tower is in Berlin.', executive_summary='Summary for The Eiffel Tower is in Berlin.', suggested_rewrite='Fixed: The Eiffel Tower is in Berlin.', warnings=['w1'], created_at='2026-10-01T08:00:00.123456+00:00', modified_at=None, verification_url='https://lenz.io/api/v1/verifications/68ca4aaf', url='https://lenz.io/c/the-earth-is-round-68ca4aaf', failure=None), suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_policy_resolved.json b/tests/fixtures/parity/expected/review__get_policy_resolved.json new file mode 100644 index 0000000..dc93371 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_policy_resolved.json @@ -0,0 +1,187 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "low", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 2, + "suggest_edits": false, + "verdicts": [ + "False" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "low", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 2, + "suggest_edits": false, + "verdicts": [ + "False" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 1 credit charged\n\n[1/1] The EU AI Act took effect in March 2024.\n True (high) · quick check\n", + "render_issues": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 1 credit charged\n\nNo issues.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False'], confidence=['low'], max_assessments=20, max_verifications=2, depth='low', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=1), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_queued.json b/tests/fixtures/parity/expected/review__get_queued.json new file mode 100644 index 0000000..45e6ec0 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_queued.json @@ -0,0 +1,115 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [], + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": null, + "more_claim_locations": null, + "more_claims": null, + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 10, + "review_id": "d6b2bd72", + "status": "queued", + "summary": { + "assessments": null, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": null, + "claims_selected": null, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [], + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": null, + "more_claim_locations": null, + "more_claims": null, + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 10, + "review_id": "d6b2bd72", + "status": "queued", + "summary": { + "assessments": null, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": null, + "claims_selected": null, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: queued — no claims checked · 0 credits charged\n", + "render_issues": "Review d6b2bd72: queued — no claims checked · 0 credits charged\n\nNo issues.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='queued', outcome=None, created_at='2026-10-01T09:07:00.123456Z', completed_at=None, language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=None, claim_limit=20, claim_limit_reached=None, input_truncated=False, assessments=None, verifications=None, issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=0), poll_after_seconds=10, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=None, more_claim_locations=None, more_citations=None, failure=None, claims=[], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_suggested_edits.json b/tests/fixtures/parity/expected/review__get_suggested_edits.json new file mode 100644 index 0000000..5f8332a --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_suggested_edits.json @@ -0,0 +1,529 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": [ + { + "end": 30, + "start": 0, + "text": "The Eiffel Tower is in Berlin." + } + ], + "result": { + "confidence": "high", + "is_issue": true, + "source": "verification", + "verdict": "False" + }, + "suggested_edits": { + "edits": [ + { + "end": 29, + "position": 0, + "replacement": "Paris", + "start": 23, + "text": "Berlin" + } + ], + "status": "completed" + }, + "verification": { + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "high", + "content_status": "available", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "language": "en", + "lenz_score": 2, + "modified_at": null, + "status": "completed", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "visibility": "private", + "warnings": [ + "w1" + ] + } + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 1, + "positions": [ + { + "end": 85, + "start": 45, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "confidence": "high", + "is_issue": true, + "source": "assessment", + "verdict": "False" + }, + "suggested_edits": { + "edits": null, + "status": "pending" + }, + "verification": { + "claim": null, + "confidence": null, + "content_status": "available", + "created_at": null, + "depth": null, + "domain": null, + "entities": [], + "executive_summary": null, + "failure": null, + "key_finding": null, + "language": null, + "lenz_score": null, + "modified_at": null, + "status": "processing", + "suggested_rewrite": null, + "task_id": null, + "url": null, + "verdict": null, + "verification_id": null, + "verification_url": null, + "visibility": null, + "warnings": [] + } + } + ], + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 12 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "source": "verification", + "suggested_edits": { + "edits": [ + { + "end": 29, + "position": 0, + "replacement": "Paris", + "start": 23, + "text": "Berlin" + } + ], + "status": "completed" + }, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + }, + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 1, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": null, + "rationale": null, + "source": "assessment", + "suggested_edits": { + "edits": null, + "status": "pending" + }, + "suggested_rewrite": null, + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": "processing", + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": true, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 15, + "review_id": "d6b2bd72", + "status": "verifying", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 2, + "verifications": { + "completed": 1, + "failed": 0, + "planned": 2 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": [ + { + "end": 30, + "start": 0, + "text": "The Eiffel Tower is in Berlin." + } + ], + "result": { + "confidence": "high", + "is_issue": true, + "source": "verification", + "verdict": "False" + }, + "suggested_edits": { + "edits": [ + { + "end": 29, + "position": 0, + "replacement": "Paris", + "start": 23, + "text": "Berlin" + } + ], + "status": "completed" + }, + "verification": { + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "high", + "content_status": "available", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "language": "en", + "lenz_score": 2, + "modified_at": null, + "status": "completed", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "visibility": "private", + "warnings": [ + "w1" + ] + } + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 1, + "positions": [ + { + "end": 85, + "start": 45, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "confidence": "high", + "is_issue": true, + "source": "assessment", + "verdict": "False" + }, + "suggested_edits": { + "edits": null, + "status": "pending" + }, + "verification": { + "claim": null, + "confidence": null, + "content_status": "available", + "created_at": null, + "depth": null, + "domain": null, + "entities": [], + "executive_summary": null, + "failure": null, + "key_finding": null, + "language": null, + "lenz_score": null, + "modified_at": null, + "status": "processing", + "suggested_rewrite": null, + "task_id": null, + "url": null, + "verdict": null, + "verification_id": null, + "verification_url": null, + "visibility": null, + "warnings": [] + } + } + ], + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 12 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "source": "verification", + "suggested_edits": { + "edits": [ + { + "end": 29, + "position": 0, + "replacement": "Paris", + "start": 23, + "text": "Berlin" + } + ], + "status": "completed" + }, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + }, + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 1, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": null, + "rationale": null, + "source": "assessment", + "suggested_edits": { + "edits": null, + "status": "pending" + }, + "suggested_rewrite": null, + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": "processing", + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": true, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 15, + "review_id": "d6b2bd72", + "status": "verifying", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 2, + "verifications": { + "completed": 1, + "failed": 0, + "planned": 2 + } + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: verifying — 2 claims: 2 issues · 1 of 2 deep-checked · 12 credits charged\n\n[1/2] The Eiffel Tower is in Berlin. · at 0-30\n False (high) · deep check\n Finding for The Eiffel Tower is in Berlin.\n Suggested rewrite: Fixed: The Eiffel Tower is in Berlin.\n https://lenz.io/c/the-earth-is-round-68ca4aaf\n\n[2/2] The EU AI Act took effect in March 2024. · at 45-85\n False (high) · quick check\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_issues": "Review d6b2bd72: verifying — 2 claims: 2 issues · 1 of 2 deep-checked · 12 credits charged\n\n[1/2] The Eiffel Tower is in Berlin.\n False (high) · deep check\n Finding for The Eiffel Tower is in Berlin.\n Suggested rewrite: Fixed: The Eiffel Tower is in Berlin.\n https://lenz.io/c/the-earth-is-round-68ca4aaf\n\n[2/2] The EU AI Act took effect in March 2024.\n False (high) · quick check\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='verifying', outcome=None, created_at='2026-10-01T09:07:00.123456Z', completed_at=None, language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=True), summary=ReviewSummary(claims_selected=2, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=2, failed=0), verifications=ReviewVerificationCounts(planned=2, completed=1, failed=0), issues=2, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=12), poll_after_seconds=15, issues=[ReviewIssue(claim_index=0, claim='The Eiffel Tower is in Berlin.', verified_claim=None, verdict='False', confidence='high', source='verification', verification_id='68ca4aaf', verification_status='completed', verification_url='https://lenz.io/api/v1/verifications/68ca4aaf', url='https://lenz.io/c/the-earth-is-round-68ca4aaf', escalation=Escalation(matched_rules=['verdict'], disposition='planned'), key_finding='Finding for The Eiffel Tower is in Berlin.', rationale=None, suggested_rewrite='Fixed: The Eiffel Tower is in Berlin.', failure=None, suggested_edits=SuggestedEdits(status='completed', edits=[SuggestedEdit(position=0, start=23, end=29, text='Berlin', replacement='Paris')])), ReviewIssue(claim_index=1, claim='The EU AI Act took effect in March 2024.', verified_claim=None, verdict='False', confidence='high', source='assessment', verification_id=None, verification_status='processing', verification_url=None, url=None, escalation=Escalation(matched_rules=['verdict'], disposition='planned'), key_finding=None, rationale=None, suggested_rewrite=None, failure=None, suggested_edits=SuggestedEdits(status='pending', edits=None))], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The Eiffel Tower is in Berlin.', positions=[Position(start=0, end=30, text='The Eiffel Tower is in Berlin.')], result=ReviewResult(verdict='False', confidence='high', source='verification', is_issue=True), assessment=ReviewAssessment(status='completed', verdict='False', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=['verdict'], disposition='planned'), verification=ReviewVerification(status='completed', content_status='available', verification_id='68ca4aaf', task_id='7cff18da2d979d6370e54a160be121ad', claim='The Eiffel Tower is in Berlin.', language='en', visibility='private', depth='standard', domain='', entities=[], verdict='False', confidence='high', lenz_score=2, key_finding='Finding for The Eiffel Tower is in Berlin.', executive_summary='Summary for The Eiffel Tower is in Berlin.', suggested_rewrite='Fixed: The Eiffel Tower is in Berlin.', warnings=['w1'], created_at='2026-10-01T09:14:00.123456+00:00', modified_at=None, verification_url='https://lenz.io/api/v1/verifications/68ca4aaf', url='https://lenz.io/c/the-earth-is-round-68ca4aaf', failure=None), suggested_edits=SuggestedEdits(status='completed', edits=[SuggestedEdit(position=0, start=23, end=29, text='Berlin', replacement='Paris')])), ReviewClaim(index=1, claim='The EU AI Act took effect in March 2024.', positions=[Position(start=45, end=85, text='The EU AI Act took effect in March 2024.')], result=ReviewResult(verdict='False', confidence='high', source='assessment', is_issue=True), assessment=ReviewAssessment(status='completed', verdict='False', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=['verdict'], disposition='planned'), verification=ReviewVerification(status='processing', content_status='available', verification_id=None, task_id=None, claim=None, language=None, visibility=None, depth=None, domain=None, entities=[], verdict=None, confidence=None, lenz_score=None, key_finding=None, executive_summary=None, suggested_rewrite=None, warnings=[], created_at=None, modified_at=None, verification_url=None, url=None, failure=None), suggested_edits=SuggestedEdits(status='pending', edits=None))], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_suggested_edits_issues_view.json b/tests/fixtures/parity/expected/review__get_suggested_edits_issues_view.json new file mode 100644 index 0000000..ec30607 --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_suggested_edits_issues_view.json @@ -0,0 +1,249 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [], + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 12 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "source": "verification", + "suggested_edits": { + "edits": [ + { + "end": 29, + "position": 0, + "replacement": "Paris", + "start": 23, + "text": "Berlin" + } + ], + "status": "completed" + }, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + }, + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 1, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": null, + "rationale": null, + "source": "assessment", + "suggested_edits": { + "edits": null, + "status": "pending" + }, + "suggested_rewrite": null, + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": "processing", + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": true, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 15, + "review_id": "d6b2bd72", + "status": "verifying", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 2, + "verifications": { + "completed": 1, + "failed": 0, + "planned": 2 + } + }, + "view": "issues" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 12 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "source": "verification", + "suggested_edits": { + "edits": [ + { + "end": 29, + "position": 0, + "replacement": "Paris", + "start": 23, + "text": "Berlin" + } + ], + "status": "completed" + }, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + }, + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 1, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": null, + "rationale": null, + "source": "assessment", + "suggested_edits": { + "edits": null, + "status": "pending" + }, + "suggested_rewrite": null, + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": "processing", + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": true, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 15, + "review_id": "d6b2bd72", + "status": "verifying", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 2, + "verifications": { + "completed": 1, + "failed": 0, + "planned": 2 + } + }, + "view": "issues" + }, + "exit_code": 2, + "render": "Review d6b2bd72: verifying — 2 claims: 2 issues · 1 of 2 deep-checked · 12 credits charged\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_issues": "Review d6b2bd72: verifying — 2 claims: 2 issues · 1 of 2 deep-checked · 12 credits charged\n\n[1/2] The Eiffel Tower is in Berlin.\n False (high) · deep check\n Finding for The Eiffel Tower is in Berlin.\n Suggested rewrite: Fixed: The Eiffel Tower is in Berlin.\n https://lenz.io/c/the-earth-is-round-68ca4aaf\n\n[2/2] The EU AI Act took effect in March 2024.\n False (high) · quick check\n\nA suggested rewrite has not been verified itself: review it, or run it through `lenz verify`, before you use it.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='issues', status='verifying', outcome=None, created_at='2026-10-01T09:07:00.123456Z', completed_at=None, language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=True), summary=ReviewSummary(claims_selected=2, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=2, failed=0), verifications=ReviewVerificationCounts(planned=2, completed=1, failed=0), issues=2, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=12), poll_after_seconds=15, issues=[ReviewIssue(claim_index=0, claim='The Eiffel Tower is in Berlin.', verified_claim=None, verdict='False', confidence='high', source='verification', verification_id='68ca4aaf', verification_status='completed', verification_url='https://lenz.io/api/v1/verifications/68ca4aaf', url='https://lenz.io/c/the-earth-is-round-68ca4aaf', escalation=Escalation(matched_rules=['verdict'], disposition='planned'), key_finding='Finding for The Eiffel Tower is in Berlin.', rationale=None, suggested_rewrite='Fixed: The Eiffel Tower is in Berlin.', failure=None, suggested_edits=SuggestedEdits(status='completed', edits=[SuggestedEdit(position=0, start=23, end=29, text='Berlin', replacement='Paris')])), ReviewIssue(claim_index=1, claim='The EU AI Act took effect in March 2024.', verified_claim=None, verdict='False', confidence='high', source='assessment', verification_id=None, verification_status='processing', verification_url=None, url=None, escalation=Escalation(matched_rules=['verdict'], disposition='planned'), key_finding=None, rationale=None, suggested_rewrite=None, failure=None, suggested_edits=SuggestedEdits(status='pending', edits=None))], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_url_review.json b/tests/fixtures/parity/expected/review__get_url_review.json new file mode 100644 index 0000000..8153a7d --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_url_review.json @@ -0,0 +1,203 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": [ + { + "end": null, + "start": null, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": [ + { + "end": null, + "start": null, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "exit_code": 0, + "render": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 1 credit charged\n\n[1/1] The EU AI Act took effect in March 2024.\n True (high) · quick check\n", + "render_issues": "Review d6b2bd72: clean — 1 claim: 1 true or mostly true · 1 credit charged\n\nNo issues.\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='completed', outcome='clean', created_at='2026-10-01T09:07:00.123456Z', completed_at='2026-10-01T10:07:00.123456Z', language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=1, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=1, failed=0), verifications=ReviewVerificationCounts(planned=0, completed=0, failed=0), issues=0, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=1), poll_after_seconds=None, issues=[], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=[Position(start=None, end=None, text='The EU AI Act took effect in March 2024.')], result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__get_verifying.json b/tests/fixtures/parity/expected/review__get_verifying.json new file mode 100644 index 0000000..63b031e --- /dev/null +++ b/tests/fixtures/parity/expected/review__get_verifying.json @@ -0,0 +1,349 @@ +{ + "dump": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "assessment", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": null, + "confidence": null, + "content_status": "available", + "created_at": null, + "depth": null, + "domain": null, + "entities": [], + "executive_summary": null, + "failure": null, + "key_finding": null, + "language": null, + "lenz_score": null, + "modified_at": null, + "status": "processing", + "suggested_rewrite": null, + "task_id": null, + "url": null, + "verdict": null, + "verification_id": null, + "verification_url": null, + "visibility": null, + "warnings": [] + } + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": null, + "rationale": null, + "source": "assessment", + "suggested_edits": null, + "suggested_rewrite": null, + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": "processing", + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 15, + "review_id": "d6b2bd72", + "status": "verifying", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 1, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 1 + } + }, + "view": "full" + }, + "dump_unset": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The EU AI Act took effect in March 2024.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "assessment", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": null, + "confidence": null, + "content_status": "available", + "created_at": null, + "depth": null, + "domain": null, + "entities": [], + "executive_summary": null, + "failure": null, + "key_finding": null, + "language": null, + "lenz_score": null, + "modified_at": null, + "status": "processing", + "suggested_rewrite": null, + "task_id": null, + "url": null, + "verdict": null, + "verification_id": null, + "verification_url": null, + "visibility": null, + "warnings": [] + } + }, + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "Water boils at 100 C at sea level.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 1, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": null, + "rationale": null, + "source": "assessment", + "suggested_edits": null, + "suggested_rewrite": null, + "url": null, + "verdict": "False", + "verification_id": null, + "verification_status": "processing", + "verification_url": null, + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": null, + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": 15, + "review_id": "d6b2bd72", + "status": "verifying", + "summary": { + "assessments": { + "completed": 2, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 2, + "input_truncated": false, + "issues": 1, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 1 + } + }, + "view": "full" + }, + "exit_code": 2, + "render": "Review d6b2bd72: verifying — 2 claims: 1 issue, 1 true or mostly true · 0 of 1 deep-checked · 2 credits charged\n\n[1/2] The EU AI Act took effect in March 2024.\n False (high) · quick check\n\n[2/2] Water boils at 100 C at sea level.\n True (high) · quick check\n", + "render_issues": "Review d6b2bd72: verifying — 2 claims: 1 issue, 1 true or mostly true · 0 of 1 deep-checked · 2 credits charged\n\n[1/2] The EU AI Act took effect in March 2024.\n False (high) · quick check\n", + "render_json": null, + "repr": "ReviewFull(review_id='d6b2bd72', view='full', status='verifying', outcome=None, created_at='2026-10-01T09:07:00.123456Z', completed_at=None, language='en', policy=EscalationPolicy(verdicts=['False', 'Mostly False', 'Mixed'], confidence=['low'], max_assessments=20, max_verifications=5, depth='standard', max_citations=0, suggest_edits=False), summary=ReviewSummary(claims_selected=2, claim_limit=20, claim_limit_reached=False, input_truncated=False, assessments=ReviewAssessmentCounts(completed=2, failed=0), verifications=ReviewVerificationCounts(planned=1, completed=0, failed=0), issues=1, citations_found=None, citations_selected=None, citation_limit=None, citation_limit_reached=None, citation_checks=None, citation_issues=0, citations_skipped=None), credits=ReviewCredits(charged=2), poll_after_seconds=15, issues=[ReviewIssue(claim_index=0, claim='The EU AI Act took effect in March 2024.', verified_claim=None, verdict='False', confidence='high', source='assessment', verification_id=None, verification_status='processing', verification_url=None, url=None, escalation=Escalation(matched_rules=['verdict'], disposition='planned'), key_finding=None, rationale=None, suggested_rewrite=None, failure=None, suggested_edits=None)], failures=[], citation_issues=[], citation_failures=[], more_claims=[], more_claim_locations=[], more_citations=[], failure=None, claims=[ReviewClaim(index=0, claim='The EU AI Act took effect in March 2024.', positions=None, result=ReviewResult(verdict='False', confidence='high', source='assessment', is_issue=True), assessment=ReviewAssessment(status='completed', verdict='False', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=['verdict'], disposition='planned'), verification=ReviewVerification(status='processing', content_status='available', verification_id=None, task_id=None, claim=None, language=None, visibility=None, depth=None, domain=None, entities=[], verdict=None, confidence=None, lenz_score=None, key_finding=None, executive_summary=None, suggested_rewrite=None, warnings=[], created_at=None, modified_at=None, verification_url=None, url=None, failure=None), suggested_edits=None), ReviewClaim(index=1, claim='Water boils at 100 C at sea level.', positions=None, result=ReviewResult(verdict='True', confidence='high', source='assessment', is_issue=False), assessment=ReviewAssessment(status='completed', verdict='True', confidence='high', rationale=None, dissent=None, verification_url=None, error_code=None, identified_claims=[], hint=None, suggested_rewrite=None, failure=None), escalation=Escalation(matched_rules=[], disposition='not_selected'), verification=None, suggested_edits=None)], citations=[])" +} diff --git a/tests/fixtures/parity/expected/review__idempotency_body_mismatch_422.json b/tests/fixtures/parity/expected/review__idempotency_body_mismatch_422.json new file mode 100644 index 0000000..5de20e3 --- /dev/null +++ b/tests/fixtures/parity/expected/review__idempotency_body_mismatch_422.json @@ -0,0 +1,29 @@ +{ + "error": { + "cause": "Idempotency-Key reused with a different request body.", + "code": "idempotency_body_mismatch", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "header" + ], + "msg": "Idempotency-Key reused with a different request body." + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Idempotency-Key reused with a different request body.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Idempotency-Key reused with a different request body.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Idempotency-Key reused with a different request body.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/review__idempotency_conflict_409.json b/tests/fixtures/parity/expected/review__idempotency_conflict_409.json new file mode 100644 index 0000000..6f3c206 --- /dev/null +++ b/tests/fixtures/parity/expected/review__idempotency_conflict_409.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "A review with this Idempotency-Key is still being created. Retry shortly.", + "code": "idempotency_conflict", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "A review with this Idempotency-Key is still being created. Retry shortly.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "A review with this Idempotency-Key is still being created. Retry shortly.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "A review with this Idempotency-Key is still being created. Retry shortly.", + "status": 409 + } + }, + "request_id": "", + "status_code": 409, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/review__idempotency_conflict_409_existing_review.json b/tests/fixtures/parity/expected/review__idempotency_conflict_409_existing_review.json new file mode 100644 index 0000000..6f3c206 --- /dev/null +++ b/tests/fixtures/parity/expected/review__idempotency_conflict_409_existing_review.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "A review with this Idempotency-Key is still being created. Retry shortly.", + "code": "idempotency_conflict", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "A review with this Idempotency-Key is still being created. Retry shortly.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "A review with this Idempotency-Key is still being created. Retry shortly.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "A review with this Idempotency-Key is still being created. Retry shortly.", + "status": 409 + } + }, + "request_id": "", + "status_code": 409, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/review__idempotent_replay_202.json b/tests/fixtures/parity/expected/review__idempotent_replay_202.json new file mode 100644 index 0000000..615c995 --- /dev/null +++ b/tests/fixtures/parity/expected/review__idempotent_replay_202.json @@ -0,0 +1,12 @@ +{ + "dump": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "dump_unset": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "render_json": null, + "repr": "ReviewStarted(review_id='d6b2bd72', status='queued')" +} diff --git a/tests/fixtures/parity/expected/review__receipt_202.json b/tests/fixtures/parity/expected/review__receipt_202.json new file mode 100644 index 0000000..615c995 --- /dev/null +++ b/tests/fixtures/parity/expected/review__receipt_202.json @@ -0,0 +1,12 @@ +{ + "dump": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "dump_unset": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "render_json": null, + "repr": "ReviewStarted(review_id='d6b2bd72', status='queued')" +} diff --git a/tests/fixtures/parity/expected/review__receipt_202_empty_webhook_url.json b/tests/fixtures/parity/expected/review__receipt_202_empty_webhook_url.json new file mode 100644 index 0000000..615c995 --- /dev/null +++ b/tests/fixtures/parity/expected/review__receipt_202_empty_webhook_url.json @@ -0,0 +1,12 @@ +{ + "dump": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "dump_unset": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "render_json": null, + "repr": "ReviewStarted(review_id='d6b2bd72', status='queued')" +} diff --git a/tests/fixtures/parity/expected/review__receipt_202_webhook_url.json b/tests/fixtures/parity/expected/review__receipt_202_webhook_url.json new file mode 100644 index 0000000..615c995 --- /dev/null +++ b/tests/fixtures/parity/expected/review__receipt_202_webhook_url.json @@ -0,0 +1,12 @@ +{ + "dump": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "dump_unset": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "render_json": null, + "repr": "ReviewStarted(review_id='d6b2bd72', status='queued')" +} diff --git a/tests/fixtures/parity/expected/review__replay_later_202.json b/tests/fixtures/parity/expected/review__replay_later_202.json new file mode 100644 index 0000000..615c995 --- /dev/null +++ b/tests/fixtures/parity/expected/review__replay_later_202.json @@ -0,0 +1,12 @@ +{ + "dump": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "dump_unset": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "render_json": null, + "repr": "ReviewStarted(review_id='d6b2bd72', status='queued')" +} diff --git a/tests/fixtures/parity/expected/verify__batch_202.json b/tests/fixtures/parity/expected/verify__batch_202.json new file mode 100644 index 0000000..1f9894c --- /dev/null +++ b/tests/fixtures/parity/expected/verify__batch_202.json @@ -0,0 +1,30 @@ +{ + "dump": { + "batch_id": "7ea9cdbd4064e3cf", + "items": [ + { + "claim_text": "The Earth is round.", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + { + "claim_text": "Water boils at 100C at sea level.", + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be" + } + ] + }, + "dump_unset": { + "batch_id": "7ea9cdbd4064e3cf", + "items": [ + { + "claim_text": "The Earth is round.", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + { + "claim_text": "Water boils at 100C at sea level.", + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be" + } + ] + }, + "render_json": null, + "repr": "BatchAccepted(batch_id='7ea9cdbd4064e3cf', items=[TaskAccepted(task_id='7cff18da2d979d6370e54a160be121ad', claim_text='The Earth is round.'), TaskAccepted(task_id='0b92b443eb69b9c71434fdc64f2ca8be', claim_text='Water boils at 100C at sea level.')])" +} diff --git a/tests/fixtures/parity/expected/verify__batch_capacity_503.json b/tests/fixtures/parity/expected/verify__batch_capacity_503.json new file mode 100644 index 0000000..11cc917 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__batch_capacity_503.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "doc_url": "https://lenz.io/docs/errors#unavailable", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "status": 503 + } + }, + "request_id": "", + "retry_after": null, + "status_code": 503, + "type": "LenzUpstreamUnavailableError" + } +} diff --git a/tests/fixtures/parity/expected/verify__batch_empty_422.json b/tests/fixtures/parity/expected/verify__batch_empty_422.json new file mode 100644 index 0000000..e1ddac5 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__batch_empty_422.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "claims is required and must be non-empty.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "claims is required and must be non-empty.\n Fix: Check the request body against the OpenAPI spec.", + "message": "claims is required and must be non-empty.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "claims is required and must be non-empty.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/verify__batch_idempotency_conflict_409.json b/tests/fixtures/parity/expected/verify__batch_idempotency_conflict_409.json new file mode 100644 index 0000000..54ca3d5 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__batch_idempotency_conflict_409.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "A request with this Idempotency-Key is already in progress.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "A request with this Idempotency-Key is already in progress.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "A request with this Idempotency-Key is already in progress.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "A request with this Idempotency-Key is already in progress.", + "status": 409 + } + }, + "request_id": "", + "status_code": 409, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/verify__batch_item_missing_claim_422.json b/tests/fixtures/parity/expected/verify__batch_item_missing_claim_422.json new file mode 100644 index 0000000..f2a3fe8 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__batch_item_missing_claim_422.json @@ -0,0 +1,34 @@ +{ + "error": { + "cause": "[{'type': 'missing', 'loc': ['body', 'payload', 'claims', 1, 'text'], 'msg': 'Field required'}]", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "claims", + 1, + "text" + ], + "msg": "Field required", + "type": "missing" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "[{'type': 'missing', 'loc': ['body', 'payload', 'claims', 1, 'text'], 'msg': 'Field required'}]\n Fix: Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'claims', 1, 'text'], 'msg': 'Field required'}]", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'claims', 1, 'text'], 'msg': 'Field required'}]", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/verify__batch_no_credits_402.json b/tests/fixtures/parity/expected/verify__batch_no_credits_402.json new file mode 100644 index 0000000..52d04da --- /dev/null +++ b/tests/fixtures/parity/expected/verify__batch_no_credits_402.json @@ -0,0 +1,28 @@ +{ + "error": { + "cause": "Insufficient credits for batch.", + "code": "no_credits", + "cost": 10, + "credit_balance": 0, + "doc_url": "https://lenz.io/docs/billing", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "friendly_text": "Insufficient credits for batch.\n Fix: Top up or upgrade at https://lenz.io/plans, or wait for the period reset. See https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "message": "Insufficient credits for batch.", + "payload_json": { + "error": { + "code": "no_credits", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "message": "Insufficient credits for batch.", + "status": 402, + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } + }, + "remaining": 0, + "request_id": "", + "requested": 1, + "resets_at": "2026-10-01T14:07:00+00:00", + "status_code": 402, + "type": "LenzQuotaExceededError", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } +} diff --git a/tests/fixtures/parity/expected/verify__batch_partial_202.json b/tests/fixtures/parity/expected/verify__batch_partial_202.json new file mode 100644 index 0000000..8a4a0ba --- /dev/null +++ b/tests/fixtures/parity/expected/verify__batch_partial_202.json @@ -0,0 +1,24 @@ +{ + "dump": { + "batch_id": "7ea9cdbd4064e3cf", + "items": [ + { + "claim_text": "First claim.", + "task_id": "7cff18da2d979d6370e54a160be121ad" + } + ], + "partial": true + }, + "dump_unset": { + "batch_id": "7ea9cdbd4064e3cf", + "items": [ + { + "claim_text": "First claim.", + "task_id": "7cff18da2d979d6370e54a160be121ad" + } + ], + "partial": true + }, + "render_json": null, + "repr": "BatchAccepted(batch_id='7ea9cdbd4064e3cf', items=[TaskAccepted(task_id='7cff18da2d979d6370e54a160be121ad', claim_text='First claim.')], partial=True)" +} diff --git a/tests/fixtures/parity/expected/verify__batch_too_many_422.json b/tests/fixtures/parity/expected/verify__batch_too_many_422.json new file mode 100644 index 0000000..c07dafe --- /dev/null +++ b/tests/fixtures/parity/expected/verify__batch_too_many_422.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Batch size exceeds maximum of 20.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Batch size exceeds maximum of 20.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Batch size exceeds maximum of 20.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Batch size exceeds maximum of 20.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/verify__blank_claim_422.json b/tests/fixtures/parity/expected/verify__blank_claim_422.json new file mode 100644 index 0000000..872ff11 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__blank_claim_422.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Text is required.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Text is required.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Text is required.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Text is required.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/verify__capacity_503.json b/tests/fixtures/parity/expected/verify__capacity_503.json new file mode 100644 index 0000000..11cc917 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__capacity_503.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "doc_url": "https://lenz.io/docs/errors#unavailable", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "status": 503 + } + }, + "request_id": "", + "retry_after": null, + "status_code": 503, + "type": "LenzUpstreamUnavailableError" + } +} diff --git a/tests/fixtures/parity/expected/verify__delete_200.json b/tests/fixtures/parity/expected/verify__delete_200.json new file mode 100644 index 0000000..a75769b --- /dev/null +++ b/tests/fixtures/parity/expected/verify__delete_200.json @@ -0,0 +1,12 @@ +{ + "dump": { + "claim_text": "", + "ok": true, + "task_id": "" + }, + "dump_unset": { + "ok": true + }, + "render_json": null, + "repr": "TaskAccepted(task_id='', claim_text='', ok=True)" +} diff --git a/tests/fixtures/parity/expected/verify__delete_404.json b/tests/fixtures/parity/expected/verify__delete_404.json new file mode 100644 index 0000000..41573fe --- /dev/null +++ b/tests/fixtures/parity/expected/verify__delete_404.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Not found.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/verify__delete_not_yours_404.json b/tests/fixtures/parity/expected/verify__delete_not_yours_404.json new file mode 100644 index 0000000..41573fe --- /dev/null +++ b/tests/fixtures/parity/expected/verify__delete_not_yours_404.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Not found.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/verify__idempotency_body_mismatch_422.json b/tests/fixtures/parity/expected/verify__idempotency_body_mismatch_422.json new file mode 100644 index 0000000..989af48 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__idempotency_body_mismatch_422.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Idempotency-Key reused with a different request body.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Idempotency-Key reused with a different request body.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Idempotency-Key reused with a different request body.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Idempotency-Key reused with a different request body.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/verify__idempotency_conflict_409.json b/tests/fixtures/parity/expected/verify__idempotency_conflict_409.json new file mode 100644 index 0000000..54ca3d5 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__idempotency_conflict_409.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "A request with this Idempotency-Key is already in progress.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "A request with this Idempotency-Key is already in progress.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "A request with this Idempotency-Key is already in progress.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "A request with this Idempotency-Key is already in progress.", + "status": 409 + } + }, + "request_id": "", + "status_code": 409, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/verify__idempotency_key_replay.json b/tests/fixtures/parity/expected/verify__idempotency_key_replay.json new file mode 100644 index 0000000..74a0269 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__idempotency_key_replay.json @@ -0,0 +1,15 @@ +{ + "dump": { + "chain_id": "99a0a9ca89e1e72c", + "claim_text": "", + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "chain_id": "99a0a9ca89e1e72c", + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render_json": null, + "repr": "TaskAccepted(task_id='7cff18da2d979d6370e54a160be121ad', claim_text='', status='queued', chain_id='99a0a9ca89e1e72c')" +} diff --git a/tests/fixtures/parity/expected/verify__implicit_dedup_200.json b/tests/fixtures/parity/expected/verify__implicit_dedup_200.json new file mode 100644 index 0000000..a7ae9ac --- /dev/null +++ b/tests/fixtures/parity/expected/verify__implicit_dedup_200.json @@ -0,0 +1,13 @@ +{ + "dump": { + "claim_text": "", + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render_json": null, + "repr": "TaskAccepted(task_id='7cff18da2d979d6370e54a160be121ad', claim_text='', status='queued')" +} diff --git a/tests/fixtures/parity/expected/verify__implicit_repeat_replay.json b/tests/fixtures/parity/expected/verify__implicit_repeat_replay.json new file mode 100644 index 0000000..74a0269 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__implicit_repeat_replay.json @@ -0,0 +1,15 @@ +{ + "dump": { + "chain_id": "99a0a9ca89e1e72c", + "claim_text": "", + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "chain_id": "99a0a9ca89e1e72c", + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render_json": null, + "repr": "TaskAccepted(task_id='7cff18da2d979d6370e54a160be121ad', claim_text='', status='queued', chain_id='99a0a9ca89e1e72c')" +} diff --git a/tests/fixtures/parity/expected/verify__invalid_depth_422.json b/tests/fixtures/parity/expected/verify__invalid_depth_422.json new file mode 100644 index 0000000..128dad2 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__invalid_depth_422.json @@ -0,0 +1,35 @@ +{ + "error": { + "cause": "[{'type': 'literal_error', 'loc': ['body', 'payload', 'depth'], 'msg': \"Input should be 'standard' or 'low'\", 'ctx': {'expected': \"'standard' or 'low'\"}}]", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "ctx": { + "expected": "'standard' or 'low'" + }, + "loc": [ + "body", + "payload", + "depth" + ], + "msg": "Input should be 'standard' or 'low'", + "type": "literal_error" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "[{'type': 'literal_error', 'loc': ['body', 'payload', 'depth'], 'msg': \"Input should be 'standard' or 'low'\", 'ctx': {'expected': \"'standard' or 'low'\"}}]\n Fix: Check the request body against the OpenAPI spec.", + "message": "[{'type': 'literal_error', 'loc': ['body', 'payload', 'depth'], 'msg': \"Input should be 'standard' or 'low'\", 'ctx': {'expected': \"'standard' or 'low'\"}}]", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "[{'type': 'literal_error', 'loc': ['body', 'payload', 'depth'], 'msg': \"Input should be 'standard' or 'low'\", 'ctx': {'expected': \"'standard' or 'low'\"}}]", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/verify__invalid_language_422.json b/tests/fixtures/parity/expected/verify__invalid_language_422.json new file mode 100644 index 0000000..b5218f2 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__invalid_language_422.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Unsupported language 'xx-not-a-language'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Unsupported language 'xx-not-a-language'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Unsupported language 'xx-not-a-language'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Unsupported language 'xx-not-a-language'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/verify__list_200.json b/tests/fixtures/parity/expected/verify__list_200.json new file mode 100644 index 0000000..ce1a3f5 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__list_200.json @@ -0,0 +1,78 @@ +{ + "dump": { + "items": [ + { + "claim": "The Earth is round.", + "confidence": "high", + "created_at": "2026-10-01T09:07:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + }, + { + "claim": "The Earth is round.", + "confidence": "high", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "4d44dfaf" + } + ], + "page": 1, + "page_size": 20, + "total": 2 + }, + "dump_unset": { + "items": [ + { + "claim": "The Earth is round.", + "confidence": "high", + "created_at": "2026-10-01T09:07:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + }, + { + "claim": "The Earth is round.", + "confidence": "high", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "4d44dfaf" + } + ], + "page": 1, + "page_size": 20, + "total": 2 + }, + "render_json": null, + "repr": "VerificationList(items=[VerificationListItem(verification_id='68ca4aaf', claim='The Earth is round.', domain='Science', entities=[], verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', suggested_rewrite=None, created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en'), VerificationListItem(verification_id='4d44dfaf', claim='The Earth is round.', domain='Science', entities=[], verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', suggested_rewrite=None, created_at='2026-10-01T09:14:00.123456+00:00', modified_at=None, language='en')], total=2, page=1, page_size=20)" +} diff --git a/tests/fixtures/parity/expected/verify__list_200_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/expected/verify__list_200_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..0483d52 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__list_200_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,48 @@ +{ + "dump": { + "items": [ + { + "claim": "The Earth is round.", + "confidence": "high", + "created_at": "2026-10-01T23:55:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + } + ], + "page": 1, + "page_size": 20, + "total": 1 + }, + "dump_unset": { + "items": [ + { + "claim": "The Earth is round.", + "confidence": "high", + "created_at": "2026-10-01T23:55:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + } + ], + "page": 1, + "page_size": 20, + "total": 1 + }, + "render_json": null, + "repr": "VerificationList(items=[VerificationListItem(verification_id='68ca4aaf', claim='The Earth is round.', domain='Science', entities=[], verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', suggested_rewrite=None, created_at='2026-10-01T23:55:00.123456+00:00', modified_at='2026-10-02T00:03:00.123456+00:00', language='en')], total=1, page=1, page_size=20)" +} diff --git a/tests/fixtures/parity/expected/verify__list_200_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/expected/verify__list_200_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..43c5712 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__list_200_modified_at_same_day_hours_apart.json @@ -0,0 +1,48 @@ +{ + "dump": { + "items": [ + { + "claim": "The Earth is round.", + "confidence": "high", + "created_at": "2026-10-01T08:00:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + } + ], + "page": 1, + "page_size": 20, + "total": 1 + }, + "dump_unset": { + "items": [ + { + "claim": "The Earth is round.", + "confidence": "high", + "created_at": "2026-10-01T08:00:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + } + ], + "page": 1, + "page_size": 20, + "total": 1 + }, + "render_json": null, + "repr": "VerificationList(items=[VerificationListItem(verification_id='68ca4aaf', claim='The Earth is round.', domain='Science', entities=[], verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', suggested_rewrite=None, created_at='2026-10-01T08:00:00.123456+00:00', modified_at=None, language='en')], total=1, page=1, page_size=20)" +} diff --git a/tests/fixtures/parity/expected/verify__list_clamped_200.json b/tests/fixtures/parity/expected/verify__list_clamped_200.json new file mode 100644 index 0000000..5f47a1d --- /dev/null +++ b/tests/fixtures/parity/expected/verify__list_clamped_200.json @@ -0,0 +1,16 @@ +{ + "dump": { + "items": [], + "page": 1, + "page_size": 100, + "total": 0 + }, + "dump_unset": { + "items": [], + "page": 1, + "page_size": 100, + "total": 0 + }, + "render_json": null, + "repr": "VerificationList(items=[], total=0, page=1, page_size=100)" +} diff --git a/tests/fixtures/parity/expected/verify__list_empty_200.json b/tests/fixtures/parity/expected/verify__list_empty_200.json new file mode 100644 index 0000000..a0747d2 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__list_empty_200.json @@ -0,0 +1,16 @@ +{ + "dump": { + "items": [], + "page": 1, + "page_size": 20, + "total": 0 + }, + "dump_unset": { + "items": [], + "page": 1, + "page_size": 20, + "total": 0 + }, + "render_json": null, + "repr": "VerificationList(items=[], total=0, page=1, page_size=20)" +} diff --git a/tests/fixtures/parity/expected/verify__list_page2_200.json b/tests/fixtures/parity/expected/verify__list_page2_200.json new file mode 100644 index 0000000..e2682ef --- /dev/null +++ b/tests/fixtures/parity/expected/verify__list_page2_200.json @@ -0,0 +1,48 @@ +{ + "dump": { + "items": [ + { + "claim": "The Earth is round.", + "confidence": "high", + "created_at": "2026-10-01T09:07:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + } + ], + "page": 2, + "page_size": 2, + "total": 3 + }, + "dump_unset": { + "items": [ + { + "claim": "The Earth is round.", + "confidence": "high", + "created_at": "2026-10-01T09:07:00.123456+00:00", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf" + } + ], + "page": 2, + "page_size": 2, + "total": 3 + }, + "render_json": null, + "repr": "VerificationList(items=[VerificationListItem(verification_id='68ca4aaf', claim='The Earth is round.', domain='Science', entities=[], verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', suggested_rewrite=None, created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en')], total=3, page=2, page_size=2)" +} diff --git a/tests/fixtures/parity/expected/verify__misnamed_field_422.json b/tests/fixtures/parity/expected/verify__misnamed_field_422.json new file mode 100644 index 0000000..6760d1a --- /dev/null +++ b/tests/fixtures/parity/expected/verify__misnamed_field_422.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required", + "type": "missing" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]\n Fix: Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/verify__missing_claim_422.json b/tests/fixtures/parity/expected/verify__missing_claim_422.json new file mode 100644 index 0000000..6760d1a --- /dev/null +++ b/tests/fixtures/parity/expected/verify__missing_claim_422.json @@ -0,0 +1,32 @@ +{ + "error": { + "cause": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required", + "type": "missing" + } + ], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]\n Fix: Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "[{'type': 'missing', 'loc': ['body', 'payload', 'text'], 'msg': 'Field required'}]", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/verify__no_credits_402.json b/tests/fixtures/parity/expected/verify__no_credits_402.json new file mode 100644 index 0000000..f16364a --- /dev/null +++ b/tests/fixtures/parity/expected/verify__no_credits_402.json @@ -0,0 +1,28 @@ +{ + "error": { + "cause": "No remaining claim checks.", + "code": "no_credits", + "cost": 10, + "credit_balance": 0, + "doc_url": "https://lenz.io/docs/billing", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "friendly_text": "No remaining claim checks.\n Fix: Top up or upgrade at https://lenz.io/plans, or wait for the period reset. See https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "message": "No remaining claim checks.", + "payload_json": { + "error": { + "code": "no_credits", + "fix": "Top up or upgrade at https://lenz.io/plans, or wait for the period reset.", + "message": "No remaining claim checks.", + "status": 402, + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } + }, + "remaining": 0, + "request_id": "", + "requested": null, + "resets_at": "2026-10-01T14:07:00+00:00", + "status_code": 402, + "type": "LenzQuotaExceededError", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57" + } +} diff --git a/tests/fixtures/parity/expected/verify__replay_later_202.json b/tests/fixtures/parity/expected/verify__replay_later_202.json new file mode 100644 index 0000000..74a0269 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__replay_later_202.json @@ -0,0 +1,15 @@ +{ + "dump": { + "chain_id": "99a0a9ca89e1e72c", + "claim_text": "", + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "chain_id": "99a0a9ca89e1e72c", + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render_json": null, + "repr": "TaskAccepted(task_id='7cff18da2d979d6370e54a160be121ad', claim_text='', status='queued', chain_id='99a0a9ca89e1e72c')" +} diff --git a/tests/fixtures/parity/expected/verify__select_202.json b/tests/fixtures/parity/expected/verify__select_202.json new file mode 100644 index 0000000..1f9894c --- /dev/null +++ b/tests/fixtures/parity/expected/verify__select_202.json @@ -0,0 +1,30 @@ +{ + "dump": { + "batch_id": "7ea9cdbd4064e3cf", + "items": [ + { + "claim_text": "The Earth is round.", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + { + "claim_text": "Water boils at 100C at sea level.", + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be" + } + ] + }, + "dump_unset": { + "batch_id": "7ea9cdbd4064e3cf", + "items": [ + { + "claim_text": "The Earth is round.", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + { + "claim_text": "Water boils at 100C at sea level.", + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be" + } + ] + }, + "render_json": null, + "repr": "BatchAccepted(batch_id='7ea9cdbd4064e3cf', items=[TaskAccepted(task_id='7cff18da2d979d6370e54a160be121ad', claim_text='The Earth is round.'), TaskAccepted(task_id='0b92b443eb69b9c71434fdc64f2ca8be', claim_text='Water boils at 100C at sea level.')])" +} diff --git a/tests/fixtures/parity/expected/verify__select_empty_422.json b/tests/fixtures/parity/expected/verify__select_empty_422.json new file mode 100644 index 0000000..975cb65 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__select_empty_422.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "texts is required and must be non-empty.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "texts is required and must be non-empty.\n Fix: Check the request body against the OpenAPI spec.", + "message": "texts is required and must be non-empty.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "texts is required and must be non-empty.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/verify__select_invalid_selection_422.json b/tests/fixtures/parity/expected/verify__select_invalid_selection_422.json new file mode 100644 index 0000000..1a020a2 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__select_invalid_selection_422.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Selected text was not one of the offered claims: 'The Moon is made of cheese.'", + "code": "invalid_selection", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Selected text was not one of the offered claims: 'The Moon is made of cheese.'\n Fix: Check the request body against the OpenAPI spec.", + "message": "Selected text was not one of the offered claims: 'The Moon is made of cheese.'", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Selected text was not one of the offered claims: 'The Moon is made of cheese.'", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/verify__select_no_selection_pending_409.json b/tests/fixtures/parity/expected/verify__select_no_selection_pending_409.json new file mode 100644 index 0000000..fd4d147 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__select_no_selection_pending_409.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "This task has no pending claim selection.", + "code": "no_selection_pending", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "This task has no pending claim selection.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "This task has no pending claim selection.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "This task has no pending claim selection.", + "status": 409 + } + }, + "request_id": "", + "status_code": 409, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/verify__select_too_many_422.json b/tests/fixtures/parity/expected/verify__select_too_many_422.json new file mode 100644 index 0000000..9a93a10 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__select_too_many_422.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "Cannot select more than 20 claims.", + "code": "", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "Cannot select more than 20 claims.\n Fix: Check the request body against the OpenAPI spec.", + "message": "Cannot select more than 20 claims.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "Cannot select more than 20 claims.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/verify__select_unknown_task_404.json b/tests/fixtures/parity/expected/verify__select_unknown_task_404.json new file mode 100644 index 0000000..68a468c --- /dev/null +++ b/tests/fixtures/parity/expected/verify__select_unknown_task_404.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Task not found.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Task not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Task not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Task not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_cancelled_after_a_while.json b/tests/fixtures/parity/expected/verify__status_cancelled_after_a_while.json new file mode 100644 index 0000000..820dfc6 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_cancelled_after_a_while.json @@ -0,0 +1,61 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "https://lenz.io/docs/errors#cancelled", + "error": "Cancelled.", + "failure_class": "cancelled", + "failure_detail": "", + "failure_reason": "cancelled", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": null, + "retryable": false, + "similar_claims": [], + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "docs_url": "https://lenz.io/docs/errors#cancelled", + "error": "Cancelled.", + "failure_class": "cancelled", + "failure_reason": "cancelled", + "retryable": false, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "failed — Cancelled.\n", + "render_json": "{\n \"status\": \"failed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": null,\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"Cancelled.\",\n \"failure_reason\": \"cancelled\",\n \"failure_detail\": \"\",\n \"failure_class\": \"cancelled\",\n \"retryable\": false,\n \"docs_url\": \"https://lenz.io/docs/errors#cancelled\"\n}\n", + "repr": "TaskStatus(status='failed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=None, claims=[], candidates=[], similar_claims=[], error='Cancelled.', failure_reason='cancelled', failure_detail='', failure_class='cancelled', retryable=False, docs_url='https://lenz.io/docs/errors#cancelled')", + "wait": { + "cause": "Cancelled.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "failure_class": "cancelled", + "failure_reason": "cancelled", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "friendly_text": "Pipeline failed: Cancelled.\n Fix: Retry with a different claim, or check status.error for the diagnostic.", + "hint": "", + "message": "Pipeline failed: Cancelled.", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "message": "Pipeline failed: Cancelled.", + "status": 0 + } + }, + "request_id": "", + "retryable": false, + "status_code": 0, + "task_id": "t", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_completed.json b/tests/fixtures/parity/expected/verify__status_completed.json new file mode 100644 index 0000000..9f88760 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_completed.json @@ -0,0 +1,295 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "", + "error": "", + "failure_class": "", + "failure_detail": "", + "failure_reason": "", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "retryable": null, + "similar_claims": [], + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "True (high) score 9/10\n\nverification_id: 68ca4aaf\nfull report: lenz show 68ca4aaf\n", + "render_json": "{\n \"status\": \"completed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": {\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T09:07:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n },\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"\",\n \"failure_reason\": \"\",\n \"failure_detail\": \"\",\n \"failure_class\": \"\",\n \"retryable\": null,\n \"docs_url\": \"\"\n}\n", + "render_verification": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "repr": "TaskStatus(status='completed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1')), claims=[], candidates=[], similar_claims=[], error='', failure_reason='', failure_detail='', failure_class='', retryable=None, docs_url='')", + "wait": { + "returned": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + } + } +} diff --git a/tests/fixtures/parity/expected/verify__status_completed_after_a_while.json b/tests/fixtures/parity/expected/verify__status_completed_after_a_while.json new file mode 100644 index 0000000..9f88760 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_completed_after_a_while.json @@ -0,0 +1,295 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "", + "error": "", + "failure_class": "", + "failure_detail": "", + "failure_reason": "", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "retryable": null, + "similar_claims": [], + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "True (high) score 9/10\n\nverification_id: 68ca4aaf\nfull report: lenz show 68ca4aaf\n", + "render_json": "{\n \"status\": \"completed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": {\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T09:07:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n },\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"\",\n \"failure_reason\": \"\",\n \"failure_detail\": \"\",\n \"failure_class\": \"\",\n \"retryable\": null,\n \"docs_url\": \"\"\n}\n", + "render_verification": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "repr": "TaskStatus(status='completed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1')), claims=[], candidates=[], similar_claims=[], error='', failure_reason='', failure_detail='', failure_class='', retryable=None, docs_url='')", + "wait": { + "returned": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + } + } +} diff --git a/tests/fixtures/parity/expected/verify__status_completed_after_a_while_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/expected/verify__status_completed_after_a_while_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..fd6df30 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_completed_after_a_while_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,295 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "", + "error": "", + "failure_class": "", + "failure_detail": "", + "failure_reason": "", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "retryable": null, + "similar_claims": [], + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "True (high) score 9/10\n\nverification_id: 68ca4aaf\nfull report: lenz show 68ca4aaf\n", + "render_json": "{\n \"status\": \"completed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": {\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T23:55:00.123456+00:00\",\n \"modified_at\": \"2026-10-02T00:03:00.123456+00:00\",\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n },\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"\",\n \"failure_reason\": \"\",\n \"failure_detail\": \"\",\n \"failure_class\": \"\",\n \"retryable\": null,\n \"docs_url\": \"\"\n}\n", + "render_verification": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "repr": "TaskStatus(status='completed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T23:55:00.123456+00:00', modified_at='2026-10-02T00:03:00.123456+00:00', language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1')), claims=[], candidates=[], similar_claims=[], error='', failure_reason='', failure_detail='', failure_class='', retryable=None, docs_url='')", + "wait": { + "returned": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + } + } +} diff --git a/tests/fixtures/parity/expected/verify__status_completed_after_a_while_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/expected/verify__status_completed_after_a_while_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..b935bd9 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_completed_after_a_while_modified_at_same_day_hours_apart.json @@ -0,0 +1,295 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "", + "error": "", + "failure_class": "", + "failure_detail": "", + "failure_reason": "", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "retryable": null, + "similar_claims": [], + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "True (high) score 9/10\n\nverification_id: 68ca4aaf\nfull report: lenz show 68ca4aaf\n", + "render_json": "{\n \"status\": \"completed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": {\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T08:00:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n },\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"\",\n \"failure_reason\": \"\",\n \"failure_detail\": \"\",\n \"failure_class\": \"\",\n \"retryable\": null,\n \"docs_url\": \"\"\n}\n", + "render_verification": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "repr": "TaskStatus(status='completed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T08:00:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1')), claims=[], candidates=[], similar_claims=[], error='', failure_reason='', failure_detail='', failure_class='', retryable=None, docs_url='')", + "wait": { + "returned": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + } + } +} diff --git a/tests/fixtures/parity/expected/verify__status_completed_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/expected/verify__status_completed_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..fd6df30 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_completed_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,295 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "", + "error": "", + "failure_class": "", + "failure_detail": "", + "failure_reason": "", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "retryable": null, + "similar_claims": [], + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "True (high) score 9/10\n\nverification_id: 68ca4aaf\nfull report: lenz show 68ca4aaf\n", + "render_json": "{\n \"status\": \"completed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": {\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T23:55:00.123456+00:00\",\n \"modified_at\": \"2026-10-02T00:03:00.123456+00:00\",\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n },\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"\",\n \"failure_reason\": \"\",\n \"failure_detail\": \"\",\n \"failure_class\": \"\",\n \"retryable\": null,\n \"docs_url\": \"\"\n}\n", + "render_verification": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "repr": "TaskStatus(status='completed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T23:55:00.123456+00:00', modified_at='2026-10-02T00:03:00.123456+00:00', language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1')), claims=[], candidates=[], similar_claims=[], error='', failure_reason='', failure_detail='', failure_class='', retryable=None, docs_url='')", + "wait": { + "returned": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + } + } +} diff --git a/tests/fixtures/parity/expected/verify__status_completed_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/expected/verify__status_completed_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..b935bd9 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_completed_modified_at_same_day_hours_apart.json @@ -0,0 +1,295 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "", + "error": "", + "failure_class": "", + "failure_detail": "", + "failure_reason": "", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "retryable": null, + "similar_claims": [], + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "True (high) score 9/10\n\nverification_id: 68ca4aaf\nfull report: lenz show 68ca4aaf\n", + "render_json": "{\n \"status\": \"completed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": {\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T08:00:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n },\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"\",\n \"failure_reason\": \"\",\n \"failure_detail\": \"\",\n \"failure_class\": \"\",\n \"retryable\": null,\n \"docs_url\": \"\"\n}\n", + "render_verification": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "repr": "TaskStatus(status='completed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T08:00:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1')), claims=[], candidates=[], similar_claims=[], error='', failure_reason='', failure_detail='', failure_class='', retryable=None, docs_url='')", + "wait": { + "returned": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + } + } +} diff --git a/tests/fixtures/parity/expected/verify__status_failed.json b/tests/fixtures/parity/expected/verify__status_failed.json new file mode 100644 index 0000000..c550bd3 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_failed.json @@ -0,0 +1,61 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence", + "error": "Pipeline stopped at: research_empty", + "failure_class": "insufficient_evidence", + "failure_detail": "", + "failure_reason": "research_empty", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": null, + "retryable": false, + "similar_claims": [], + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence", + "error": "Pipeline stopped at: research_empty", + "failure_class": "insufficient_evidence", + "failure_reason": "research_empty", + "retryable": false, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "failed — Pipeline stopped at: research_empty\n", + "render_json": "{\n \"status\": \"failed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": null,\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"Pipeline stopped at: research_empty\",\n \"failure_reason\": \"research_empty\",\n \"failure_detail\": \"\",\n \"failure_class\": \"insufficient_evidence\",\n \"retryable\": false,\n \"docs_url\": \"https://lenz.io/docs/errors#insufficient-evidence\"\n}\n", + "repr": "TaskStatus(status='failed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=None, claims=[], candidates=[], similar_claims=[], error='Pipeline stopped at: research_empty', failure_reason='research_empty', failure_detail='', failure_class='insufficient_evidence', retryable=False, docs_url='https://lenz.io/docs/errors#insufficient-evidence')", + "wait": { + "cause": "Pipeline stopped at: research_empty", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "failure_class": "insufficient_evidence", + "failure_reason": "research_empty", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "friendly_text": "Pipeline failed: Pipeline stopped at: research_empty\n Fix: Retry with a different claim, or check status.error for the diagnostic.", + "hint": "", + "message": "Pipeline failed: Pipeline stopped at: research_empty", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "message": "Pipeline failed: Pipeline stopped at: research_empty", + "status": 0 + } + }, + "request_id": "", + "retryable": false, + "status_code": 0, + "task_id": "t", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_failed_after_a_while.json b/tests/fixtures/parity/expected/verify__status_failed_after_a_while.json new file mode 100644 index 0000000..4714bed --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_failed_after_a_while.json @@ -0,0 +1,61 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "https://lenz.io/docs/errors#internal", + "error": "Pipeline stopped: conclusion_failed.", + "failure_class": "internal", + "failure_detail": "", + "failure_reason": "conclusion_failed", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": null, + "retryable": false, + "similar_claims": [], + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "docs_url": "https://lenz.io/docs/errors#internal", + "error": "Pipeline stopped: conclusion_failed.", + "failure_class": "internal", + "failure_reason": "conclusion_failed", + "retryable": false, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "failed — Pipeline stopped: conclusion_failed.\n", + "render_json": "{\n \"status\": \"failed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": null,\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"Pipeline stopped: conclusion_failed.\",\n \"failure_reason\": \"conclusion_failed\",\n \"failure_detail\": \"\",\n \"failure_class\": \"internal\",\n \"retryable\": false,\n \"docs_url\": \"https://lenz.io/docs/errors#internal\"\n}\n", + "repr": "TaskStatus(status='failed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=None, claims=[], candidates=[], similar_claims=[], error='Pipeline stopped: conclusion_failed.', failure_reason='conclusion_failed', failure_detail='', failure_class='internal', retryable=False, docs_url='https://lenz.io/docs/errors#internal')", + "wait": { + "cause": "Pipeline stopped: conclusion_failed.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "failure_class": "internal", + "failure_reason": "conclusion_failed", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "friendly_text": "Pipeline failed: Pipeline stopped: conclusion_failed.\n Fix: Retry with a different claim, or check status.error for the diagnostic.", + "hint": "", + "message": "Pipeline failed: Pipeline stopped: conclusion_failed.", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "message": "Pipeline failed: Pipeline stopped: conclusion_failed.", + "status": 0 + } + }, + "request_id": "", + "retryable": false, + "status_code": 0, + "task_id": "t", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_failed_after_a_while_framing.json b/tests/fixtures/parity/expected/verify__status_failed_after_a_while_framing.json new file mode 100644 index 0000000..635cdf9 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_failed_after_a_while_framing.json @@ -0,0 +1,61 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "error": "Pipeline stopped: framing_failed.", + "failure_class": "upstream_unavailable", + "failure_detail": "", + "failure_reason": "framing_failed", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": null, + "retryable": true, + "similar_claims": [], + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "error": "Pipeline stopped: framing_failed.", + "failure_class": "upstream_unavailable", + "failure_reason": "framing_failed", + "retryable": true, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "failed — Pipeline stopped: framing_failed.\n", + "render_json": "{\n \"status\": \"failed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": null,\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"Pipeline stopped: framing_failed.\",\n \"failure_reason\": \"framing_failed\",\n \"failure_detail\": \"\",\n \"failure_class\": \"upstream_unavailable\",\n \"retryable\": true,\n \"docs_url\": \"https://lenz.io/docs/errors#upstream-unavailable\"\n}\n", + "repr": "TaskStatus(status='failed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=None, claims=[], candidates=[], similar_claims=[], error='Pipeline stopped: framing_failed.', failure_reason='framing_failed', failure_detail='', failure_class='upstream_unavailable', retryable=True, docs_url='https://lenz.io/docs/errors#upstream-unavailable')", + "wait": { + "cause": "Pipeline stopped: framing_failed.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "failure_class": "upstream_unavailable", + "failure_reason": "framing_failed", + "fix": "Transient provider outage — retry the same request after a short wait.", + "friendly_text": "Pipeline failed: Pipeline stopped: framing_failed.\n Fix: Transient provider outage — retry the same request after a short wait.", + "hint": "", + "message": "Pipeline failed: Pipeline stopped: framing_failed.", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Transient provider outage — retry the same request after a short wait.", + "message": "Pipeline failed: Pipeline stopped: framing_failed.", + "status": 0 + } + }, + "request_id": "", + "retryable": true, + "status_code": 0, + "task_id": "t", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_failed_retryable.json b/tests/fixtures/parity/expected/verify__status_failed_retryable.json new file mode 100644 index 0000000..f49b1cc --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_failed_retryable.json @@ -0,0 +1,61 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "error": "Pipeline stopped at: adjudication_failed", + "failure_class": "upstream_unavailable", + "failure_detail": "", + "failure_reason": "adjudication_failed", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": null, + "retryable": true, + "similar_claims": [], + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "error": "Pipeline stopped at: adjudication_failed", + "failure_class": "upstream_unavailable", + "failure_reason": "adjudication_failed", + "retryable": true, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "failed — Pipeline stopped at: adjudication_failed\n", + "render_json": "{\n \"status\": \"failed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": null,\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"Pipeline stopped at: adjudication_failed\",\n \"failure_reason\": \"adjudication_failed\",\n \"failure_detail\": \"\",\n \"failure_class\": \"upstream_unavailable\",\n \"retryable\": true,\n \"docs_url\": \"https://lenz.io/docs/errors#upstream-unavailable\"\n}\n", + "repr": "TaskStatus(status='failed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=None, claims=[], candidates=[], similar_claims=[], error='Pipeline stopped at: adjudication_failed', failure_reason='adjudication_failed', failure_detail='', failure_class='upstream_unavailable', retryable=True, docs_url='https://lenz.io/docs/errors#upstream-unavailable')", + "wait": { + "cause": "Pipeline stopped at: adjudication_failed", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "failure_class": "upstream_unavailable", + "failure_reason": "adjudication_failed", + "fix": "Transient provider outage — retry the same request after a short wait.", + "friendly_text": "Pipeline failed: Pipeline stopped at: adjudication_failed\n Fix: Transient provider outage — retry the same request after a short wait.", + "hint": "", + "message": "Pipeline failed: Pipeline stopped at: adjudication_failed", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Transient provider outage — retry the same request after a short wait.", + "message": "Pipeline failed: Pipeline stopped at: adjudication_failed", + "status": 0 + } + }, + "request_id": "", + "retryable": true, + "status_code": 0, + "task_id": "t", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_needs_input.json b/tests/fixtures/parity/expected/verify__status_needs_input.json new file mode 100644 index 0000000..0a1ff14 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_needs_input.json @@ -0,0 +1,107 @@ +{ + "dump": { + "candidates": [], + "claims": [ + { + "domain": "Science", + "text": "The Earth is round." + }, + { + "domain": "Science", + "text": "Water boils at 100C at sea level." + } + ], + "docs_url": "", + "error": "", + "failure_class": "", + "failure_detail": "", + "failure_reason": "", + "hint": "The text holds several distinct claims. Send the ones to check to POST /verify/{task_id}/select.", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "multi_claim", + "result": null, + "retryable": null, + "similar_claims": [], + "status": "needs_input", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "claims": [ + { + "domain": "Science", + "text": "The Earth is round." + }, + { + "domain": "Science", + "text": "Water boils at 100C at sea level." + } + ], + "hint": "The text holds several distinct claims. Send the ones to check to POST /verify/{task_id}/select.", + "reason": "multi_claim", + "status": "needs_input", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "needs input (multi_claim)\nclaims found:\n 1. The Earth is round.\n 2. Water boils at 100C at sea level.\nresolve it: lenz verify --resume t --claim --detach\n", + "render_json": "{\n \"status\": \"needs_input\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"multi_claim\",\n \"hint\": \"The text holds several distinct claims. Send the ones to check to POST /verify/{task_id}/select.\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": null,\n \"claims\": [\n {\n \"text\": \"The Earth is round.\",\n \"domain\": \"Science\"\n },\n {\n \"text\": \"Water boils at 100C at sea level.\",\n \"domain\": \"Science\"\n }\n ],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"\",\n \"failure_reason\": \"\",\n \"failure_detail\": \"\",\n \"failure_class\": \"\",\n \"retryable\": null,\n \"docs_url\": \"\"\n}\n", + "repr": "TaskStatus(status='needs_input', task_id='7cff18da2d979d6370e54a160be121ad', reason='multi_claim', hint='The text holds several distinct claims. Send the ones to check to POST /verify/{task_id}/select.', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=None, claims=[CandidateClaim(text='The Earth is round.', domain='Science'), CandidateClaim(text='Water boils at 100C at sea level.', domain='Science')], candidates=[], similar_claims=[], error='', failure_reason='', failure_detail='', failure_class='', retryable=None, docs_url='')", + "wait": { + "cause": "The verification needs caller input to proceed.", + "code": "", + "doc_url": "https://lenz.io/docs/verify#needs-input", + "fix": "Inspect the payload, then call client.select(task_id, texts=[...]) with the chosen claim(s).", + "friendly_text": "Pipeline paused: multi_claim\n Fix: Inspect the payload, then call client.select(task_id, texts=[...]) with the chosen claim(s).", + "hint": "The text holds several distinct claims. Send the ones to check to POST /verify/{task_id}/select.", + "kind": "multi_claim", + "message": "Pipeline paused: multi_claim", + "payload": { + "candidates": [], + "claims": [ + { + "domain": "Science", + "text": "The Earth is round." + }, + { + "domain": "Science", + "text": "Water boils at 100C at sea level." + } + ], + "docs_url": "", + "error": "", + "failure_class": "", + "failure_detail": "", + "failure_reason": "", + "hint": "The text holds several distinct claims. Send the ones to check to POST /verify/{task_id}/select.", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "multi_claim", + "result": null, + "retryable": null, + "similar_claims": [], + "status": "needs_input", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "payload_json": { + "error": { + "code": "needs_input", + "fix": "Inspect the payload, then call client.select(task_id, texts=[...]) with the chosen claim(s).", + "message": "Pipeline paused: multi_claim", + "status": 0 + } + }, + "request_id": "", + "status_code": 0, + "task_id": "t", + "type": "LenzNeedsInputError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_not_a_claim.json b/tests/fixtures/parity/expected/verify__status_not_a_claim.json new file mode 100644 index 0000000..1007c6e --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_not_a_claim.json @@ -0,0 +1,62 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "error": "Not a verifiable claim.", + "failure_class": "invalid_input", + "failure_detail": "", + "failure_reason": "not_a_claim", + "hint": "The input is a greeting, not a statement that can be checked. Send one factual claim, or run the text through /extract to enumerate its claims.", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": null, + "retryable": false, + "similar_claims": [], + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "error": "Not a verifiable claim.", + "failure_class": "invalid_input", + "failure_reason": "not_a_claim", + "hint": "The input is a greeting, not a statement that can be checked. Send one factual claim, or run the text through /extract to enumerate its claims.", + "retryable": false, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "failed — Not a verifiable claim.\n", + "render_json": "{\n \"status\": \"failed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"The input is a greeting, not a statement that can be checked. Send one factual claim, or run the text through /extract to enumerate its claims.\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": null,\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"Not a verifiable claim.\",\n \"failure_reason\": \"not_a_claim\",\n \"failure_detail\": \"\",\n \"failure_class\": \"invalid_input\",\n \"retryable\": false,\n \"docs_url\": \"https://lenz.io/docs/errors#invalid-input\"\n}\n", + "repr": "TaskStatus(status='failed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='The input is a greeting, not a statement that can be checked. Send one factual claim, or run the text through /extract to enumerate its claims.', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=None, claims=[], candidates=[], similar_claims=[], error='Not a verifiable claim.', failure_reason='not_a_claim', failure_detail='', failure_class='invalid_input', retryable=False, docs_url='https://lenz.io/docs/errors#invalid-input')", + "wait": { + "cause": "Not a verifiable claim.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "failure_class": "invalid_input", + "failure_reason": "not_a_claim", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "friendly_text": "Pipeline failed: Not a verifiable claim.\n Fix: Retry with a different claim, or check status.error for the diagnostic.", + "hint": "The input is a greeting, not a statement that can be checked. Send one factual claim, or run the text through /extract to enumerate its claims.", + "message": "Pipeline failed: Not a verifiable claim.", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "message": "Pipeline failed: Not a verifiable claim.", + "status": 0 + } + }, + "request_id": "", + "retryable": false, + "status_code": 0, + "task_id": "t", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_not_a_claim_after_a_while.json b/tests/fixtures/parity/expected/verify__status_not_a_claim_after_a_while.json new file mode 100644 index 0000000..d056d07 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_not_a_claim_after_a_while.json @@ -0,0 +1,61 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "error": "Pipeline stopped: not_a_claim.", + "failure_class": "invalid_input", + "failure_detail": "", + "failure_reason": "not_a_claim", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": null, + "retryable": false, + "similar_claims": [], + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "error": "Pipeline stopped: not_a_claim.", + "failure_class": "invalid_input", + "failure_reason": "not_a_claim", + "retryable": false, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "failed — Pipeline stopped: not_a_claim.\n", + "render_json": "{\n \"status\": \"failed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": null,\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"Pipeline stopped: not_a_claim.\",\n \"failure_reason\": \"not_a_claim\",\n \"failure_detail\": \"\",\n \"failure_class\": \"invalid_input\",\n \"retryable\": false,\n \"docs_url\": \"https://lenz.io/docs/errors#invalid-input\"\n}\n", + "repr": "TaskStatus(status='failed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=None, claims=[], candidates=[], similar_claims=[], error='Pipeline stopped: not_a_claim.', failure_reason='not_a_claim', failure_detail='', failure_class='invalid_input', retryable=False, docs_url='https://lenz.io/docs/errors#invalid-input')", + "wait": { + "cause": "Pipeline stopped: not_a_claim.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "failure_class": "invalid_input", + "failure_reason": "not_a_claim", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "friendly_text": "Pipeline failed: Pipeline stopped: not_a_claim.\n Fix: Retry with a different claim, or check status.error for the diagnostic.", + "hint": "", + "message": "Pipeline failed: Pipeline stopped: not_a_claim.", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "message": "Pipeline failed: Pipeline stopped: not_a_claim.", + "status": 0 + } + }, + "request_id": "", + "retryable": false, + "status_code": 0, + "task_id": "t", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_not_yours_404.json b/tests/fixtures/parity/expected/verify__status_not_yours_404.json new file mode 100644 index 0000000..68a468c --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_not_yours_404.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Task not found.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Task not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Task not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Task not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_older_run_completed.json b/tests/fixtures/parity/expected/verify__status_older_run_completed.json new file mode 100644 index 0000000..9f88760 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_older_run_completed.json @@ -0,0 +1,295 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "", + "error": "", + "failure_class": "", + "failure_detail": "", + "failure_reason": "", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "retryable": null, + "similar_claims": [], + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "result": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "True (high) score 9/10\n\nverification_id: 68ca4aaf\nfull report: lenz show 68ca4aaf\n", + "render_json": "{\n \"status\": \"completed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": {\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T09:07:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n },\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"\",\n \"failure_reason\": \"\",\n \"failure_detail\": \"\",\n \"failure_class\": \"\",\n \"retryable\": null,\n \"docs_url\": \"\"\n}\n", + "render_verification": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "repr": "TaskStatus(status='completed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1')), claims=[], candidates=[], similar_claims=[], error='', failure_reason='', failure_detail='', failure_class='', retryable=None, docs_url='')", + "wait": { + "returned": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + } + } +} diff --git a/tests/fixtures/parity/expected/verify__status_older_run_failed_crashed.json b/tests/fixtures/parity/expected/verify__status_older_run_failed_crashed.json new file mode 100644 index 0000000..04bfe69 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_older_run_failed_crashed.json @@ -0,0 +1,61 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "https://lenz.io/docs/errors#internal", + "error": "Pipeline failed.", + "failure_class": "internal", + "failure_detail": "", + "failure_reason": "task_error", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": null, + "retryable": false, + "similar_claims": [], + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "docs_url": "https://lenz.io/docs/errors#internal", + "error": "Pipeline failed.", + "failure_class": "internal", + "failure_reason": "task_error", + "retryable": false, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "failed — Pipeline failed.\n", + "render_json": "{\n \"status\": \"failed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": null,\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"Pipeline failed.\",\n \"failure_reason\": \"task_error\",\n \"failure_detail\": \"\",\n \"failure_class\": \"internal\",\n \"retryable\": false,\n \"docs_url\": \"https://lenz.io/docs/errors#internal\"\n}\n", + "repr": "TaskStatus(status='failed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=None, claims=[], candidates=[], similar_claims=[], error='Pipeline failed.', failure_reason='task_error', failure_detail='', failure_class='internal', retryable=False, docs_url='https://lenz.io/docs/errors#internal')", + "wait": { + "cause": "Pipeline failed.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "failure_class": "internal", + "failure_reason": "task_error", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "friendly_text": "Pipeline failed: Pipeline failed.\n Fix: Retry with a different claim, or check status.error for the diagnostic.", + "hint": "", + "message": "Pipeline failed: Pipeline failed.", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "message": "Pipeline failed: Pipeline failed.", + "status": 0 + } + }, + "request_id": "", + "retryable": false, + "status_code": 0, + "task_id": "t", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_older_run_failed_insufficient_evidence.json b/tests/fixtures/parity/expected/verify__status_older_run_failed_insufficient_evidence.json new file mode 100644 index 0000000..c550bd3 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_older_run_failed_insufficient_evidence.json @@ -0,0 +1,61 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence", + "error": "Pipeline stopped at: research_empty", + "failure_class": "insufficient_evidence", + "failure_detail": "", + "failure_reason": "research_empty", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": null, + "retryable": false, + "similar_claims": [], + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence", + "error": "Pipeline stopped at: research_empty", + "failure_class": "insufficient_evidence", + "failure_reason": "research_empty", + "retryable": false, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "failed — Pipeline stopped at: research_empty\n", + "render_json": "{\n \"status\": \"failed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": null,\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"Pipeline stopped at: research_empty\",\n \"failure_reason\": \"research_empty\",\n \"failure_detail\": \"\",\n \"failure_class\": \"insufficient_evidence\",\n \"retryable\": false,\n \"docs_url\": \"https://lenz.io/docs/errors#insufficient-evidence\"\n}\n", + "repr": "TaskStatus(status='failed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=None, claims=[], candidates=[], similar_claims=[], error='Pipeline stopped at: research_empty', failure_reason='research_empty', failure_detail='', failure_class='insufficient_evidence', retryable=False, docs_url='https://lenz.io/docs/errors#insufficient-evidence')", + "wait": { + "cause": "Pipeline stopped at: research_empty", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "failure_class": "insufficient_evidence", + "failure_reason": "research_empty", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "friendly_text": "Pipeline failed: Pipeline stopped at: research_empty\n Fix: Retry with a different claim, or check status.error for the diagnostic.", + "hint": "", + "message": "Pipeline failed: Pipeline stopped at: research_empty", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "message": "Pipeline failed: Pipeline stopped at: research_empty", + "status": 0 + } + }, + "request_id": "", + "retryable": false, + "status_code": 0, + "task_id": "t", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_older_run_in_progress.json b/tests/fixtures/parity/expected/verify__status_older_run_in_progress.json new file mode 100644 index 0000000..01a834c --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_older_run_in_progress.json @@ -0,0 +1,63 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "", + "error": "", + "failure_class": "", + "failure_detail": "", + "failure_reason": "", + "hint": "", + "progress": { + "elapsed_seconds": 1, + "index": 2, + "poll_after_seconds": 5, + "step": "research", + "total": 5 + }, + "reason": "", + "result": null, + "retryable": null, + "similar_claims": [], + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "progress": { + "elapsed_seconds": 1, + "index": 2, + "poll_after_seconds": 5, + "step": "research", + "total": 5 + }, + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "processing — Gathering evidence (2/5)\n", + "render_json": "{\n \"status\": \"processing\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"research\",\n \"index\": 2,\n \"total\": 5,\n \"elapsed_seconds\": 1,\n \"poll_after_seconds\": 5\n },\n \"result\": null,\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"\",\n \"failure_reason\": \"\",\n \"failure_detail\": \"\",\n \"failure_class\": \"\",\n \"retryable\": null,\n \"docs_url\": \"\"\n}\n", + "repr": "TaskStatus(status='processing', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='research', index=2, total=5, elapsed_seconds=1, poll_after_seconds=5), result=None, claims=[], candidates=[], similar_claims=[], error='', failure_reason='', failure_detail='', failure_class='', retryable=None, docs_url='')", + "wait": { + "cause": "unknown", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "failure_class": "", + "failure_reason": "", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "friendly_text": "Pipeline failed: unknown\n Fix: Retry with a different claim, or check status.error for the diagnostic.", + "hint": "", + "message": "Pipeline failed: unknown", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "message": "Pipeline failed: unknown", + "status": 0 + } + }, + "request_id": "", + "retryable": null, + "status_code": 0, + "task_id": "t", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_processing.json b/tests/fixtures/parity/expected/verify__status_processing.json new file mode 100644 index 0000000..01a834c --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_processing.json @@ -0,0 +1,63 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "", + "error": "", + "failure_class": "", + "failure_detail": "", + "failure_reason": "", + "hint": "", + "progress": { + "elapsed_seconds": 1, + "index": 2, + "poll_after_seconds": 5, + "step": "research", + "total": 5 + }, + "reason": "", + "result": null, + "retryable": null, + "similar_claims": [], + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "progress": { + "elapsed_seconds": 1, + "index": 2, + "poll_after_seconds": 5, + "step": "research", + "total": 5 + }, + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "processing — Gathering evidence (2/5)\n", + "render_json": "{\n \"status\": \"processing\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"research\",\n \"index\": 2,\n \"total\": 5,\n \"elapsed_seconds\": 1,\n \"poll_after_seconds\": 5\n },\n \"result\": null,\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"\",\n \"failure_reason\": \"\",\n \"failure_detail\": \"\",\n \"failure_class\": \"\",\n \"retryable\": null,\n \"docs_url\": \"\"\n}\n", + "repr": "TaskStatus(status='processing', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='research', index=2, total=5, elapsed_seconds=1, poll_after_seconds=5), result=None, claims=[], candidates=[], similar_claims=[], error='', failure_reason='', failure_detail='', failure_class='', retryable=None, docs_url='')", + "wait": { + "cause": "unknown", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "failure_class": "", + "failure_reason": "", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "friendly_text": "Pipeline failed: unknown\n Fix: Retry with a different claim, or check status.error for the diagnostic.", + "hint": "", + "message": "Pipeline failed: unknown", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "message": "Pipeline failed: unknown", + "status": 0 + } + }, + "request_id": "", + "retryable": null, + "status_code": 0, + "task_id": "t", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_processing_after_a_while.json b/tests/fixtures/parity/expected/verify__status_processing_after_a_while.json new file mode 100644 index 0000000..03a199c --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_processing_after_a_while.json @@ -0,0 +1,63 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "", + "error": "", + "failure_class": "", + "failure_detail": "", + "failure_reason": "", + "hint": "", + "progress": { + "elapsed_seconds": 1, + "index": 4, + "poll_after_seconds": 5, + "step": "adjudication", + "total": 5 + }, + "reason": "", + "result": null, + "retryable": null, + "similar_claims": [], + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "progress": { + "elapsed_seconds": 1, + "index": 4, + "poll_after_seconds": 5, + "step": "adjudication", + "total": 5 + }, + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "processing — Panel review across models (4/5)\n", + "render_json": "{\n \"status\": \"processing\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"adjudication\",\n \"index\": 4,\n \"total\": 5,\n \"elapsed_seconds\": 1,\n \"poll_after_seconds\": 5\n },\n \"result\": null,\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"\",\n \"failure_reason\": \"\",\n \"failure_detail\": \"\",\n \"failure_class\": \"\",\n \"retryable\": null,\n \"docs_url\": \"\"\n}\n", + "repr": "TaskStatus(status='processing', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='adjudication', index=4, total=5, elapsed_seconds=1, poll_after_seconds=5), result=None, claims=[], candidates=[], similar_claims=[], error='', failure_reason='', failure_detail='', failure_class='', retryable=None, docs_url='')", + "wait": { + "cause": "unknown", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "failure_class": "", + "failure_reason": "", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "friendly_text": "Pipeline failed: unknown\n Fix: Retry with a different claim, or check status.error for the diagnostic.", + "hint": "", + "message": "Pipeline failed: unknown", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Retry with a different claim, or check status.error for the diagnostic.", + "message": "Pipeline failed: unknown", + "status": 0 + } + }, + "request_id": "", + "retryable": null, + "status_code": 0, + "task_id": "t", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_task_stuck.json b/tests/fixtures/parity/expected/verify__status_task_stuck.json new file mode 100644 index 0000000..db68477 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_task_stuck.json @@ -0,0 +1,61 @@ +{ + "dump": { + "candidates": [], + "claims": [], + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "error": "The task was never completed and has been marked failed.", + "failure_class": "upstream_unavailable", + "failure_detail": "", + "failure_reason": "task_stuck", + "hint": "", + "progress": { + "elapsed_seconds": null, + "index": null, + "poll_after_seconds": null, + "step": "", + "total": null + }, + "reason": "", + "result": null, + "retryable": true, + "similar_claims": [], + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "error": "The task was never completed and has been marked failed.", + "failure_class": "upstream_unavailable", + "failure_reason": "task_stuck", + "retryable": true, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render": "failed — The task was never completed and has been marked failed.\n", + "render_json": "{\n \"status\": \"failed\",\n \"task_id\": \"7cff18da2d979d6370e54a160be121ad\",\n \"reason\": \"\",\n \"hint\": \"\",\n \"progress\": {\n \"step\": \"\",\n \"index\": null,\n \"total\": null,\n \"elapsed_seconds\": null,\n \"poll_after_seconds\": null\n },\n \"result\": null,\n \"claims\": [],\n \"candidates\": [],\n \"similar_claims\": [],\n \"error\": \"The task was never completed and has been marked failed.\",\n \"failure_reason\": \"task_stuck\",\n \"failure_detail\": \"\",\n \"failure_class\": \"upstream_unavailable\",\n \"retryable\": true,\n \"docs_url\": \"https://lenz.io/docs/errors#upstream-unavailable\"\n}\n", + "repr": "TaskStatus(status='failed', task_id='7cff18da2d979d6370e54a160be121ad', reason='', hint='', progress=Progress(step='', index=None, total=None, elapsed_seconds=None, poll_after_seconds=None), result=None, claims=[], candidates=[], similar_claims=[], error='The task was never completed and has been marked failed.', failure_reason='task_stuck', failure_detail='', failure_class='upstream_unavailable', retryable=True, docs_url='https://lenz.io/docs/errors#upstream-unavailable')", + "wait": { + "cause": "The task was never completed and has been marked failed.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "failure_class": "upstream_unavailable", + "failure_reason": "task_stuck", + "fix": "Transient provider outage — retry the same request after a short wait.", + "friendly_text": "Pipeline failed: The task was never completed and has been marked failed.\n Fix: Transient provider outage — retry the same request after a short wait.", + "hint": "", + "message": "Pipeline failed: The task was never completed and has been marked failed.", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Transient provider outage — retry the same request after a short wait.", + "message": "Pipeline failed: The task was never completed and has been marked failed.", + "status": 0 + } + }, + "request_id": "", + "retryable": true, + "status_code": 0, + "task_id": "t", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__status_unknown_404.json b/tests/fixtures/parity/expected/verify__status_unknown_404.json new file mode 100644 index 0000000..68a468c --- /dev/null +++ b/tests/fixtures/parity/expected/verify__status_unknown_404.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Task not found.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Task not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Task not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Task not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/verify__submit_202.json b/tests/fixtures/parity/expected/verify__submit_202.json new file mode 100644 index 0000000..74a0269 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__submit_202.json @@ -0,0 +1,15 @@ +{ + "dump": { + "chain_id": "99a0a9ca89e1e72c", + "claim_text": "", + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "chain_id": "99a0a9ca89e1e72c", + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render_json": null, + "repr": "TaskAccepted(task_id='7cff18da2d979d6370e54a160be121ad', claim_text='', status='queued', chain_id='99a0a9ca89e1e72c')" +} diff --git a/tests/fixtures/parity/expected/verify__submit_202_options.json b/tests/fixtures/parity/expected/verify__submit_202_options.json new file mode 100644 index 0000000..74a0269 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__submit_202_options.json @@ -0,0 +1,15 @@ +{ + "dump": { + "chain_id": "99a0a9ca89e1e72c", + "claim_text": "", + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "chain_id": "99a0a9ca89e1e72c", + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render_json": null, + "repr": "TaskAccepted(task_id='7cff18da2d979d6370e54a160be121ad', claim_text='', status='queued', chain_id='99a0a9ca89e1e72c')" +} diff --git a/tests/fixtures/parity/expected/verify__submit_202_text_alias.json b/tests/fixtures/parity/expected/verify__submit_202_text_alias.json new file mode 100644 index 0000000..74a0269 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__submit_202_text_alias.json @@ -0,0 +1,15 @@ +{ + "dump": { + "chain_id": "99a0a9ca89e1e72c", + "claim_text": "", + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "dump_unset": { + "chain_id": "99a0a9ca89e1e72c", + "status": "queued", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "render_json": null, + "repr": "TaskAccepted(task_id='7cff18da2d979d6370e54a160be121ad', claim_text='', status='queued', chain_id='99a0a9ca89e1e72c')" +} diff --git a/tests/fixtures/parity/expected/verify__unauthenticated_401.json b/tests/fixtures/parity/expected/verify__unauthenticated_401.json new file mode 100644 index 0000000..e57982a --- /dev/null +++ b/tests/fixtures/parity/expected/verify__unauthenticated_401.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Unauthorized", + "code": "", + "doc_url": "https://lenz.io/docs/auth", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "friendly_text": "Unauthorized\n Fix: Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "payload_json": { + "error": { + "code": "unauthorized", + "fix": "Your credential is missing, invalid or expired. Check the key you passed, or get a new one at https://lenz.io/api-credentials.", + "message": "Unauthorized", + "status": 401 + } + }, + "request_id": "", + "status_code": 401, + "type": "LenzAuthError" + } +} diff --git a/tests/fixtures/parity/expected/verify__verification_200.json b/tests/fixtures/parity/expected/verify__verification_200.json new file mode 100644 index 0000000..8ec0e7a --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_200.json @@ -0,0 +1,180 @@ +{ + "dump": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "dump_unset": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "render": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_concise": "True (high) score 9/10\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nSources (2):\n • The shape of the Earth\n https://nasa.example/shape\n • Earth from space\n https://esa.example/earth\n\nverification_id: 68ca4aaf\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_json": "{\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T09:07:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n}\n", + "repr": "Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1'))" +} diff --git a/tests/fixtures/parity/expected/verify__verification_200_covered.json b/tests/fixtures/parity/expected/verify__verification_200_covered.json new file mode 100644 index 0000000..ed0c52c --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_200_covered.json @@ -0,0 +1,176 @@ +{ + "dump": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": "2026-03-10T12:01:30+00:00", + "cap": 10000, + "certificate_id": "95b0f3dd008b46846b6dd6b15099e2b3", + "certificate_url": "https://lenz.io/certificate/95b0f3dd008b46846b6dd6b15099e2b3", + "currency": "EUR", + "reasons": [], + "status": "covered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "dump_unset": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": "2026-03-10T12:01:30+00:00", + "cap": 10000, + "certificate_id": "95b0f3dd008b46846b6dd6b15099e2b3", + "certificate_url": "https://lenz.io/certificate/95b0f3dd008b46846b6dd6b15099e2b3", + "currency": "EUR", + "reasons": [], + "status": "covered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "render": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_concise": "True (high) score 9/10\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nSources (2):\n • The shape of the Earth\n https://nasa.example/shape\n • Earth from space\n https://esa.example/earth\n\nverification_id: 68ca4aaf\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_json": "{\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T09:07:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"covered\",\n \"reasons\": [],\n \"certificate_id\": \"95b0f3dd008b46846b6dd6b15099e2b3\",\n \"certificate_url\": \"https://lenz.io/certificate/95b0f3dd008b46846b6dd6b15099e2b3\",\n \"as_of\": \"2026-03-10T12:01:30+00:00\",\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n}\n", + "repr": "Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='covered', reasons=[], certificate_id='95b0f3dd008b46846b6dd6b15099e2b3', certificate_url='https://lenz.io/certificate/95b0f3dd008b46846b6dd6b15099e2b3', as_of='2026-03-10T12:01:30+00:00', currency='EUR', cap=10000, aggregate=500000, terms_version='v1'))" +} diff --git a/tests/fixtures/parity/expected/verify__verification_200_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/expected/verify__verification_200_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..ab23f79 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_200_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,180 @@ +{ + "dump": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "dump_unset": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "render": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_concise": "True (high) score 9/10\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nSources (2):\n • The shape of the Earth\n https://nasa.example/shape\n • Earth from space\n https://esa.example/earth\n\nverification_id: 68ca4aaf\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_json": "{\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T23:55:00.123456+00:00\",\n \"modified_at\": \"2026-10-02T00:03:00.123456+00:00\",\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n}\n", + "repr": "Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T23:55:00.123456+00:00', modified_at='2026-10-02T00:03:00.123456+00:00', language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1'))" +} diff --git a/tests/fixtures/parity/expected/verify__verification_200_modified_at_null.json b/tests/fixtures/parity/expected/verify__verification_200_modified_at_null.json new file mode 100644 index 0000000..8ec0e7a --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_200_modified_at_null.json @@ -0,0 +1,180 @@ +{ + "dump": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "dump_unset": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "render": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_concise": "True (high) score 9/10\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nSources (2):\n • The shape of the Earth\n https://nasa.example/shape\n • Earth from space\n https://esa.example/earth\n\nverification_id: 68ca4aaf\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_json": "{\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T09:07:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n}\n", + "repr": "Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1'))" +} diff --git a/tests/fixtures/parity/expected/verify__verification_200_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/expected/verify__verification_200_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..6e45445 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_200_modified_at_same_day_hours_apart.json @@ -0,0 +1,180 @@ +{ + "dump": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "dump_unset": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "render": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_concise": "True (high) score 9/10\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nSources (2):\n • The shape of the Earth\n https://nasa.example/shape\n • Earth from space\n https://esa.example/earth\n\nverification_id: 68ca4aaf\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_json": "{\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T08:00:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n}\n", + "repr": "Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T08:00:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1'))" +} diff --git a/tests/fixtures/parity/expected/verify__verification_200_modified_at_set.json b/tests/fixtures/parity/expected/verify__verification_200_modified_at_set.json new file mode 100644 index 0000000..ab23f79 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_200_modified_at_set.json @@ -0,0 +1,180 @@ +{ + "dump": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "dump_unset": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "render": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_concise": "True (high) score 9/10\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nSources (2):\n • The shape of the Earth\n https://nasa.example/shape\n • Earth from space\n https://esa.example/earth\n\nverification_id: 68ca4aaf\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_json": "{\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T23:55:00.123456+00:00\",\n \"modified_at\": \"2026-10-02T00:03:00.123456+00:00\",\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n}\n", + "repr": "Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T23:55:00.123456+00:00', modified_at='2026-10-02T00:03:00.123456+00:00', language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1'))" +} diff --git a/tests/fixtures/parity/expected/verify__verification_200_result_json_conclusion_only.json b/tests/fixtures/parity/expected/verify__verification_200_result_json_conclusion_only.json new file mode 100644 index 0000000..30e90b7 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_200_result_json_conclusion_only.json @@ -0,0 +1,102 @@ +{ + "dump": { + "audit": { + "adjudication_summary": "", + "assessments": [], + "debate_con": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "debate_pro": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "panel_agreement": "split" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "", + "sources": [], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [] + }, + "dump_unset": { + "audit": { + "adjudication_summary": "", + "assessments": [], + "debate_con": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "debate_pro": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "panel_agreement": "split" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "", + "sources": [], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [] + }, + "render": "True (high) score 9/10\n\nClaim The Earth is round.\nScience\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\n── Panel ──\nagreement: split\n\nDebate\n PRO \n CON \n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_concise": "True (high) score 9/10\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nverification_id: 68ca4aaf\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_json": "{\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [],\n \"presumed_intent\": \"\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [],\n \"suggested_rewrite\": null,\n \"sources\": [],\n \"audit\": {\n \"adjudication_summary\": \"\",\n \"assessments\": [],\n \"debate_pro\": {\n \"role\": \"\",\n \"argument\": \"\",\n \"rebuttal\": \"\"\n },\n \"debate_con\": {\n \"role\": \"\",\n \"argument\": \"\",\n \"rebuttal\": \"\"\n },\n \"panel_agreement\": \"split\"\n },\n \"created_at\": \"2026-10-01T09:07:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n}\n", + "repr": "Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[], presumed_intent='', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=[], suggested_rewrite=None, sources=[], audit=Audit(adjudication_summary='', assessments=[], debate_pro=DebateSide(role='', argument='', rebuttal=''), debate_con=DebateSide(role='', argument='', rebuttal=''), panel_agreement='split'), created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1'))" +} diff --git a/tests/fixtures/parity/expected/verify__verification_200_result_json_empty.json b/tests/fixtures/parity/expected/verify__verification_200_result_json_empty.json new file mode 100644 index 0000000..30e90b7 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_200_result_json_empty.json @@ -0,0 +1,102 @@ +{ + "dump": { + "audit": { + "adjudication_summary": "", + "assessments": [], + "debate_con": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "debate_pro": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "panel_agreement": "split" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "", + "sources": [], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [] + }, + "dump_unset": { + "audit": { + "adjudication_summary": "", + "assessments": [], + "debate_con": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "debate_pro": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "panel_agreement": "split" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "", + "sources": [], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [] + }, + "render": "True (high) score 9/10\n\nClaim The Earth is round.\nScience\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\n── Panel ──\nagreement: split\n\nDebate\n PRO \n CON \n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_concise": "True (high) score 9/10\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nverification_id: 68ca4aaf\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_json": "{\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [],\n \"presumed_intent\": \"\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [],\n \"suggested_rewrite\": null,\n \"sources\": [],\n \"audit\": {\n \"adjudication_summary\": \"\",\n \"assessments\": [],\n \"debate_pro\": {\n \"role\": \"\",\n \"argument\": \"\",\n \"rebuttal\": \"\"\n },\n \"debate_con\": {\n \"role\": \"\",\n \"argument\": \"\",\n \"rebuttal\": \"\"\n },\n \"panel_agreement\": \"split\"\n },\n \"created_at\": \"2026-10-01T09:07:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n}\n", + "repr": "Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[], presumed_intent='', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=[], suggested_rewrite=None, sources=[], audit=Audit(adjudication_summary='', assessments=[], debate_pro=DebateSide(role='', argument='', rebuttal=''), debate_con=DebateSide(role='', argument='', rebuttal=''), panel_agreement='split'), created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1'))" +} diff --git a/tests/fixtures/parity/expected/verify__verification_200_result_json_old_shape_strings.json b/tests/fixtures/parity/expected/verify__verification_200_result_json_old_shape_strings.json new file mode 100644 index 0000000..f9f875f --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_200_result_json_old_shape_strings.json @@ -0,0 +1,134 @@ +{ + "dump": { + "audit": { + "adjudication_summary": "", + "assessments": [ + { + "focus_area": "", + "panelist_name": "Reviewer A", + "reasoning": "", + "score": null, + "warnings": [] + } + ], + "debate_con": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "debate_pro": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "panel_agreement": "split" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "", + "sources": [ + { + "date": "", + "snippet": "Old row.", + "source_name": "", + "title": "", + "url": "https://old.example/a" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [] + }, + "dump_unset": { + "audit": { + "adjudication_summary": "", + "assessments": [ + { + "focus_area": "", + "panelist_name": "Reviewer A", + "reasoning": "", + "score": null, + "warnings": [] + } + ], + "debate_con": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "debate_pro": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "panel_agreement": "split" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "", + "sources": [ + { + "date": "", + "snippet": "Old row.", + "source_name": "", + "title": "", + "url": "https://old.example/a" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [] + }, + "render": "True (high) score 9/10\n\nClaim The Earth is round.\nScience\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nSources (1):\n • https://old.example/a\n https://old.example/a\n Old row.\n\n── Panel ──\nagreement: split\n\nReviewer A\n\nDebate\n PRO \n CON \n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_concise": "True (high) score 9/10\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nSources (1):\n • https://old.example/a\n https://old.example/a\n\nverification_id: 68ca4aaf\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_json": "{\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [],\n \"presumed_intent\": \"\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"\",\n \"title\": \"\",\n \"url\": \"https://old.example/a\",\n \"snippet\": \"Old row.\",\n \"date\": \"\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"\",\n \"score\": null,\n \"reasoning\": \"\",\n \"warnings\": []\n }\n ],\n \"debate_pro\": {\n \"role\": \"\",\n \"argument\": \"\",\n \"rebuttal\": \"\"\n },\n \"debate_con\": {\n \"role\": \"\",\n \"argument\": \"\",\n \"rebuttal\": \"\"\n },\n \"panel_agreement\": \"split\"\n },\n \"created_at\": \"2026-10-01T09:07:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n}\n", + "repr": "Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[], presumed_intent='', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=[], suggested_rewrite=None, sources=[Source(source_name='', title='', url='https://old.example/a', snippet='Old row.', date='')], audit=Audit(adjudication_summary='', assessments=[Assessment(panelist_name='Reviewer A', focus_area='', score=None, reasoning='', warnings=[])], debate_pro=DebateSide(role='', argument='', rebuttal=''), debate_con=DebateSide(role='', argument='', rebuttal=''), panel_agreement='split'), created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1'))" +} diff --git a/tests/fixtures/parity/expected/verify__verification_404.json b/tests/fixtures/parity/expected/verify__verification_404.json new file mode 100644 index 0000000..41573fe --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_404.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Not found.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/verify__verification_by_task_id_200.json b/tests/fixtures/parity/expected/verify__verification_by_task_id_200.json new file mode 100644 index 0000000..8ec0e7a --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_by_task_id_200.json @@ -0,0 +1,180 @@ +{ + "dump": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "dump_unset": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "render": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_concise": "True (high) score 9/10\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nSources (2):\n • The shape of the Earth\n https://nasa.example/shape\n • Earth from space\n https://esa.example/earth\n\nverification_id: 68ca4aaf\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_json": "{\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T09:07:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n}\n", + "repr": "Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1'))" +} diff --git a/tests/fixtures/parity/expected/verify__verification_failed_409.json b/tests/fixtures/parity/expected/verify__verification_failed_409.json new file mode 100644 index 0000000..e938c8a --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_failed_409.json @@ -0,0 +1,26 @@ +{ + "error": { + "cause": "This check failed and has no result.", + "code": "verification_failed", + "doc_url": "https://lenz.io/docs/errors#insufficient-evidence", + "failure_class": "insufficient_evidence", + "failure_reason": "research_empty", + "fix": "Resubmit to POST /verify if retryable is true. GET /verify/status/7cff18da2d979d6370e54a160be121ad has the full failure.", + "friendly_text": "This check failed and has no result.\n Fix: Resubmit to POST /verify if retryable is true. GET /verify/status/7cff18da2d979d6370e54a160be121ad has the full failure.", + "hint": "Resubmit to POST /verify if retryable is true. GET /verify/status/7cff18da2d979d6370e54a160be121ad has the full failure.", + "message": "This check failed and has no result.", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Resubmit to POST /verify if retryable is true. GET /verify/status/7cff18da2d979d6370e54a160be121ad has the full failure.", + "message": "This check failed and has no result.", + "status": 409 + } + }, + "request_id": "", + "retryable": false, + "status_code": 409, + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__verification_failed_409_not_a_claim_after_a_while.json b/tests/fixtures/parity/expected/verify__verification_failed_409_not_a_claim_after_a_while.json new file mode 100644 index 0000000..3a9e337 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_failed_409_not_a_claim_after_a_while.json @@ -0,0 +1,26 @@ +{ + "error": { + "cause": "This check failed and has no result.", + "code": "verification_failed", + "doc_url": "https://lenz.io/docs/errors#invalid-input", + "failure_class": "invalid_input", + "failure_reason": "not_a_claim", + "fix": "Resubmit to POST /verify if retryable is true. GET /verify/status/7cff18da2d979d6370e54a160be121ad has the full failure.", + "friendly_text": "This check failed and has no result.\n Fix: Resubmit to POST /verify if retryable is true. GET /verify/status/7cff18da2d979d6370e54a160be121ad has the full failure.", + "hint": "Resubmit to POST /verify if retryable is true. GET /verify/status/7cff18da2d979d6370e54a160be121ad has the full failure.", + "message": "This check failed and has no result.", + "payload_json": { + "error": { + "code": "pipeline_failed", + "fix": "Resubmit to POST /verify if retryable is true. GET /verify/status/7cff18da2d979d6370e54a160be121ad has the full failure.", + "message": "This check failed and has no result.", + "status": 409 + } + }, + "request_id": "", + "retryable": false, + "status_code": 409, + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "LenzPipelineError" + } +} diff --git a/tests/fixtures/parity/expected/verify__verification_not_ready_409.json b/tests/fixtures/parity/expected/verify__verification_not_ready_409.json new file mode 100644 index 0000000..14d8183 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_not_ready_409.json @@ -0,0 +1,24 @@ +{ + "error": { + "cause": "This check is still running.", + "code": "verification_not_ready", + "doc_url": "https://lenz.io/docs/verify", + "fix": "Poll GET /verify/status/7cff18da2d979d6370e54a160be121ad until it completes, then read its result.", + "friendly_text": "This check is still running.\n Fix: Poll GET /verify/status/7cff18da2d979d6370e54a160be121ad until it completes, then read its result.", + "hint": "Poll GET /verify/status/7cff18da2d979d6370e54a160be121ad until it completes, then read its result.", + "message": "This check is still running.", + "payload_json": { + "error": { + "code": "not_ready", + "fix": "Poll GET /verify/status/7cff18da2d979d6370e54a160be121ad until it completes, then read its result.", + "message": "This check is still running.", + "status": 409 + } + }, + "request_id": "", + "status": "processing", + "status_code": 409, + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "LenzVerificationNotReadyError" + } +} diff --git a/tests/fixtures/parity/expected/verify__verification_not_yours_404.json b/tests/fixtures/parity/expected/verify__verification_not_yours_404.json new file mode 100644 index 0000000..41573fe --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_not_yours_404.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Not found.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/verify__verification_public_anonymous.json b/tests/fixtures/parity/expected/verify__verification_public_anonymous.json new file mode 100644 index 0000000..7319f6f --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_public_anonymous.json @@ -0,0 +1,156 @@ +{ + "dump": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "public", + "warnings": [ + "Relies on limited sources" + ] + }, + "dump_unset": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "public", + "warnings": [ + "Relies on limited sources" + ] + }, + "render": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_concise": "True (high) score 9/10\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nSources (2):\n • The shape of the Earth\n https://nasa.example/shape\n • Earth from space\n https://esa.example/earth\n\nverification_id: 68ca4aaf\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_json": "{\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"public\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T09:07:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": null\n}\n", + "repr": "Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='public', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en', coverage=None)" +} diff --git a/tests/fixtures/parity/expected/verify__verification_public_of_another_user.json b/tests/fixtures/parity/expected/verify__verification_public_of_another_user.json new file mode 100644 index 0000000..dc75e23 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_public_of_another_user.json @@ -0,0 +1,180 @@ +{ + "dump": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "public", + "warnings": [ + "Relies on limited sources" + ] + }, + "dump_unset": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is verified.", + "key_finding": "The Earth is approximately spherical in shape.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "public", + "warnings": [ + "Relies on limited sources" + ] + }, + "render": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_concise": "True (high) score 9/10\n\nThe Earth is approximately spherical in shape.\n\nThe claim is verified.\n\nSources (2):\n • The shape of the Earth\n https://nasa.example/shape\n • Earth from space\n https://esa.example/earth\n\nverification_id: 68ca4aaf\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_json": "{\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"public\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical in shape.\",\n \"executive_summary\": \"The claim is verified.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T09:07:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n}\n", + "repr": "Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='public', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical in shape.', executive_summary='The claim is verified.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1'))" +} diff --git a/tests/fixtures/parity/expected/verify__verification_unknown_task_404.json b/tests/fixtures/parity/expected/verify__verification_unknown_task_404.json new file mode 100644 index 0000000..41573fe --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_unknown_task_404.json @@ -0,0 +1,21 @@ +{ + "error": { + "cause": "Not found.", + "code": "", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "friendly_text": "Not found.\n Fix: Retry; if the error persists, file an issue with the Request ID.", + "message": "Not found.", + "payload_json": { + "error": { + "code": "api_error", + "fix": "Retry; if the error persists, file an issue with the Request ID.", + "message": "Not found.", + "status": 404 + } + }, + "request_id": "", + "status_code": 404, + "type": "LenzError" + } +} diff --git a/tests/fixtures/parity/expected/verify__verification_zero_retention_expired_410.json b/tests/fixtures/parity/expected/verify__verification_zero_retention_expired_410.json new file mode 100644 index 0000000..99f659b --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_zero_retention_expired_410.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "This verification is no longer available: its account removes verifications after a set period.", + "code": "purged", + "doc_url": "https://lenz.io/docs/errors", + "fix": "Its account's retention period removed it. A certificate issued for it is still available.", + "friendly_text": "This verification is no longer available: its account removes verifications after a set period.\n Fix: Its account's retention period removed it. A certificate issued for it is still available.", + "message": "This verification is no longer available: its account removes verifications after a set period.", + "payload_json": { + "error": { + "code": "gone", + "fix": "Its account's retention period removed it. A certificate issued for it is still available.", + "message": "This verification is no longer available: its account removes verifications after a set period.", + "status": 410 + } + }, + "purged_at": "2026-10-01T09:07:00.123456+00:00", + "request_id": "", + "status_code": 410, + "type": "LenzGoneError" + } +} diff --git a/tests/fixtures/parity/expected/verify__verification_zero_retention_served.json b/tests/fixtures/parity/expected/verify__verification_zero_retention_served.json new file mode 100644 index 0000000..463876f --- /dev/null +++ b/tests/fixtures/parity/expected/verify__verification_zero_retention_served.json @@ -0,0 +1,180 @@ +{ + "dump": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is well supported by evidence.", + "key_finding": "The Earth is approximately spherical.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "dump_unset": { + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "focus_area": "Claim Precision & Quantitative Accuracy", + "panelist_name": "Reviewer A", + "reasoning": "Precision analysis reasoning.", + "score": 9.0, + "warnings": [] + }, + { + "focus_area": "Sources", + "panelist_name": "Reviewer B", + "reasoning": "Source audit reasoning.", + "score": 9.0, + "warnings": [ + "weak source A" + ] + } + ], + "debate_con": { + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim.", + "role": "Skeptic" + }, + "debate_pro": { + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold.", + "role": "Advocate" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Earth is round.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "executive_summary": "The claim is well supported by evidence.", + "key_finding": "The Earth is approximately spherical.", + "language": "en", + "lenz_score": 9, + "modified_at": null, + "presumed_intent": "Verify a basic scientific fact", + "sources": [ + { + "date": "2025-01-15", + "snippet": "Satellite imagery shows an oblate spheroid.", + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape" + }, + { + "date": "2025-01-16", + "snippet": "Orbital measurements confirm the curvature.", + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth" + } + ], + "suggested_rewrite": null, + "verdict": "True", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Relies on limited sources" + ] + }, + "render": "True (high) score 9/10\n\nClaim The Earth is round.\nScience • Earth\n\nThe Earth is approximately spherical.\n\nThe claim is well supported by evidence.\n\nWarnings (1):\n • Relies on limited sources\n\nSources (2):\n • The shape of the Earth (2025-01-15)\n https://nasa.example/shape\n Satellite imagery shows an oblate spheroid.\n • Earth from space (2025-01-16)\n https://esa.example/earth\n Orbital measurements confirm the curvature.\n\n── Panel ──\nagreement: unanimous\n\nReviewer A (Claim Precision & Quantitative Accuracy) 9.0/10\n Precision analysis reasoning.\n\nReviewer B (Sources) 9.0/10\n Source audit reasoning.\n • weak source A\n\nPanel Review\nBoth reviewers agreed.\n\nDebate\n PRO Satellite imagery and geodesy agree.\n rebuttal: Flat-Earth objections do not hold.\n CON The Earth is not a perfect sphere.\n rebuttal: Oblate, but round for the claim.\n\nverification_id: 68ca4aaf\nchecked Oct 1, 2026\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_concise": "True (high) score 9/10\n\nThe Earth is approximately spherical.\n\nThe claim is well supported by evidence.\n\nSources (2):\n • The shape of the Earth\n https://nasa.example/shape\n • Earth from space\n https://esa.example/earth\n\nverification_id: 68ca4aaf\nask follow-ups: lenz ask 68ca4aaf \"\"\n", + "render_json": "{\n \"verification_id\": \"68ca4aaf\",\n \"claim\": \"The Earth is round.\",\n \"visibility\": \"private\",\n \"depth\": \"standard\",\n \"domain\": \"Science\",\n \"entities\": [\n {\n \"name\": \"Earth\",\n \"qid\": null\n }\n ],\n \"presumed_intent\": \"Verify a basic scientific fact\",\n \"verdict\": \"True\",\n \"confidence\": \"high\",\n \"lenz_score\": 9,\n \"key_finding\": \"The Earth is approximately spherical.\",\n \"executive_summary\": \"The claim is well supported by evidence.\",\n \"warnings\": [\n \"Relies on limited sources\"\n ],\n \"suggested_rewrite\": null,\n \"sources\": [\n {\n \"source_name\": \"NASA\",\n \"title\": \"The shape of the Earth\",\n \"url\": \"https://nasa.example/shape\",\n \"snippet\": \"Satellite imagery shows an oblate spheroid.\",\n \"date\": \"2025-01-15\"\n },\n {\n \"source_name\": \"ESA\",\n \"title\": \"Earth from space\",\n \"url\": \"https://esa.example/earth\",\n \"snippet\": \"Orbital measurements confirm the curvature.\",\n \"date\": \"2025-01-16\"\n }\n ],\n \"audit\": {\n \"adjudication_summary\": \"Both reviewers agreed.\",\n \"assessments\": [\n {\n \"panelist_name\": \"Reviewer A\",\n \"focus_area\": \"Claim Precision & Quantitative Accuracy\",\n \"score\": 9.0,\n \"reasoning\": \"Precision analysis reasoning.\",\n \"warnings\": []\n },\n {\n \"panelist_name\": \"Reviewer B\",\n \"focus_area\": \"Sources\",\n \"score\": 9.0,\n \"reasoning\": \"Source audit reasoning.\",\n \"warnings\": [\n \"weak source A\"\n ]\n }\n ],\n \"debate_pro\": {\n \"role\": \"Advocate\",\n \"argument\": \"Satellite imagery and geodesy agree.\",\n \"rebuttal\": \"Flat-Earth objections do not hold.\"\n },\n \"debate_con\": {\n \"role\": \"Skeptic\",\n \"argument\": \"The Earth is not a perfect sphere.\",\n \"rebuttal\": \"Oblate, but round for the claim.\"\n },\n \"panel_agreement\": \"unanimous\"\n },\n \"created_at\": \"2026-10-01T09:07:00.123456+00:00\",\n \"modified_at\": null,\n \"language\": \"en\",\n \"coverage\": {\n \"status\": \"uncovered\",\n \"reasons\": [\n \"plan\"\n ],\n \"certificate_id\": null,\n \"certificate_url\": null,\n \"as_of\": null,\n \"currency\": \"EUR\",\n \"cap\": 10000,\n \"aggregate\": 500000,\n \"terms_version\": \"v1\"\n }\n}\n", + "repr": "Verification(verification_id='68ca4aaf', claim='The Earth is round.', visibility='private', depth='standard', domain='Science', entities=[EntityRef(name='Earth', qid=None)], presumed_intent='Verify a basic scientific fact', verdict='True', confidence='high', lenz_score=9, key_finding='The Earth is approximately spherical.', executive_summary='The claim is well supported by evidence.', warnings=['Relies on limited sources'], suggested_rewrite=None, sources=[Source(source_name='NASA', title='The shape of the Earth', url='https://nasa.example/shape', snippet='Satellite imagery shows an oblate spheroid.', date='2025-01-15'), Source(source_name='ESA', title='Earth from space', url='https://esa.example/earth', snippet='Orbital measurements confirm the curvature.', date='2025-01-16')], audit=Audit(adjudication_summary='Both reviewers agreed.', assessments=[Assessment(panelist_name='Reviewer A', focus_area='Claim Precision & Quantitative Accuracy', score=9.0, reasoning='Precision analysis reasoning.', warnings=[]), Assessment(panelist_name='Reviewer B', focus_area='Sources', score=9.0, reasoning='Source audit reasoning.', warnings=['weak source A'])], debate_pro=DebateSide(role='Advocate', argument='Satellite imagery and geodesy agree.', rebuttal='Flat-Earth objections do not hold.'), debate_con=DebateSide(role='Skeptic', argument='The Earth is not a perfect sphere.', rebuttal='Oblate, but round for the claim.'), panel_agreement='unanimous'), created_at='2026-10-01T09:07:00.123456+00:00', modified_at=None, language='en', coverage=Coverage(status='uncovered', reasons=['plan'], certificate_id=None, certificate_url=None, as_of=None, currency='EUR', cap=10000, aggregate=500000, terms_version='v1'))" +} diff --git a/tests/fixtures/parity/expected/verify__webhook_secret_missing_422.json b/tests/fixtures/parity/expected/verify__webhook_secret_missing_422.json new file mode 100644 index 0000000..aa4b7e1 --- /dev/null +++ b/tests/fixtures/parity/expected/verify__webhook_secret_missing_422.json @@ -0,0 +1,22 @@ +{ + "error": { + "cause": "webhook_url was supplied but this API key has no HMAC secret. Generate one at https://lenz.io/api-credentials (Webhooks panel) before submitting webhook-delivered calls.", + "code": "webhook_secret_missing", + "doc_url": "https://lenz.io/docs/errors/validation", + "errors": [], + "fix": "Check the request body against the OpenAPI spec.", + "friendly_text": "webhook_url was supplied but this API key has no HMAC secret. Generate one at https://lenz.io/api-credentials (Webhooks panel) before submitting webhook-delivered calls.\n Fix: Check the request body against the OpenAPI spec.", + "message": "webhook_url was supplied but this API key has no HMAC secret. Generate one at https://lenz.io/api-credentials (Webhooks panel) before submitting webhook-delivered calls.", + "payload_json": { + "error": { + "code": "invalid_request", + "fix": "Check the request body against the OpenAPI spec.", + "message": "webhook_url was supplied but this API key has no HMAC secret. Generate one at https://lenz.io/api-credentials (Webhooks panel) before submitting webhook-delivered calls.", + "status": 422 + } + }, + "request_id": "", + "status_code": 422, + "type": "LenzValidationError" + } +} diff --git a/tests/fixtures/parity/expected/webhook__certificate_timestamped.json b/tests/fixtures/parity/expected/webhook__certificate_timestamped.json new file mode 100644 index 0000000..754e890 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__certificate_timestamped.json @@ -0,0 +1,23 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "coverage": { + "aggregate": 500000, + "as_of": "2026-09-03T10:00:00+00:00", + "cap": 10000, + "certificate_id": "95b0f3dd008b46846b6dd6b15099e2b3", + "certificate_url": "https://lenz.io/certificate/95b0f3dd008b46846b6dd6b15099e2b3", + "currency": "EUR", + "reasons": [], + "status": "covered", + "terms_version": "v1" + }, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "certificate.timestamped", + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "CertificateTimestamped", + "verification_id": "68ca4aaf" + } +} diff --git a/tests/fixtures/parity/expected/webhook__certificate_timestamped_review_child.json b/tests/fixtures/parity/expected/webhook__certificate_timestamped_review_child.json new file mode 100644 index 0000000..754e890 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__certificate_timestamped_review_child.json @@ -0,0 +1,23 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "coverage": { + "aggregate": 500000, + "as_of": "2026-09-03T10:00:00+00:00", + "cap": 10000, + "certificate_id": "95b0f3dd008b46846b6dd6b15099e2b3", + "certificate_url": "https://lenz.io/certificate/95b0f3dd008b46846b6dd6b15099e2b3", + "currency": "EUR", + "reasons": [], + "status": "covered", + "terms_version": "v1" + }, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "certificate.timestamped", + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "CertificateTimestamped", + "verification_id": "68ca4aaf" + } +} diff --git a/tests/fixtures/parity/expected/webhook__citecheck_completed.json b/tests/fixtures/parity/expected/webhook__citecheck_completed.json new file mode 100644 index 0000000..0fdf121 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__citecheck_completed.json @@ -0,0 +1,135 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "citecheck": { + "citation_failures": [], + "citation_issues": [ + { + "citation_index": 0, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": null, + "finding": "contradicted", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "position": null, + "quotes": [], + "rationale": "The page states it.", + "reference": "https://example.gov/report-2024", + "snippet": "The source says so.", + "source": "support", + "statement": "Unemployment fell to 4.1% in 2024." + } + ], + "citations": [ + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "status": "completed", + "support": "contradicted", + "unchecked_reason": null + }, + "cited_url": "https://example.gov/report-2024", + "doi": null, + "index": 0, + "position": null, + "quotes": [], + "reference": "https://example.gov/report-2024", + "result": { + "finding": "contradicted", + "is_issue": true, + "source": "support" + }, + "statement": "Unemployment fell to 4.1% in 2024." + }, + { + "check": { + "doi_registered": null, + "failure": null, + "hint": null, + "metadata": null, + "metadata_differences": [], + "missing_quote": null, + "page_language": "en", + "page_published_date": null, + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "quote": null, + "rationale": "The page states it.", + "registered": null, + "snippet": "The source says so.", + "source_url": "https://example.org/statement", + "source_version": null, + "status": "completed", + "support": "supported", + "unchecked_reason": null + }, + "cited_url": "https://example.org/statement", + "doi": null, + "index": 1, + "position": null, + "quotes": [], + "reference": "https://example.org/statement", + "result": { + "finding": "supported", + "is_issue": false, + "source": "support" + }, + "statement": "The agency said so in a statement." + } + ], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 2 + }, + "failure": null, + "language": "en", + "more_citations": [], + "outcome": "issues_found", + "policy": { + "max_citations": 2 + }, + "poll_after_seconds": null, + "status": "completed", + "summary": { + "citation_checks": { + "checked": 2, + "failed": 0, + "unchecked": 0 + }, + "citation_issues": 1, + "citation_limit": 2, + "citation_limit_reached": false, + "citations_found": 2, + "citations_selected": 2 + } + }, + "citecheck_id": "8eb49302", + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "citecheck.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "CitecheckEvent", + "verification_id": null + } +} diff --git a/tests/fixtures/parity/expected/webhook__citecheck_failed.json b/tests/fixtures/parity/expected/webhook__citecheck_failed.json new file mode 100644 index 0000000..400e0d6 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__citecheck_failed.json @@ -0,0 +1,48 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "citecheck": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "citecheck_id": "8eb49302", + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "failure_class": "invalid_input", + "failure_reason": "no_citations", + "hint": "The text has no citation to check: no link, DOI or numbered reference with one.", + "retryable": false + }, + "language": "en", + "more_citations": null, + "outcome": "unchecked", + "policy": { + "max_citations": 20 + }, + "poll_after_seconds": null, + "status": "failed", + "summary": { + "citation_checks": null, + "citation_issues": 0, + "citation_limit": 20, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null + } + }, + "citecheck_id": "8eb49302", + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "citecheck.failed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "CitecheckEvent", + "verification_id": null + } +} diff --git a/tests/fixtures/parity/expected/webhook__review_completed.json b/tests/fixtures/parity/expected/webhook__review_completed.json new file mode 100644 index 0000000..e1f3697 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__review_completed.json @@ -0,0 +1,157 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "review.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "review": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "False", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": true, + "source": "verification", + "verdict": "False" + }, + "suggested_edits": null, + "verification": { + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "high", + "content_status": "available", + "created_at": "2026-10-01T09:14:00.123456+00:00", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "language": "en", + "lenz_score": 2, + "modified_at": null, + "status": "completed", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "visibility": "private", + "warnings": [ + "w1" + ] + } + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 11 + }, + "failure": null, + "failures": [], + "issues": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "claim_index": 0, + "confidence": "high", + "escalation": { + "disposition": "planned", + "matched_rules": [ + "verdict" + ] + }, + "failure": null, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "source": "verification", + "suggested_edits": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "verdict": "False", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "verified_claim": null + } + ], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "issues_found", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 1, + "verifications": { + "completed": 1, + "failed": 0, + "planned": 1 + } + }, + "view": "full" + }, + "review_id": "d6b2bd72", + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "ReviewEvent", + "verification_id": null + } +} diff --git a/tests/fixtures/parity/expected/webhook__review_completed_key_default_url.json b/tests/fixtures/parity/expected/webhook__review_completed_key_default_url.json new file mode 100644 index 0000000..85da702 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__review_completed_key_default_url.json @@ -0,0 +1,106 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "review.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "review": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [ + { + "assessment": { + "confidence": "high", + "dissent": null, + "error_code": null, + "failure": null, + "hint": null, + "identified_claims": [], + "rationale": null, + "status": "completed", + "suggested_rewrite": null, + "verdict": "True", + "verification_url": null + }, + "claim": "The Eiffel Tower is in Berlin.", + "escalation": { + "disposition": "not_selected", + "matched_rules": [] + }, + "index": 0, + "positions": null, + "result": { + "confidence": "high", + "is_issue": false, + "source": "assessment", + "verdict": "True" + }, + "suggested_edits": null, + "verification": null + } + ], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 1 + }, + "failure": null, + "failures": [], + "issues": [], + "language": "en", + "more_citations": [], + "more_claim_locations": [], + "more_claims": [], + "outcome": "clean", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "completed", + "summary": { + "assessments": { + "completed": 1, + "failed": 0 + }, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": false, + "claims_selected": 1, + "input_truncated": false, + "issues": 0, + "verifications": { + "completed": 0, + "failed": 0, + "planned": 0 + } + }, + "view": "full" + }, + "review_id": "d6b2bd72", + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "ReviewEvent", + "verification_id": null + } +} diff --git a/tests/fixtures/parity/expected/webhook__review_completed_oversized_rebuilt.json b/tests/fixtures/parity/expected/webhook__review_completed_oversized_rebuilt.json new file mode 100644 index 0000000..048af92 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__review_completed_oversized_rebuilt.json @@ -0,0 +1,15 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "", + "event": "review.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "review": null, + "review_id": "d6b2bd72", + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "ReviewEvent", + "verification_id": null + } +} diff --git a/tests/fixtures/parity/expected/webhook__review_failed.json b/tests/fixtures/parity/expected/webhook__review_failed.json new file mode 100644 index 0000000..ce0bfb0 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__review_failed.json @@ -0,0 +1,74 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "review.failed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "review": { + "citation_failures": [], + "citation_issues": [], + "citations": [], + "claims": [], + "completed_at": "2026-10-01T10:07:00.123456Z", + "created_at": "2026-10-01T09:07:00.123456Z", + "credits": { + "charged": 0 + }, + "failure": { + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "failure_class": "invalid_input", + "failure_reason": "no_claim", + "hint": "No factual statement that can be checked against evidence was found in the input. Send one factual claim, or run the text through /extract to enumerate its claims.", + "retryable": false + }, + "failures": [], + "issues": [], + "language": "en", + "more_citations": null, + "more_claim_locations": null, + "more_claims": null, + "outcome": "unchecked", + "policy": { + "confidence": [ + "low" + ], + "depth": "standard", + "max_assessments": 20, + "max_citations": 0, + "max_verifications": 5, + "suggest_edits": false, + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ] + }, + "poll_after_seconds": null, + "review_id": "d6b2bd72", + "status": "failed", + "summary": { + "assessments": null, + "citation_checks": null, + "citation_issues": 0, + "citation_limit": null, + "citation_limit_reached": null, + "citations_found": null, + "citations_selected": null, + "citations_skipped": null, + "claim_limit": 20, + "claim_limit_reached": null, + "claims_selected": null, + "input_truncated": false, + "issues": 0, + "verifications": null + }, + "view": "full" + }, + "review_id": "d6b2bd72", + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "ReviewEvent", + "verification_id": null + } +} diff --git a/tests/fixtures/parity/expected/webhook__test_fire.json b/tests/fixtures/parity/expected/webhook__test_fire.json new file mode 100644 index 0000000..b796dcd --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__test_fire.json @@ -0,0 +1,12 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "webhook.test", + "status": "test", + "task_id": "test_7cff18da2d979d63", + "type": "WebhookEvent", + "verification_id": null + } +} diff --git a/tests/fixtures/parity/expected/webhook__verification_completed.json b/tests/fixtures/parity/expected/webhook__verification_completed.json new file mode 100644 index 0000000..1f8d807 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__verification_completed.json @@ -0,0 +1,103 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "verification.completed", + "result": { + "audit": { + "adjudication_summary": "Both reviewers found it false.", + "assessments": [ + { + "focus_area": "Evidence", + "panelist_name": "Reviewer A", + "reasoning": "Both sources place the tower in Paris.", + "score": 1.0, + "warnings": [ + "Example Travel is a travel blog." + ] + }, + { + "focus_area": "Evidence", + "panelist_name": "Reviewer B", + "reasoning": "The encyclopedia entry is unambiguous.", + "score": 2.0, + "warnings": [] + } + ], + "debate_con": { + "argument": "Every source places it in Paris.", + "rebuttal": "The pro case cites no source.", + "role": "con" + }, + "debate_pro": { + "argument": "Some guides place it in Berlin.", + "rebuttal": "None of them are reliable.", + "role": "pro" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Geography", + "entities": [ + { + "name": "Eiffel Tower", + "qid": null + }, + { + "name": "Berlin", + "qid": null + } + ], + "executive_summary": "The Eiffel Tower stands in Paris, France, not in Berlin.", + "key_finding": "The Eiffel Tower is in Paris.", + "language": "en", + "lenz_score": 1, + "modified_at": null, + "presumed_intent": "Check where a landmark is.", + "sources": [ + { + "date": "2025-01-15", + "snippet": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.", + "source_name": "Example Encyclopedia", + "title": "Eiffel Tower", + "url": "https://example.org/eiffel-tower" + }, + { + "date": "", + "snippet": "Most visitors climb the tower on their first day in Paris.", + "source_name": "Example Travel", + "title": "Visiting Paris", + "url": "https://example.com/visit-paris" + } + ], + "suggested_rewrite": "The Eiffel Tower is in Paris.", + "verdict": "False", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Only two sources were found." + ] + }, + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "VerificationCompleted", + "verification_id": "68ca4aaf" + } +} diff --git a/tests/fixtures/parity/expected/webhook__verification_completed_in_batch.json b/tests/fixtures/parity/expected/webhook__verification_completed_in_batch.json new file mode 100644 index 0000000..2fff9b6 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__verification_completed_in_batch.json @@ -0,0 +1,103 @@ +{ + "event": { + "attempt": 1, + "batch_id": "7ea9cdbd4064e3cf", + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "verification.completed", + "result": { + "audit": { + "adjudication_summary": "Both reviewers found it false.", + "assessments": [ + { + "focus_area": "Evidence", + "panelist_name": "Reviewer A", + "reasoning": "Both sources place the tower in Paris.", + "score": 1.0, + "warnings": [ + "Example Travel is a travel blog." + ] + }, + { + "focus_area": "Evidence", + "panelist_name": "Reviewer B", + "reasoning": "The encyclopedia entry is unambiguous.", + "score": 2.0, + "warnings": [] + } + ], + "debate_con": { + "argument": "Every source places it in Paris.", + "rebuttal": "The pro case cites no source.", + "role": "con" + }, + "debate_pro": { + "argument": "Some guides place it in Berlin.", + "rebuttal": "None of them are reliable.", + "role": "pro" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "depth": "standard", + "domain": "Geography", + "entities": [ + { + "name": "Eiffel Tower", + "qid": null + }, + { + "name": "Berlin", + "qid": null + } + ], + "executive_summary": "The Eiffel Tower stands in Paris, France, not in Berlin.", + "key_finding": "The Eiffel Tower is in Paris.", + "language": "en", + "lenz_score": 1, + "modified_at": null, + "presumed_intent": "Check where a landmark is.", + "sources": [ + { + "date": "2025-01-15", + "snippet": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.", + "source_name": "Example Encyclopedia", + "title": "Eiffel Tower", + "url": "https://example.org/eiffel-tower" + }, + { + "date": "", + "snippet": "Most visitors climb the tower on their first day in Paris.", + "source_name": "Example Travel", + "title": "Visiting Paris", + "url": "https://example.com/visit-paris" + } + ], + "suggested_rewrite": "The Eiffel Tower is in Paris.", + "verdict": "False", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Only two sources were found." + ] + }, + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "VerificationCompleted", + "verification_id": "68ca4aaf" + } +} diff --git a/tests/fixtures/parity/expected/webhook__verification_completed_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/expected/webhook__verification_completed_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..0edf9aa --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__verification_completed_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,103 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "verification.completed", + "result": { + "audit": { + "adjudication_summary": "Both reviewers found it false.", + "assessments": [ + { + "focus_area": "Evidence", + "panelist_name": "Reviewer A", + "reasoning": "Both sources place the tower in Paris.", + "score": 1.0, + "warnings": [ + "Example Travel is a travel blog." + ] + }, + { + "focus_area": "Evidence", + "panelist_name": "Reviewer B", + "reasoning": "The encyclopedia entry is unambiguous.", + "score": 2.0, + "warnings": [] + } + ], + "debate_con": { + "argument": "Every source places it in Paris.", + "rebuttal": "The pro case cites no source.", + "role": "con" + }, + "debate_pro": { + "argument": "Some guides place it in Berlin.", + "rebuttal": "None of them are reliable.", + "role": "pro" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "depth": "standard", + "domain": "Geography", + "entities": [ + { + "name": "Eiffel Tower", + "qid": null + }, + { + "name": "Berlin", + "qid": null + } + ], + "executive_summary": "The Eiffel Tower stands in Paris, France, not in Berlin.", + "key_finding": "The Eiffel Tower is in Paris.", + "language": "en", + "lenz_score": 1, + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "presumed_intent": "Check where a landmark is.", + "sources": [ + { + "date": "2025-01-15", + "snippet": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.", + "source_name": "Example Encyclopedia", + "title": "Eiffel Tower", + "url": "https://example.org/eiffel-tower" + }, + { + "date": "", + "snippet": "Most visitors climb the tower on their first day in Paris.", + "source_name": "Example Travel", + "title": "Visiting Paris", + "url": "https://example.com/visit-paris" + } + ], + "suggested_rewrite": "The Eiffel Tower is in Paris.", + "verdict": "False", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Only two sources were found." + ] + }, + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "VerificationCompleted", + "verification_id": "68ca4aaf" + } +} diff --git a/tests/fixtures/parity/expected/webhook__verification_completed_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/expected/webhook__verification_completed_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..c573ea4 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__verification_completed_modified_at_same_day_hours_apart.json @@ -0,0 +1,103 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "verification.completed", + "result": { + "audit": { + "adjudication_summary": "Both reviewers found it false.", + "assessments": [ + { + "focus_area": "Evidence", + "panelist_name": "Reviewer A", + "reasoning": "Both sources place the tower in Paris.", + "score": 1.0, + "warnings": [ + "Example Travel is a travel blog." + ] + }, + { + "focus_area": "Evidence", + "panelist_name": "Reviewer B", + "reasoning": "The encyclopedia entry is unambiguous.", + "score": 2.0, + "warnings": [] + } + ], + "debate_con": { + "argument": "Every source places it in Paris.", + "rebuttal": "The pro case cites no source.", + "role": "con" + }, + "debate_pro": { + "argument": "Some guides place it in Berlin.", + "rebuttal": "None of them are reliable.", + "role": "pro" + }, + "panel_agreement": "unanimous" + }, + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "high", + "coverage": { + "aggregate": 500000, + "as_of": null, + "cap": 10000, + "certificate_id": null, + "certificate_url": null, + "currency": "EUR", + "reasons": [ + "plan" + ], + "status": "uncovered", + "terms_version": "v1" + }, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "depth": "standard", + "domain": "Geography", + "entities": [ + { + "name": "Eiffel Tower", + "qid": null + }, + { + "name": "Berlin", + "qid": null + } + ], + "executive_summary": "The Eiffel Tower stands in Paris, France, not in Berlin.", + "key_finding": "The Eiffel Tower is in Paris.", + "language": "en", + "lenz_score": 1, + "modified_at": null, + "presumed_intent": "Check where a landmark is.", + "sources": [ + { + "date": "2025-01-15", + "snippet": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.", + "source_name": "Example Encyclopedia", + "title": "Eiffel Tower", + "url": "https://example.org/eiffel-tower" + }, + { + "date": "", + "snippet": "Most visitors climb the tower on their first day in Paris.", + "source_name": "Example Travel", + "title": "Visiting Paris", + "url": "https://example.com/visit-paris" + } + ], + "suggested_rewrite": "The Eiffel Tower is in Paris.", + "verdict": "False", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [ + "Only two sources were found." + ] + }, + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "VerificationCompleted", + "verification_id": "68ca4aaf" + } +} diff --git a/tests/fixtures/parity/expected/webhook__verification_completed_sparse_result.json b/tests/fixtures/parity/expected/webhook__verification_completed_sparse_result.json new file mode 100644 index 0000000..51c0452 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__verification_completed_sparse_result.json @@ -0,0 +1,48 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "verification.completed", + "result": { + "audit": { + "adjudication_summary": "", + "assessments": [], + "debate_con": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "debate_pro": { + "argument": "", + "rebuttal": "", + "role": "" + }, + "panel_agreement": "" + }, + "claim": "The Eiffel Tower is in Berlin.", + "confidence": "low", + "coverage": null, + "created_at": "", + "depth": "standard", + "domain": "", + "entities": [], + "executive_summary": "", + "key_finding": "", + "language": "en", + "lenz_score": null, + "modified_at": null, + "presumed_intent": "", + "sources": [], + "suggested_rewrite": null, + "verdict": "", + "verification_id": "68ca4aaf", + "visibility": "private", + "warnings": [] + }, + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "VerificationCompleted", + "verification_id": "68ca4aaf" + } +} diff --git a/tests/fixtures/parity/expected/webhook__verification_failed_error_none.json b/tests/fixtures/parity/expected/webhook__verification_failed_error_none.json new file mode 100644 index 0000000..3081f2a --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__verification_failed_error_none.json @@ -0,0 +1,15 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "error": "", + "event": "verification.failed", + "failure_class": "internal", + "retryable": false, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "VerificationFailed", + "verification_id": null + } +} diff --git a/tests/fixtures/parity/expected/webhook__verification_failed_insufficient_evidence.json b/tests/fixtures/parity/expected/webhook__verification_failed_insufficient_evidence.json new file mode 100644 index 0000000..f455192 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__verification_failed_insufficient_evidence.json @@ -0,0 +1,15 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "error": "research_insufficient", + "event": "verification.failed", + "failure_class": "insufficient_evidence", + "retryable": false, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "VerificationFailed", + "verification_id": null + } +} diff --git a/tests/fixtures/parity/expected/webhook__verification_failed_not_a_claim.json b/tests/fixtures/parity/expected/webhook__verification_failed_not_a_claim.json new file mode 100644 index 0000000..97484e4 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__verification_failed_not_a_claim.json @@ -0,0 +1,15 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "error": "not_a_claim", + "event": "verification.failed", + "failure_class": "invalid_input", + "retryable": false, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "VerificationFailed", + "verification_id": null + } +} diff --git a/tests/fixtures/parity/expected/webhook__verification_failed_upstream_unavailable.json b/tests/fixtures/parity/expected/webhook__verification_failed_upstream_unavailable.json new file mode 100644 index 0000000..cc5caa7 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__verification_failed_upstream_unavailable.json @@ -0,0 +1,15 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "error": "framing_failed", + "event": "verification.failed", + "failure_class": "upstream_unavailable", + "retryable": true, + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "VerificationFailed", + "verification_id": null + } +} diff --git a/tests/fixtures/parity/expected/webhook__verification_needs_input_hint_none.json b/tests/fixtures/parity/expected/webhook__verification_needs_input_hint_none.json new file mode 100644 index 0000000..93f162e --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__verification_needs_input_hint_none.json @@ -0,0 +1,23 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "verification.needs_input", + "hint": "", + "needs_input": { + "claims": [ + { + "domain": "", + "text": "The Eiffel Tower is in Berlin." + } + ], + "hint": null, + "reason": "multi_claim" + }, + "status": "needs_input", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "VerificationNeedsInput", + "verification_id": null + } +} diff --git a/tests/fixtures/parity/expected/webhook__verification_needs_input_multi_claim.json b/tests/fixtures/parity/expected/webhook__verification_needs_input_multi_claim.json new file mode 100644 index 0000000..3a2f006 --- /dev/null +++ b/tests/fixtures/parity/expected/webhook__verification_needs_input_multi_claim.json @@ -0,0 +1,27 @@ +{ + "event": { + "attempt": 1, + "batch_id": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "event": "verification.needs_input", + "hint": "The text holds several distinct claims. Send the ones to check to POST /verify/{task_id}/select.", + "needs_input": { + "claims": [ + { + "domain": "", + "text": "The Earth is round." + }, + { + "domain": "Science", + "text": "The Moon is made of cheese." + } + ], + "hint": "The text holds several distinct claims. Send the ones to check to POST /verify/{task_id}/select.", + "reason": "multi_claim" + }, + "status": "needs_input", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "type": "VerificationNeedsInput", + "verification_id": null + } +} diff --git a/tests/fixtures/parity/legacy/account__api_root.json b/tests/fixtures/parity/legacy/account__api_root.json new file mode 100644 index 0000000..592cd14 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__api_root.json @@ -0,0 +1,43 @@ +{ + "status": 200, + "body": { + "name": "Lenz Public API", + "version": "v1", + "docs_url": "https://lenz.io/api/v1/docs/", + "openapi_url": "https://lenz.io/api/v1/openapi.json", + "quickstart_url": "https://lenz.io/docs/quickstart", + "developer_portal_url": "https://lenz.io/developers", + "endpoints": { + "extract": "https://lenz.io/api/v1/extract", + "assess": "https://lenz.io/api/v1/assess", + "verify": "https://lenz.io/api/v1/verify", + "ask": "https://lenz.io/api/v1/ask/{verification_id}", + "verify_status": "https://lenz.io/api/v1/verify/status/{task_id}", + "verifications": "https://lenz.io/api/v1/verifications/{verification_id}", + "library": "https://lenz.io/api/v1/library", + "usage": "https://lenz.io/api/v1/me/usage" + }, + "sdks": { + "python": { + "repository": "https://github.com/lenzhq/lenz-io-python", + "package": "https://pypi.org/project/lenz-io/", + "install": "pip install lenz-io" + }, + "node": { + "repository": "https://github.com/lenzhq/lenz-io-node", + "package": "https://www.npmjs.com/package/lenz-io", + "install": "npm install lenz-io" + } + }, + "mcp": { + "url": "https://lenz.io/mcp", + "transport": "streamable-http", + "repository": "https://github.com/lenzhq/lenz-mcp" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__ask_history_after_reset.json b/tests/fixtures/parity/legacy/account__ask_history_after_reset.json new file mode 100644 index 0000000..e9962b2 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__ask_history_after_reset.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "messages": [], + "exchanges_used": 0, + "exchange_limit": 100, + "can_send": true + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__ask_history_after_send.json b/tests/fixtures/parity/legacy/account__ask_history_after_send.json new file mode 100644 index 0000000..ded388d --- /dev/null +++ b/tests/fixtures/parity/legacy/account__ask_history_after_send.json @@ -0,0 +1,25 @@ +{ + "status": 200, + "body": { + "messages": [ + { + "role": "user", + "content": "Why?", + "created_at": "2026-10-01T09:07:00.123456+00:00" + }, + { + "role": "expert", + "content": "Because **evidence**.", + "created_at": "2026-10-01T09:14:00.123456+00:00" + } + ], + "exchanges_used": 1, + "exchange_limit": 100, + "can_send": true + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__ask_history_empty.json b/tests/fixtures/parity/legacy/account__ask_history_empty.json new file mode 100644 index 0000000..e9962b2 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__ask_history_empty.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "messages": [], + "exchanges_used": 0, + "exchange_limit": 100, + "can_send": true + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__ask_history_messages.json b/tests/fixtures/parity/legacy/account__ask_history_messages.json new file mode 100644 index 0000000..efc4809 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__ask_history_messages.json @@ -0,0 +1,25 @@ +{ + "status": 200, + "body": { + "messages": [ + { + "role": "user", + "content": "Hello", + "created_at": "2026-10-01T09:07:00.123456+00:00" + }, + { + "role": "expert", + "content": "Hi there!", + "created_at": "2026-10-01T09:14:00.123456+00:00" + } + ], + "exchanges_used": 0, + "exchange_limit": 100, + "can_send": true + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__ask_reset.json b/tests/fixtures/parity/legacy/account__ask_reset.json new file mode 100644 index 0000000..cddadae --- /dev/null +++ b/tests/fixtures/parity/legacy/account__ask_reset.json @@ -0,0 +1,11 @@ +{ + "status": 200, + "body": { + "ok": true + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__ask_send.json b/tests/fixtures/parity/legacy/account__ask_send.json new file mode 100644 index 0000000..d07ac92 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__ask_send.json @@ -0,0 +1,13 @@ +{ + "status": 200, + "body": { + "role": "expert", + "content": "Because **evidence**.", + "created_at": "2026-10-01T09:07:00.123456+00:00" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__ask_send_language.json b/tests/fixtures/parity/legacy/account__ask_send_language.json new file mode 100644 index 0000000..37c151c --- /dev/null +++ b/tests/fixtures/parity/legacy/account__ask_send_language.json @@ -0,0 +1,13 @@ +{ + "status": 200, + "body": { + "role": "expert", + "content": "Porque.", + "created_at": "2026-10-01T09:07:00.123456+00:00" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__library_empty.json b/tests/fixtures/parity/legacy/account__library_empty.json new file mode 100644 index 0000000..406be8e --- /dev/null +++ b/tests/fixtures/parity/legacy/account__library_empty.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "items": [], + "total": 0, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__library_item_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/legacy/account__library_item_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..4e168ad --- /dev/null +++ b/tests/fixtures/parity/legacy/account__library_item_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "A library claim.", + "domain": "", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "language": "en" + } + ], + "total": 1, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__library_item_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/legacy/account__library_item_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..43ecdcc --- /dev/null +++ b/tests/fixtures/parity/legacy/account__library_item_modified_at_same_day_hours_apart.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "A library claim.", + "domain": "", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "modified_at": null, + "language": "en" + } + ], + "total": 1, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__library_items.json b/tests/fixtures/parity/legacy/account__library_items.json new file mode 100644 index 0000000..a78c2b7 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__library_items.json @@ -0,0 +1,60 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "Library claim 0.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "language": "en" + }, + { + "verification_id": "4d44dfaf", + "claim": "Library claim 1.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:14:00.123456+00:00", + "modified_at": null, + "language": "en" + }, + { + "verification_id": "7c83247c", + "claim": "Library claim 2.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:21:00.123456+00:00", + "modified_at": null, + "language": "en" + } + ], + "total": 3, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__library_no_match.json b/tests/fixtures/parity/legacy/account__library_no_match.json new file mode 100644 index 0000000..406be8e --- /dev/null +++ b/tests/fixtures/parity/legacy/account__library_no_match.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "items": [], + "total": 0, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__library_page_past_end.json b/tests/fixtures/parity/legacy/account__library_page_past_end.json new file mode 100644 index 0000000..575d59b --- /dev/null +++ b/tests/fixtures/parity/legacy/account__library_page_past_end.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "items": [], + "total": 1, + "page": 2, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__library_paginated_second_page.json b/tests/fixtures/parity/legacy/account__library_paginated_second_page.json new file mode 100644 index 0000000..67e00eb --- /dev/null +++ b/tests/fixtures/parity/legacy/account__library_paginated_second_page.json @@ -0,0 +1,45 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "Paged claim 020.", + "domain": "", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "language": "en" + }, + { + "verification_id": "4d44dfaf", + "claim": "Paged claim 021.", + "domain": "", + "entities": [], + "verdict": "True", + "confidence": "low", + "lenz_score": 10, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:14:00.123456+00:00", + "modified_at": null, + "language": "en" + } + ], + "total": 22, + "page": 2, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__me_usage_extra_credits.json b/tests/fixtures/parity/legacy/account__me_usage_extra_credits.json new file mode 100644 index 0000000..8eb83cf --- /dev/null +++ b/tests/fixtures/parity/legacy/account__me_usage_extra_credits.json @@ -0,0 +1,66 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "credits": { + "total": 350, + "used": 0, + "remaining": 350, + "extra": 250, + "bonus": 250, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "verify": { + "quota_used": 0, + "quota_total": 35, + "quota_remaining": 35, + "bonus": 25, + "credits": 25, + "remaining": 35 + }, + "ask": { + "quota_used": 0, + "quota_total": 350, + "quota_remaining": 350, + "bonus": 250, + "credits": 250, + "remaining": 350 + }, + "assess": { + "quota_used": 0, + "quota_total": 350, + "quota_remaining": 350, + "bonus": 250, + "credits": 250, + "remaining": 350 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__me_usage_extra_only.json b/tests/fixtures/parity/legacy/account__me_usage_extra_only.json new file mode 100644 index 0000000..5941290 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__me_usage_extra_only.json @@ -0,0 +1,66 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "credits": { + "total": 137, + "used": 100, + "remaining": 37, + "extra": 37, + "bonus": 37, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "verify": { + "quota_used": 10, + "quota_total": 13, + "quota_remaining": 3, + "bonus": 3, + "credits": 3, + "remaining": 3 + }, + "ask": { + "quota_used": 100, + "quota_total": 137, + "quota_remaining": 37, + "bonus": 37, + "credits": 37, + "remaining": 37 + }, + "assess": { + "quota_used": 100, + "quota_total": 137, + "quota_remaining": 37, + "bonus": 37, + "credits": 37, + "remaining": 37 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__me_usage_extract_calls.json b/tests/fixtures/parity/legacy/account__me_usage_extract_calls.json new file mode 100644 index 0000000..8ed7b3c --- /dev/null +++ b/tests/fixtures/parity/legacy/account__me_usage_extract_calls.json @@ -0,0 +1,66 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "credits": { + "total": 100, + "used": 0, + "remaining": 100, + "extra": 0, + "bonus": 0, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "verify": { + "quota_used": 0, + "quota_total": 10, + "quota_remaining": 10, + "bonus": 0, + "credits": 0, + "remaining": 10 + }, + "ask": { + "quota_used": 0, + "quota_total": 100, + "quota_remaining": 100, + "bonus": 0, + "credits": 0, + "remaining": 100 + }, + "assess": { + "quota_used": 0, + "quota_total": 100, + "quota_remaining": 100, + "bonus": 0, + "credits": 0, + "remaining": 100 + }, + "extract": { + "calls_today": 7, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__me_usage_free.json b/tests/fixtures/parity/legacy/account__me_usage_free.json new file mode 100644 index 0000000..5edd565 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__me_usage_free.json @@ -0,0 +1,66 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "credits": { + "total": 100, + "used": 0, + "remaining": 100, + "extra": 0, + "bonus": 0, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "verify": { + "quota_used": 0, + "quota_total": 10, + "quota_remaining": 10, + "bonus": 0, + "credits": 0, + "remaining": 10 + }, + "ask": { + "quota_used": 0, + "quota_total": 100, + "quota_remaining": 100, + "bonus": 0, + "credits": 0, + "remaining": 100 + }, + "assess": { + "quota_used": 0, + "quota_total": 100, + "quota_remaining": 100, + "bonus": 0, + "credits": 0, + "remaining": 100 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__me_usage_free_partly_spent.json b/tests/fixtures/parity/legacy/account__me_usage_free_partly_spent.json new file mode 100644 index 0000000..7ef23a6 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__me_usage_free_partly_spent.json @@ -0,0 +1,66 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "credits": { + "total": 100, + "used": 17, + "remaining": 83, + "extra": 0, + "bonus": 0, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "verify": { + "quota_used": 2, + "quota_total": 10, + "quota_remaining": 8, + "bonus": 0, + "credits": 0, + "remaining": 8 + }, + "ask": { + "quota_used": 17, + "quota_total": 100, + "quota_remaining": 83, + "bonus": 0, + "credits": 0, + "remaining": 83 + }, + "assess": { + "quota_used": 17, + "quota_total": 100, + "quota_remaining": 83, + "bonus": 0, + "credits": 0, + "remaining": 83 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__me_usage_oauth.json b/tests/fixtures/parity/legacy/account__me_usage_oauth.json new file mode 100644 index 0000000..5edd565 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__me_usage_oauth.json @@ -0,0 +1,66 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "credits": { + "total": 100, + "used": 0, + "remaining": 100, + "extra": 0, + "bonus": 0, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "verify": { + "quota_used": 0, + "quota_total": 10, + "quota_remaining": 10, + "bonus": 0, + "credits": 0, + "remaining": 10 + }, + "ask": { + "quota_used": 0, + "quota_total": 100, + "quota_remaining": 100, + "bonus": 0, + "credits": 0, + "remaining": 100 + }, + "assess": { + "quota_used": 0, + "quota_total": 100, + "quota_remaining": 100, + "bonus": 0, + "credits": 0, + "remaining": 100 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__me_usage_plus.json b/tests/fixtures/parity/legacy/account__me_usage_plus.json new file mode 100644 index 0000000..6de7069 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__me_usage_plus.json @@ -0,0 +1,66 @@ +{ + "status": 200, + "body": { + "plan": "plus", + "plan_label": "Plus", + "quota_resets_at": "2026-10-01T14:07:00.123456+00:00", + "credits": { + "total": 500, + "used": 0, + "remaining": 500, + "extra": 0, + "bonus": 0, + "resets_at": "2026-10-01T14:07:00.123456+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "verify": { + "quota_used": 0, + "quota_total": 50, + "quota_remaining": 50, + "bonus": 0, + "credits": 0, + "remaining": 50 + }, + "ask": { + "quota_used": 0, + "quota_total": 500, + "quota_remaining": 500, + "bonus": 0, + "credits": 0, + "remaining": 500 + }, + "assess": { + "quota_used": 0, + "quota_total": 500, + "quota_remaining": 500, + "bonus": 0, + "credits": 0, + "remaining": 500 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__me_usage_pro.json b/tests/fixtures/parity/legacy/account__me_usage_pro.json new file mode 100644 index 0000000..8f14251 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__me_usage_pro.json @@ -0,0 +1,66 @@ +{ + "status": 200, + "body": { + "plan": "pro", + "plan_label": "Pro", + "quota_resets_at": "2026-10-01T14:07:00.123456+00:00", + "credits": { + "total": 5000, + "used": 0, + "remaining": 5000, + "extra": 0, + "bonus": 0, + "resets_at": "2026-10-01T14:07:00.123456+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "verify": { + "quota_used": 0, + "quota_total": 500, + "quota_remaining": 500, + "bonus": 0, + "credits": 0, + "remaining": 500 + }, + "ask": { + "quota_used": 0, + "quota_total": 5000, + "quota_remaining": 5000, + "bonus": 0, + "credits": 0, + "remaining": 5000 + }, + "assess": { + "quota_used": 0, + "quota_total": 5000, + "quota_remaining": 5000, + "bonus": 0, + "credits": 0, + "remaining": 5000 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__me_usage_pro_extra.json b/tests/fixtures/parity/legacy/account__me_usage_pro_extra.json new file mode 100644 index 0000000..fe0a019 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__me_usage_pro_extra.json @@ -0,0 +1,66 @@ +{ + "status": 200, + "body": { + "plan": "pro", + "plan_label": "Pro", + "quota_resets_at": "2026-10-01T14:07:00.123456+00:00", + "credits": { + "total": 6000, + "used": 0, + "remaining": 6000, + "extra": 1000, + "bonus": 1000, + "resets_at": "2026-10-01T14:07:00.123456+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "verify": { + "quota_used": 0, + "quota_total": 600, + "quota_remaining": 600, + "bonus": 100, + "credits": 100, + "remaining": 600 + }, + "ask": { + "quota_used": 0, + "quota_total": 6000, + "quota_remaining": 6000, + "bonus": 1000, + "credits": 1000, + "remaining": 6000 + }, + "assess": { + "quota_used": 0, + "quota_total": 6000, + "quota_remaining": 6000, + "bonus": 1000, + "credits": 1000, + "remaining": 6000 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__me_usage_stale_quota_row.json b/tests/fixtures/parity/legacy/account__me_usage_stale_quota_row.json new file mode 100644 index 0000000..5edd565 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__me_usage_stale_quota_row.json @@ -0,0 +1,66 @@ +{ + "status": 200, + "body": { + "plan": "free", + "plan_label": "Free", + "quota_resets_at": "2026-10-01T14:07:00+00:00", + "credits": { + "total": 100, + "used": 0, + "remaining": 100, + "extra": 0, + "bonus": 0, + "resets_at": "2026-10-01T14:07:00+00:00" + }, + "costs": { + "verify": 10, + "assess": 1, + "ask": 1, + "citation": 1, + "extract": 0 + }, + "cost_options": { + "verify": { + "depth": { + "standard": 10, + "low": 5 + } + } + }, + "verify": { + "quota_used": 0, + "quota_total": 10, + "quota_remaining": 10, + "bonus": 0, + "credits": 0, + "remaining": 10 + }, + "ask": { + "quota_used": 0, + "quota_total": 100, + "quota_remaining": 100, + "bonus": 0, + "credits": 0, + "remaining": 100 + }, + "assess": { + "quota_used": 0, + "quota_total": 100, + "quota_remaining": 100, + "bonus": 0, + "credits": 0, + "remaining": 100 + }, + "extract": { + "calls_today": 0, + "daily_limit": 1000, + "unlimited": false + }, + "has_webhook_secret": false + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__oauth_register_success.json b/tests/fixtures/parity/legacy/account__oauth_register_success.json new file mode 100644 index 0000000..15e9752 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__oauth_register_success.json @@ -0,0 +1,25 @@ +{ + "status": 201, + "body": { + "client_id": "lzc_0a1db81dbba84d2d473826d8", + "client_id_issued_at": "", + "client_name": "n8n", + "redirect_uris": [ + "https://acme.app.n8n.cloud/rest/oauth2-credential/callback" + ], + "grant_types": [ + "authorization_code", + "refresh_token" + ], + "response_types": [ + "code" + ], + "token_endpoint_auth_method": "none", + "scope": "assess verify ask ask:read extract history:read history:write usage:read webhooks:manage" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__oauth_revoke.json b/tests/fixtures/parity/legacy/account__oauth_revoke.json new file mode 100644 index 0000000..f0ea1e6 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__oauth_revoke.json @@ -0,0 +1,9 @@ +{ + "status": 200, + "body": {}, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__oauth_revoke_token.json b/tests/fixtures/parity/legacy/account__oauth_revoke_token.json new file mode 100644 index 0000000..f0ea1e6 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__oauth_revoke_token.json @@ -0,0 +1,9 @@ +{ + "status": 200, + "body": {}, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__webhook_secret_api_key.json b/tests/fixtures/parity/legacy/account__webhook_secret_api_key.json new file mode 100644 index 0000000..4fdb761 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__webhook_secret_api_key.json @@ -0,0 +1,12 @@ +{ + "status": 403, + "body": { + "detail": "An API key's webhook secret is managed on the API credentials page (https://lenz.io/api-credentials). This endpoint is for OAuth connections.", + "code": "oauth_only" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__webhook_secret_insufficient_scope.json b/tests/fixtures/parity/legacy/account__webhook_secret_insufficient_scope.json new file mode 100644 index 0000000..6e2d697 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__webhook_secret_insufficient_scope.json @@ -0,0 +1,14 @@ +{ + "status": 403, + "body": { + "detail": "The access token does not allow this call.", + "code": "insufficient_scope", + "scope": "webhooks:manage" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "WWW-Authenticate": "Bearer error=\"insufficient_scope\", scope=\"webhooks:manage\", resource_metadata=\"https://lenz.io/.well-known/oauth-protected-resource/api/v1\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/account__webhook_secret_oauth.json b/tests/fixtures/parity/legacy/account__webhook_secret_oauth.json new file mode 100644 index 0000000..65ec897 --- /dev/null +++ b/tests/fixtures/parity/legacy/account__webhook_secret_oauth.json @@ -0,0 +1,11 @@ +{ + "status": 200, + "body": { + "webhook_secret": "dc06a4fb5512d77eb96f64eedf3ce77dff58de30e17140fbb229a3e048c3bb93" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__401_no_key.json b/tests/fixtures/parity/legacy/assess__401_no_key.json new file mode 100644 index 0000000..54ec0b6 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__401_no_key.json @@ -0,0 +1,11 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__402_no_credits.json b/tests/fixtures/parity/legacy/assess__402_no_credits.json new file mode 100644 index 0000000..50f67b4 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__402_no_credits.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining /assess units.", + "code": "no_credits", + "doc_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__422_blank_item.json b/tests/fixtures/parity/legacy/assess__422_blank_item.json new file mode 100644 index 0000000..94cac74 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__422_blank_item.json @@ -0,0 +1,12 @@ +{ + "status": 422, + "body": { + "detail": "claims[1] is blank.", + "code": "blank_item" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__422_blank_text.json b/tests/fixtures/parity/legacy/assess__422_blank_text.json new file mode 100644 index 0000000..367f620 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__422_blank_text.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Text is required." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__422_input_conflict.json b/tests/fixtures/parity/legacy/assess__422_input_conflict.json new file mode 100644 index 0000000..5f709c8 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__422_input_conflict.json @@ -0,0 +1,12 @@ +{ + "status": 422, + "body": { + "detail": "Send either `claim` (one text) or `claims` (a list of claims), not both.", + "code": "input_conflict" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__422_item_too_long.json b/tests/fixtures/parity/legacy/assess__422_item_too_long.json new file mode 100644 index 0000000..34cbc4d --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__422_item_too_long.json @@ -0,0 +1,12 @@ +{ + "status": 422, + "body": { + "detail": "claims[1] is 2001 characters; each claim may be at most 2000. Send a document to /extract first, then assess its claims.", + "code": "item_too_long" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__422_no_input_field.json b/tests/fixtures/parity/legacy/assess__422_no_input_field.json new file mode 100644 index 0000000..591c22f --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__422_no_input_field.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": [ + { + "type": "missing", + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__422_too_many_items.json b/tests/fixtures/parity/legacy/assess__422_too_many_items.json new file mode 100644 index 0000000..4c88204 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__422_too_many_items.json @@ -0,0 +1,12 @@ +{ + "status": 422, + "body": { + "detail": "At most 20 claims per call; got 21. Split the list.", + "code": "too_many_items" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__422_wrong_type_claim.json b/tests/fixtures/parity/legacy/assess__422_wrong_type_claim.json new file mode 100644 index 0000000..dd070e7 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__422_wrong_type_claim.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": [ + { + "type": "string_type", + "loc": [ + "body", + "payload", + "claim" + ], + "msg": "Input should be a valid string" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__422_wrong_type_claims.json b/tests/fixtures/parity/legacy/assess__422_wrong_type_claims.json new file mode 100644 index 0000000..0a135da --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__422_wrong_type_claims.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": [ + { + "type": "list_type", + "loc": [ + "body", + "payload", + "claims" + ], + "msg": "Input should be a valid list" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__502_framing_failed.json b/tests/fixtures/parity/legacy/assess__502_framing_failed.json new file mode 100644 index 0000000..a15f201 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__502_framing_failed.json @@ -0,0 +1,13 @@ +{ + "status": 502, + "body": { + "detail": "Framing failed", + "code": "framing_failed", + "error": "framing_failed" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__503_capacity.json b/tests/fixtures/parity/legacy/assess__503_capacity.json new file mode 100644 index 0000000..4c5b2c2 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__503_capacity.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": 100, + "doc_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "100", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__503_list_all_upstream_unavailable.json b/tests/fixtures/parity/legacy/assess__503_list_all_upstream_unavailable.json new file mode 100644 index 0000000..d37b434 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__503_list_all_upstream_unavailable.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Our model providers are temporarily unavailable. Please retry shortly. Nothing was charged.", + "code": "upstream_unavailable", + "retry_after": 90, + "doc_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__503_upstream_unavailable.json b/tests/fixtures/parity/legacy/assess__503_upstream_unavailable.json new file mode 100644 index 0000000..9308b85 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__503_upstream_unavailable.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Our model providers are temporarily unavailable. Please retry shortly.", + "code": "upstream_unavailable", + "retry_after": 90, + "doc_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__deep_tier_hit.json b/tests/fixtures/parity/legacy/assess__deep_tier_hit.json new file mode 100644 index 0000000..ec51c5f --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__deep_tier_hit.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "claims": [ + { + "claim": "Water boils at 100C.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": "https://lenz.io/api/v1/verifications/f3436f50", + "rationale": "The claim is verified.", + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + } + ], + "error": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__idempotency_body_mismatch.json b/tests/fixtures/parity/legacy/assess__idempotency_body_mismatch.json new file mode 100644 index 0000000..2425649 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__idempotency_body_mismatch.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Idempotency-Key reused with a different request body." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__idempotency_first.json b/tests/fixtures/parity/legacy/assess__idempotency_first.json new file mode 100644 index 0000000..fedc9c5 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__idempotency_first.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "claims": [ + { + "claim": "The Earth orbits the Sun.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + } + ], + "error": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__idempotency_replay.json b/tests/fixtures/parity/legacy/assess__idempotency_replay.json new file mode 100644 index 0000000..fedc9c5 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__idempotency_replay.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "claims": [ + { + "claim": "The Earth orbits the Sun.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + } + ], + "error": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__list_all_error_rows.json b/tests/fixtures/parity/legacy/assess__list_all_error_rows.json new file mode 100644 index 0000000..d376f1f --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__list_all_error_rows.json @@ -0,0 +1,42 @@ +{ + "status": 200, + "body": { + "claims": [ + { + "claim": "hi", + "language": "en", + "verdict": "Error", + "confidence": "low", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": "no_claim", + "candidate_claims": [], + "identified_claims": [], + "hint": "The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims." + }, + { + "claim": "hello", + "language": "en", + "verdict": "Error", + "confidence": "low", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": "no_claim", + "candidate_claims": [], + "identified_claims": [], + "hint": "The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims." + } + ], + "error": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__list_compound_item.json b/tests/fixtures/parity/legacy/assess__list_compound_item.json new file mode 100644 index 0000000..cc02da1 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__list_compound_item.json @@ -0,0 +1,45 @@ +{ + "status": 200, + "body": { + "claims": [ + { + "claim": "Primary claim.", + "language": "en", + "verdict": "Mostly False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [ + "Second claim.", + "Third claim." + ], + "hint": "Assessed the main claim only. Send identified_claims as their own items to check the rest." + }, + { + "claim": "A plain claim.", + "language": "en", + "verdict": "Mostly False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + } + ], + "error": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__list_mixed_rows.json b/tests/fixtures/parity/legacy/assess__list_mixed_rows.json new file mode 100644 index 0000000..2143d2d --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__list_mixed_rows.json @@ -0,0 +1,70 @@ +{ + "status": 200, + "body": { + "claims": [ + { + "claim": "Water boils at 100 C at sea level.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "hello there", + "language": "en", + "verdict": "Error", + "confidence": "low", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": "no_claim", + "candidate_claims": [], + "identified_claims": [], + "hint": "The input is a greeting. Send one factual claim, or run the text through /extract to enumerate its claims." + }, + { + "claim": "vendor is down", + "language": "en", + "verdict": "Error", + "confidence": "low", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": "upstream_unavailable", + "candidate_claims": [], + "identified_claims": [], + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged." + }, + { + "claim": "cannot frame", + "language": "en", + "verdict": "Error", + "confidence": "low", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": "framing_failed", + "candidate_claims": [], + "identified_claims": [], + "hint": "This item could not be processed; retrying it as-is will not help. Send it rephrased as one factual statement; nothing was charged." + } + ], + "error": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__memo_hit.json b/tests/fixtures/parity/legacy/assess__memo_hit.json new file mode 100644 index 0000000..895b4d1 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__memo_hit.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "claims": [ + { + "claim": "The Danube flows through Vienna.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": "The river runs through the city.", + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + } + ], + "error": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__replay_later_200.json b/tests/fixtures/parity/legacy/assess__replay_later_200.json new file mode 100644 index 0000000..fedc9c5 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__replay_later_200.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "claims": [ + { + "claim": "The Earth orbits the Sun.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + } + ], + "error": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__single_no_claim.json b/tests/fixtures/parity/legacy/assess__single_no_claim.json new file mode 100644 index 0000000..30e6d5f --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__single_no_claim.json @@ -0,0 +1,15 @@ +{ + "status": 200, + "body": { + "claims": [], + "error": "No verifiable claim detected", + "error_code": "no_claim", + "candidate_claims": [], + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__single_one_claim.json b/tests/fixtures/parity/legacy/assess__single_one_claim.json new file mode 100644 index 0000000..329438b --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__single_one_claim.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "claims": [ + { + "claim": "The registry reported 4,200 filings in 2024.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": "The registry lists 4,200 filings for 2024 and has not revised the figure.", + "dissent": "The registry figure is provisional, so the 2024 total cannot yet be confirmed.", + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + } + ], + "error": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__single_text_over_wave_more_claims.json b/tests/fixtures/parity/legacy/assess__single_text_over_wave_more_claims.json new file mode 100644 index 0000000..fdc4751 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__single_text_over_wave_more_claims.json @@ -0,0 +1,297 @@ +{ + "status": 200, + "body": { + "claims": [ + { + "claim": "Claim number 0 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 1 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 2 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 3 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 4 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 5 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 6 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 7 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 8 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 9 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 10 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 11 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 12 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 13 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 14 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 15 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 16 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 17 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 18 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Claim number 19 is documented.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + } + ], + "error": null, + "more_claims": [ + "Claim number 20 is documented.", + "Claim number 21 is documented." + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__single_text_several_claims.json b/tests/fixtures/parity/legacy/assess__single_text_several_claims.json new file mode 100644 index 0000000..ffce99c --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__single_text_several_claims.json @@ -0,0 +1,56 @@ +{ + "status": 200, + "body": { + "claims": [ + { + "claim": "Water boils at 100 C at sea level.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "The Moon is made of cheese.", + "language": "en", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "The Pacific is the deepest ocean.", + "language": "en", + "verdict": "Mostly True", + "confidence": "medium", + "verification_url": null, + "rationale": null, + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + } + ], + "error": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/assess__suggest_rewrite.json b/tests/fixtures/parity/legacy/assess__suggest_rewrite.json new file mode 100644 index 0000000..68f4fa2 --- /dev/null +++ b/tests/fixtures/parity/legacy/assess__suggest_rewrite.json @@ -0,0 +1,42 @@ +{ + "status": 200, + "body": { + "claims": [ + { + "claim": "Venus is the closest planet to the Sun.", + "language": "en", + "verdict": "False", + "confidence": "high", + "verification_url": null, + "rationale": "Mercury, not Venus, is the closest planet to the Sun.", + "dissent": null, + "suggested_rewrite": "Mercury is the closest planet to the Sun.", + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + }, + { + "claim": "Mercury is the closest planet to the Sun.", + "language": "en", + "verdict": "True", + "confidence": "high", + "verification_url": null, + "rationale": "Mercury is the innermost planet.", + "dissent": null, + "suggested_rewrite": null, + "error_code": null, + "candidate_claims": [], + "identified_claims": [], + "hint": null + } + ], + "error": null, + "more_claims": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__402_no_credits.json b/tests/fixtures/parity/legacy/citecheck__402_no_credits.json new file mode 100644 index 0000000..a73ca33 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__402_no_credits.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining credits for citation checks.", + "code": "no_credits", + "doc_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 100, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 100, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_empty_body.json b/tests/fixtures/parity/legacy/citecheck__422_empty_body.json new file mode 100644 index 0000000..8fde0be --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_empty_body.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": "payload: Value error, send exactly one of text and pairs", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload" + ], + "msg": "Value error, send exactly one of text and pairs" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_invalid_doi.json b/tests/fixtures/parity/legacy/citecheck__422_invalid_doi.json new file mode 100644 index 0000000..7177677 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_invalid_doi.json @@ -0,0 +1,24 @@ +{ + "status": 422, + "body": { + "detail": "payload.pairs.0.doi: Send the DOI alone, like 10.1038/nature12373.", + "code": "invalid_doi", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0, + "doi" + ], + "msg": "Send the DOI alone, like 10.1038/nature12373." + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_max_citations_over_20.json b/tests/fixtures/parity/legacy/citecheck__422_max_citations_over_20.json new file mode 100644 index 0000000..710466e --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_max_citations_over_20.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "payload.max_citations: Input should be less than or equal to 20", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "max_citations" + ], + "msg": "Input should be less than or equal to 20" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_max_citations_with_pairs.json b/tests/fixtures/parity/legacy/citecheck__422_max_citations_with_pairs.json new file mode 100644 index 0000000..218964a --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_max_citations_with_pairs.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": "payload: Value error, max_citations goes with text: every pair is checked", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload" + ], + "msg": "Value error, max_citations goes with text: every pair is checked" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_pair_bad_url_scheme.json b/tests/fixtures/parity/legacy/citecheck__422_pair_bad_url_scheme.json new file mode 100644 index 0000000..b557fbf --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_pair_bad_url_scheme.json @@ -0,0 +1,24 @@ +{ + "status": 422, + "body": { + "detail": "payload.pairs.0.url: Value error, url: an http or https link", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0, + "url" + ], + "msg": "Value error, url: an http or https link" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_pair_no_source.json b/tests/fixtures/parity/legacy/citecheck__422_pair_no_source.json new file mode 100644 index 0000000..0619ab6 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_pair_no_source.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "payload.pairs.0: Value error, send exactly one of url and doi", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0 + ], + "msg": "Value error, send exactly one of url and doi" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_pair_url_and_doi.json b/tests/fixtures/parity/legacy/citecheck__422_pair_url_and_doi.json new file mode 100644 index 0000000..0619ab6 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_pair_url_and_doi.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "payload.pairs.0: Value error, send exactly one of url and doi", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0 + ], + "msg": "Value error, send exactly one of url and doi" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_pairs_empty.json b/tests/fixtures/parity/legacy/citecheck__422_pairs_empty.json new file mode 100644 index 0000000..edc2537 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_pairs_empty.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "payload.pairs: Value error, pairs: 1 to 20 items", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs" + ], + "msg": "Value error, pairs: 1 to 20 items" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_pairs_over_20.json b/tests/fixtures/parity/legacy/citecheck__422_pairs_over_20.json new file mode 100644 index 0000000..edc2537 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_pairs_over_20.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "payload.pairs: Value error, pairs: 1 to 20 items", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs" + ], + "msg": "Value error, pairs: 1 to 20 items" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_quote_not_in_statement.json b/tests/fixtures/parity/legacy/citecheck__422_quote_not_in_statement.json new file mode 100644 index 0000000..9c4f0a3 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_quote_not_in_statement.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "payload.pairs.0: Each quote must be words of its statement.", + "code": "quote_not_in_statement", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0 + ], + "msg": "Each quote must be words of its statement." + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_text_and_pairs.json b/tests/fixtures/parity/legacy/citecheck__422_text_and_pairs.json new file mode 100644 index 0000000..8fde0be --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_text_and_pairs.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": "payload: Value error, send exactly one of text and pairs", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload" + ], + "msg": "Value error, send exactly one of text and pairs" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_unknown_field.json b/tests/fixtures/parity/legacy/citecheck__422_unknown_field.json new file mode 100644 index 0000000..b63a6d8 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_unknown_field.json @@ -0,0 +1,24 @@ +{ + "status": 422, + "body": { + "detail": "payload.pairs.0.extra: Extra inputs are not permitted", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "pairs", + 0, + "extra" + ], + "msg": "Extra inputs are not permitted" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_url_input.json b/tests/fixtures/parity/legacy/citecheck__422_url_input.json new file mode 100644 index 0000000..c6786a8 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_url_input.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": "Send the page's text, with its links, to check the sources it cites.", + "code": "url_input", + "errors": [ + { + "loc": [ + "body", + "text" + ], + "msg": "Send the page's text, with its links, to check the sources it cites." + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__422_webhook_secret_missing.json b/tests/fixtures/parity/legacy/citecheck__422_webhook_secret_missing.json new file mode 100644 index 0000000..1ecf2d1 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__422_webhook_secret_missing.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.", + "code": "webhook_secret_missing", + "errors": [ + { + "loc": [ + "body", + "webhook_url" + ], + "msg": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend." + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__429_citecheck_in_flight.json b/tests/fixtures/parity/legacy/citecheck__429_citecheck_in_flight.json new file mode 100644 index 0000000..5ae869f --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__429_citecheck_in_flight.json @@ -0,0 +1,14 @@ +{ + "status": 429, + "body": { + "detail": "This account already has 3 citation checks running. Wait for one to finish.", + "code": "citecheck_in_flight", + "retry_after_seconds": 60 + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "60", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__503_capacity.json b/tests/fixtures/parity/legacy/citecheck__503_capacity.json new file mode 100644 index 0000000..085990c --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__503_capacity.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": 90, + "doc_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__503_citations_unavailable.json b/tests/fixtures/parity/legacy/citecheck__503_citations_unavailable.json new file mode 100644 index 0000000..3be14e4 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__503_citations_unavailable.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Citation checking is switched off right now. Retry later; nothing was charged.", + "code": "citations_unavailable", + "retry_after": 300, + "doc_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "300", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_404_not_found.json b/tests/fixtures/parity/legacy/citecheck__get_404_not_found.json new file mode 100644 index 0000000..5aa3709 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_404_not_found.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Citation check not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_404_review_id.json b/tests/fixtures/parity/legacy/citecheck__get_404_review_id.json new file mode 100644 index 0000000..5aa3709 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_404_review_id.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Citation check not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_410_purged.json b/tests/fixtures/parity/legacy/citecheck__get_410_purged.json new file mode 100644 index 0000000..08b9585 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_410_purged.json @@ -0,0 +1,13 @@ +{ + "status": 410, + "body": { + "detail": "This check is no longer available: its account removes content after a set period.", + "code": "purged", + "purged_at": "2026-10-01T09:07:00.123456Z" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_checking.json b/tests/fixtures/parity/legacy/citecheck__get_checking.json new file mode 100644 index 0000000..57a5d80 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_checking.json @@ -0,0 +1,103 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "checking", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "poll_after_seconds": 10, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_reached": false, + "citation_checks": { + "checked": 0, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 0 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "pending", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "pending", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_completed_clean.json b/tests/fixtures/parity/legacy/citecheck__get_completed_clean.json new file mode 100644 index 0000000..2cb9173 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_completed_clean.json @@ -0,0 +1,111 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_reached": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 2 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": null, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_completed_doi_pair.json b/tests/fixtures/parity/legacy/citecheck__get_completed_doi_pair.json new file mode 100644 index 0000000..bc7c684 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_completed_doi_pair.json @@ -0,0 +1,76 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 1 + }, + "summary": { + "citations_found": 1, + "citations_selected": 1, + "citation_limit": 1, + "citation_limit_reached": false, + "citation_checks": { + "checked": 1, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 1 + }, + "citations": [ + { + "index": 0, + "reference": "10.1038/nature12373", + "cited_url": "https://doi.org/10.1038/nature12373", + "doi": "10.1038/nature12373", + "statement": "Diamond sensors measure heat in cells.", + "quotes": [], + "position": null, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at None", + "page_published_date": null, + "page_language": "en", + "source_url": null, + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_completed_incomplete.json b/tests/fixtures/parity/legacy/citecheck__get_completed_incomplete.json new file mode 100644 index 0000000..beddca7 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_completed_incomplete.json @@ -0,0 +1,127 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "incomplete", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_reached": false, + "citation_checks": { + "checked": 1, + "unchecked": 0, + "failed": 1 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 1 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "failed", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": "The check failed on our side. Try again later.", + "failure": { + "hint": "The check failed on our side. Try again later.", + "docs_url": "https://lenz.io/docs/errors#internal", + "retryable": false, + "failure_class": "internal", + "failure_reason": "internal" + }, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [ + { + "citation_index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "failure": { + "hint": "The check failed on our side. Try again later.", + "docs_url": "https://lenz.io/docs/errors#internal", + "retryable": false, + "failure_class": "internal", + "failure_reason": "internal" + } + } + ], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_completed_issues_found.json b/tests/fixtures/parity/legacy/citecheck__get_completed_issues_found.json new file mode 100644 index 0000000..e730c7e --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_completed_issues_found.json @@ -0,0 +1,141 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 20 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_reached": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 1 + }, + "credits": { + "charged": 2 + }, + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "contradicted", + "source": "support", + "is_issue": true + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "contradicted", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [ + { + "citation_index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "finding": "contradicted", + "source": "support", + "snippet": "The source says so.", + "rationale": "The page states it.", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "failure": null + } + ], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_completed_partly_supported.json b/tests/fixtures/parity/legacy/citecheck__get_completed_partly_supported.json new file mode 100644 index 0000000..8f1a891 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_completed_partly_supported.json @@ -0,0 +1,111 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_reached": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 2 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": { + "finding": "partly_supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "partly_supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": null, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_completed_unchecked.json b/tests/fixtures/parity/legacy/citecheck__get_completed_unchecked.json new file mode 100644 index 0000000..bc4922d --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_completed_unchecked.json @@ -0,0 +1,111 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_reached": false, + "citation_checks": { + "checked": 0, + "unchecked": 2, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 0 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": { + "finding": "unchecked", + "source": null, + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "unchecked", + "snippet": null, + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": "no_text", + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": null, + "result": { + "finding": "unchecked", + "source": null, + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "unchecked", + "snippet": null, + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": "no_text", + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_failed_no_citations.json b/tests/fixtures/parity/legacy/citecheck__get_failed_no_citations.json new file mode 100644 index 0000000..6a9084b --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_failed_no_citations.json @@ -0,0 +1,42 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 20 + }, + "summary": { + "citations_found": null, + "citations_selected": null, + "citation_limit": 20, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0 + }, + "credits": { + "charged": 0 + }, + "citations": [], + "citation_issues": [], + "citation_failures": [], + "failure": { + "failure_reason": "no_citations", + "failure_class": "invalid_input", + "retryable": false, + "hint": "The text has no citation to check: no link, DOI or numbered reference with one.", + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "more_citations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_failed_upstream_unavailable.json b/tests/fixtures/parity/legacy/citecheck__get_failed_upstream_unavailable.json new file mode 100644 index 0000000..9f29da1 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_failed_upstream_unavailable.json @@ -0,0 +1,148 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 20 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_reached": false, + "citation_checks": { + "checked": 0, + "unchecked": 0, + "failed": 2 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 0 + }, + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": null, + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "failed", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": "Lenz could not reach this source just now. Try again later.", + "failure": { + "hint": "Lenz could not reach this source just now. Try again later.", + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "retryable": true, + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable" + }, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": null, + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "failed", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": "Lenz could not reach this source just now. Try again later.", + "failure": { + "hint": "Lenz could not reach this source just now. Try again later.", + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "retryable": true, + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable" + }, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [ + { + "citation_index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": { + "hint": "Lenz could not reach this source just now. Try again later.", + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "retryable": true, + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable" + } + }, + { + "citation_index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "failure": { + "hint": "Lenz could not reach this source just now. Try again later.", + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable", + "retryable": true, + "failure_class": "upstream_unavailable", + "failure_reason": "upstream_unavailable" + } + } + ], + "failure": { + "failure_reason": "upstream_unavailable", + "failure_class": "upstream_unavailable", + "retryable": true, + "hint": null, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + }, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_queued.json b/tests/fixtures/parity/legacy/citecheck__get_queued.json new file mode 100644 index 0000000..85fbb28 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_queued.json @@ -0,0 +1,72 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "queued", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "poll_after_seconds": 10, + "policy": { + "max_citations": 1 + }, + "summary": { + "citations_found": 1, + "citations_selected": 1, + "citation_limit": 1, + "citation_limit_reached": false, + "citation_checks": { + "checked": 0, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 0 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "pending", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_text_limit_exactly_at_limit.json b/tests/fixtures/parity/legacy/citecheck__get_text_limit_exactly_at_limit.json new file mode 100644 index 0000000..8740719 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_text_limit_exactly_at_limit.json @@ -0,0 +1,119 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_reached": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 2 + }, + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__get_text_limit_reached.json b/tests/fixtures/parity/legacy/citecheck__get_text_limit_reached.json new file mode 100644 index 0000000..c432a1c --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__get_text_limit_reached.json @@ -0,0 +1,93 @@ +{ + "status": 200, + "body": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 1 + }, + "summary": { + "citations_found": 2, + "citations_selected": 1, + "citation_limit": 1, + "citation_limit_reached": true, + "citation_checks": { + "checked": 1, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0 + }, + "credits": { + "charged": 1 + }, + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_citations": [ + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "sentence": "The agency said so in a statement.", + "position": { + "start": 111, + "end": 178, + "text": null + } + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__idempotency_body_mismatch_422.json b/tests/fixtures/parity/legacy/citecheck__idempotency_body_mismatch_422.json new file mode 100644 index 0000000..1c526f0 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__idempotency_body_mismatch_422.json @@ -0,0 +1,20 @@ +{ + "status": 422, + "body": { + "detail": "Idempotency-Key reused with a different request body.", + "code": "idempotency_body_mismatch", + "errors": [ + { + "loc": [ + "header" + ], + "msg": "Idempotency-Key reused with a different request body." + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__idempotency_conflict_409.json b/tests/fixtures/parity/legacy/citecheck__idempotency_conflict_409.json new file mode 100644 index 0000000..c29d230 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__idempotency_conflict_409.json @@ -0,0 +1,13 @@ +{ + "status": 409, + "body": { + "detail": "A check with this Idempotency-Key is still being created. Retry shortly.", + "code": "idempotency_conflict", + "citecheck_id": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__idempotent_replay_202.json b/tests/fixtures/parity/legacy/citecheck__idempotent_replay_202.json new file mode 100644 index 0000000..43d3598 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__idempotent_replay_202.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "citecheck_id": "8eb49302", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/citechecks/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__receipt_202.json b/tests/fixtures/parity/legacy/citecheck__receipt_202.json new file mode 100644 index 0000000..43d3598 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__receipt_202.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "citecheck_id": "8eb49302", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/citechecks/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/citecheck__receipt_202_empty_webhook_url.json b/tests/fixtures/parity/legacy/citecheck__receipt_202_empty_webhook_url.json new file mode 100644 index 0000000..43d3598 --- /dev/null +++ b/tests/fixtures/parity/legacy/citecheck__receipt_202_empty_webhook_url.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "citecheck_id": "8eb49302", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/citechecks/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__ask_bad_language.json b/tests/fixtures/parity/legacy/errors__ask_bad_language.json new file mode 100644 index 0000000..ea416f6 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__ask_bad_language.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Unsupported language 'xx-nope'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__ask_empty_message.json b/tests/fixtures/parity/legacy/errors__ask_empty_message.json new file mode 100644 index 0000000..5ee6ef6 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__ask_empty_message.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Message cannot be empty." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__ask_failed.json b/tests/fixtures/parity/legacy/errors__ask_failed.json new file mode 100644 index 0000000..f3c8931 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__ask_failed.json @@ -0,0 +1,13 @@ +{ + "status": 502, + "body": { + "detail": "The chat model could not answer this question.", + "code": "ask_failed", + "error": "ask_failed" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__ask_idempotency_key_reused.json b/tests/fixtures/parity/legacy/errors__ask_idempotency_key_reused.json new file mode 100644 index 0000000..2425649 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__ask_idempotency_key_reused.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Idempotency-Key reused with a different request body." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__ask_message_too_long.json b/tests/fixtures/parity/legacy/errors__ask_message_too_long.json new file mode 100644 index 0000000..3ad27a5 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__ask_message_too_long.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Message too long (max 500 characters)." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__ask_not_completed.json b/tests/fixtures/parity/legacy/errors__ask_not_completed.json new file mode 100644 index 0000000..6f7da62 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__ask_not_completed.json @@ -0,0 +1,11 @@ +{ + "status": 400, + "body": { + "detail": "Ask is only available for completed verifications." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__ask_reset_not_found.json b/tests/fixtures/parity/legacy/errors__ask_reset_not_found.json new file mode 100644 index 0000000..65ff442 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__ask_reset_not_found.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "detail": "Verification not found." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__ask_send_not_found.json b/tests/fixtures/parity/legacy/errors__ask_send_not_found.json new file mode 100644 index 0000000..65ff442 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__ask_send_not_found.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "detail": "Verification not found." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__auth_bad_key.json b/tests/fixtures/parity/legacy/errors__auth_bad_key.json new file mode 100644 index 0000000..54ec0b6 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__auth_bad_key.json @@ -0,0 +1,11 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__auth_bad_oauth_token.json b/tests/fixtures/parity/legacy/errors__auth_bad_oauth_token.json new file mode 100644 index 0000000..cc8ef29 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__auth_bad_oauth_token.json @@ -0,0 +1,13 @@ +{ + "status": 401, + "body": { + "detail": "The access token is invalid, expired or revoked.", + "code": "invalid_token" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "WWW-Authenticate": "Bearer error=\"invalid_token\", resource_metadata=\"https://lenz.io/.well-known/oauth-protected-resource/api/v1\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__auth_basic_scheme.json b/tests/fixtures/parity/legacy/errors__auth_basic_scheme.json new file mode 100644 index 0000000..54ec0b6 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__auth_basic_scheme.json @@ -0,0 +1,11 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__auth_expired_oauth_token.json b/tests/fixtures/parity/legacy/errors__auth_expired_oauth_token.json new file mode 100644 index 0000000..cc8ef29 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__auth_expired_oauth_token.json @@ -0,0 +1,13 @@ +{ + "status": 401, + "body": { + "detail": "The access token is invalid, expired or revoked.", + "code": "invalid_token" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "WWW-Authenticate": "Bearer error=\"invalid_token\", resource_metadata=\"https://lenz.io/.well-known/oauth-protected-resource/api/v1\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__auth_insufficient_scope.json b/tests/fixtures/parity/legacy/errors__auth_insufficient_scope.json new file mode 100644 index 0000000..4c2fcdd --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__auth_insufficient_scope.json @@ -0,0 +1,14 @@ +{ + "status": 403, + "body": { + "detail": "The access token does not allow this call.", + "code": "insufficient_scope", + "scope": "verify" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "WWW-Authenticate": "Bearer error=\"insufficient_scope\", scope=\"verify\", resource_metadata=\"https://lenz.io/.well-known/oauth-protected-resource/api/v1\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__auth_missing_bearer.json b/tests/fixtures/parity/legacy/errors__auth_missing_bearer.json new file mode 100644 index 0000000..54ec0b6 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__auth_missing_bearer.json @@ -0,0 +1,11 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__auth_missing_bearer_post.json b/tests/fixtures/parity/legacy/errors__auth_missing_bearer_post.json new file mode 100644 index 0000000..54ec0b6 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__auth_missing_bearer_post.json @@ -0,0 +1,11 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__auth_oauth_issuer_off.json b/tests/fixtures/parity/legacy/errors__auth_oauth_issuer_off.json new file mode 100644 index 0000000..54ec0b6 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__auth_oauth_issuer_off.json @@ -0,0 +1,11 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__auth_oauth_only.json b/tests/fixtures/parity/legacy/errors__auth_oauth_only.json new file mode 100644 index 0000000..4fdb761 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__auth_oauth_only.json @@ -0,0 +1,12 @@ +{ + "status": 403, + "body": { + "detail": "An API key's webhook secret is managed on the API credentials page (https://lenz.io/api-credentials). This endpoint is for OAuth connections.", + "code": "oauth_only" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__auth_private_claim_ask_history.json b/tests/fixtures/parity/legacy/errors__auth_private_claim_ask_history.json new file mode 100644 index 0000000..627261e --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__auth_private_claim_ask_history.json @@ -0,0 +1,13 @@ +{ + "status": 403, + "body": { + "detail": "This report is private.", + "code": "private_claim", + "error": "private_claim" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__auth_private_claim_ask_send.json b/tests/fixtures/parity/legacy/errors__auth_private_claim_ask_send.json new file mode 100644 index 0000000..627261e --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__auth_private_claim_ask_send.json @@ -0,0 +1,13 @@ +{ + "status": 403, + "body": { + "detail": "This report is private.", + "code": "private_claim", + "error": "private_claim" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__auth_unrecognised_prefix.json b/tests/fixtures/parity/legacy/errors__auth_unrecognised_prefix.json new file mode 100644 index 0000000..54ec0b6 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__auth_unrecognised_prefix.json @@ -0,0 +1,11 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__http_error_library_bad_curated.json b/tests/fixtures/parity/legacy/errors__http_error_library_bad_curated.json new file mode 100644 index 0000000..0a644ad --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__http_error_library_bad_curated.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Invalid curated list(s). Allowed: trivia" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__http_error_library_bad_verdict.json b/tests/fixtures/parity/legacy/errors__http_error_library_bad_verdict.json new file mode 100644 index 0000000..0e8a48d --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__http_error_library_bad_verdict.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Invalid verdict label(s). Allowed: False, Mostly False, Mixed, Mostly True, True" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__method_not_allowed_get_verify.json b/tests/fixtures/parity/legacy/errors__method_not_allowed_get_verify.json new file mode 100644 index 0000000..a769f68 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__method_not_allowed_get_verify.json @@ -0,0 +1,11 @@ +{ + "status": 405, + "body": { + "": "Method not allowed" + }, + "headers": { + "Content-Type": "text/html; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__method_not_allowed_post_library.json b/tests/fixtures/parity/legacy/errors__method_not_allowed_post_library.json new file mode 100644 index 0000000..a769f68 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__method_not_allowed_post_library.json @@ -0,0 +1,11 @@ +{ + "status": 405, + "body": { + "": "Method not allowed" + }, + "headers": { + "Content-Type": "text/html; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__not_found_ask.json b/tests/fixtures/parity/legacy/errors__not_found_ask.json new file mode 100644 index 0000000..65ff442 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__not_found_ask.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "detail": "Verification not found." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__not_found_route.json b/tests/fixtures/parity/legacy/errors__not_found_route.json new file mode 100644 index 0000000..a16648d --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__not_found_route.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "": "" + }, + "headers": { + "Content-Type": "text/html; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__not_found_verification.json b/tests/fixtures/parity/legacy/errors__not_found_verification.json new file mode 100644 index 0000000..538732c --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__not_found_verification.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "detail": "Not found." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__not_found_verify_status.json b/tests/fixtures/parity/legacy/errors__not_found_verify_status.json new file mode 100644 index 0000000..d005db5 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__not_found_verify_status.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "detail": "Task not found." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__oauth_register_disabled.json b/tests/fixtures/parity/legacy/errors__oauth_register_disabled.json new file mode 100644 index 0000000..a16648d --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__oauth_register_disabled.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "": "" + }, + "headers": { + "Content-Type": "text/html; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__oauth_register_invalid_client_metadata.json b/tests/fixtures/parity/legacy/errors__oauth_register_invalid_client_metadata.json new file mode 100644 index 0000000..461c91d --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__oauth_register_invalid_client_metadata.json @@ -0,0 +1,12 @@ +{ + "status": 400, + "body": { + "error": "invalid_client_metadata", + "error_description": "token_endpoint_auth_method must be none: Lenz registers public clients that use PKCE." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__oauth_register_invalid_redirect_uri.json b/tests/fixtures/parity/legacy/errors__oauth_register_invalid_redirect_uri.json new file mode 100644 index 0000000..63e62ba --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__oauth_register_invalid_redirect_uri.json @@ -0,0 +1,12 @@ +{ + "status": 400, + "body": { + "error": "invalid_redirect_uri", + "error_description": "Each redirect URI must be https, or http on localhost, 127.0.0.1 or [::1], without a fragment." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__oauth_revoke_invalid_client.json b/tests/fixtures/parity/legacy/errors__oauth_revoke_invalid_client.json new file mode 100644 index 0000000..a7a70ef --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__oauth_revoke_invalid_client.json @@ -0,0 +1,13 @@ +{ + "status": 401, + "body": { + "error": "invalid_client", + "error_description": "Client authentication failed." + }, + "headers": { + "Content-Type": "application/json", + "WWW-Authenticate": "Basic realm=\"lenz\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__oauth_token_invalid_client.json b/tests/fixtures/parity/legacy/errors__oauth_token_invalid_client.json new file mode 100644 index 0000000..a7a70ef --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__oauth_token_invalid_client.json @@ -0,0 +1,13 @@ +{ + "status": 401, + "body": { + "error": "invalid_client", + "error_description": "Client authentication failed." + }, + "headers": { + "Content-Type": "application/json", + "WWW-Authenticate": "Basic realm=\"lenz\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__oauth_token_invalid_grant.json b/tests/fixtures/parity/legacy/errors__oauth_token_invalid_grant.json new file mode 100644 index 0000000..88c6f64 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__oauth_token_invalid_grant.json @@ -0,0 +1,12 @@ +{ + "status": 400, + "body": { + "error": "invalid_grant", + "error_description": "The authorization is invalid or has expired." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__oauth_token_missing_grant_type.json b/tests/fixtures/parity/legacy/errors__oauth_token_missing_grant_type.json new file mode 100644 index 0000000..f989e00 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__oauth_token_missing_grant_type.json @@ -0,0 +1,11 @@ +{ + "status": 400, + "body": { + "error": "unsupported_grant_type" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__oauth_token_refresh_invalid_grant.json b/tests/fixtures/parity/legacy/errors__oauth_token_refresh_invalid_grant.json new file mode 100644 index 0000000..88c6f64 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__oauth_token_refresh_invalid_grant.json @@ -0,0 +1,12 @@ +{ + "status": 400, + "body": { + "error": "invalid_grant", + "error_description": "The authorization is invalid or has expired." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__oauth_token_unsupported_grant_type.json b/tests/fixtures/parity/legacy/errors__oauth_token_unsupported_grant_type.json new file mode 100644 index 0000000..f989e00 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__oauth_token_unsupported_grant_type.json @@ -0,0 +1,11 @@ +{ + "status": 400, + "body": { + "error": "unsupported_grant_type" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__payment_required_ask.json b/tests/fixtures/parity/legacy/errors__payment_required_ask.json new file mode 100644 index 0000000..cd203cc --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__payment_required_ask.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining ask credits.", + "code": "no_credits", + "doc_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__payment_required_assess.json b/tests/fixtures/parity/legacy/errors__payment_required_assess.json new file mode 100644 index 0000000..50f67b4 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__payment_required_assess.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining /assess units.", + "code": "no_credits", + "doc_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__payment_required_verify.json b/tests/fixtures/parity/legacy/errors__payment_required_verify.json new file mode 100644 index 0000000..bf3a6b1 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__payment_required_verify.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining claim checks.", + "code": "no_credits", + "doc_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 10 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__payment_required_verify_batch_short.json b/tests/fixtures/parity/legacy/errors__payment_required_verify_batch_short.json new file mode 100644 index 0000000..70c05cb --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__payment_required_verify_batch_short.json @@ -0,0 +1,20 @@ +{ + "status": 402, + "body": { + "detail": "Insufficient credits for batch.", + "code": "no_credits", + "doc_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "requested": 5, + "remaining": 3, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 30, + "cost": 50 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__rate_limited_extract.json b/tests/fixtures/parity/legacy/errors__rate_limited_extract.json new file mode 100644 index 0000000..1865066 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__rate_limited_extract.json @@ -0,0 +1,17 @@ +{ + "status": 429, + "body": { + "detail": "Daily /extract limit of 1000 reached for this account. The allowance is shared by every key on the account and by extractions run from the Lenz website.", + "code": "extract_daily_limit", + "limit": 1000, + "reset_in_seconds": 900, + "doc_url": "https://lenz.io/docs/errors#rate-limits", + "upgrade_url": "https://lenz.io/plans" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "900", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__service_unavailable_ask.json b/tests/fixtures/parity/legacy/errors__service_unavailable_ask.json new file mode 100644 index 0000000..88544c1 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__service_unavailable_ask.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "The chat model is unavailable right now. Retry shortly.", + "code": "upstream_unavailable", + "retry_after": 90, + "doc_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__service_unavailable_capacity.json b/tests/fixtures/parity/legacy/errors__service_unavailable_capacity.json new file mode 100644 index 0000000..b26cfff --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__service_unavailable_capacity.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": 60, + "doc_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "60", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__validation_malformed_json.json b/tests/fixtures/parity/legacy/errors__validation_malformed_json.json new file mode 100644 index 0000000..4d130b1 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__validation_malformed_json.json @@ -0,0 +1,11 @@ +{ + "status": 400, + "body": { + "detail": "Cannot parse request body (Expecting property name enclosed in double quotes: line 1 column 2 (char 1))" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__validation_missing_field_hint.json b/tests/fixtures/parity/legacy/errors__validation_missing_field_hint.json new file mode 100644 index 0000000..b887034 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__validation_missing_field_hint.json @@ -0,0 +1,27 @@ +{ + "status": 422, + "body": { + "detail": [ + { + "type": "missing", + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required" + } + ], + "hint": "Required field 'text' is missing. Unrecognised fields: content, bogus.", + "doc_url": "https://lenz.io/docs/errors#validation", + "unrecognized_fields": [ + "content", + "bogus" + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__validation_unknown_field_only.json b/tests/fixtures/parity/legacy/errors__validation_unknown_field_only.json new file mode 100644 index 0000000..c83cdc2 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__validation_unknown_field_only.json @@ -0,0 +1,26 @@ +{ + "status": 422, + "body": { + "detail": [ + { + "type": "missing", + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required" + } + ], + "hint": "Required field 'claim' is missing. Unrecognised fields: statement.", + "doc_url": "https://lenz.io/docs/errors#validation", + "unrecognized_fields": [ + "statement" + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__validation_unknown_field_wrong_type.json b/tests/fixtures/parity/legacy/errors__validation_unknown_field_wrong_type.json new file mode 100644 index 0000000..3aec659 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__validation_unknown_field_wrong_type.json @@ -0,0 +1,25 @@ +{ + "status": 422, + "body": { + "detail": [ + { + "type": "list_type", + "loc": [ + "body", + "payload", + "claims" + ], + "msg": "Input should be a valid list" + } + ], + "unrecognized_fields": [ + "bogus_field", + "another" + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__validation_wrong_type.json b/tests/fixtures/parity/legacy/errors__validation_wrong_type.json new file mode 100644 index 0000000..a2c9bcb --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__validation_wrong_type.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": [ + { + "type": "string_type", + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Input should be a valid string" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/errors__web_assess_payment_required.json b/tests/fixtures/parity/legacy/errors__web_assess_payment_required.json new file mode 100644 index 0000000..5e8991b --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__web_assess_payment_required.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No assessments left this month.", + "code": "no_credits", + "doc_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "Cookie" + } +} diff --git a/tests/fixtures/parity/legacy/errors__web_assess_signup_required.json b/tests/fixtures/parity/legacy/errors__web_assess_signup_required.json new file mode 100644 index 0000000..7621cf2 --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__web_assess_signup_required.json @@ -0,0 +1,14 @@ +{ + "status": 403, + "body": { + "detail": "Sign up to check this — it’s free.", + "code": "signup_required", + "signup_claim_stashed": false, + "attempt": "e2fffcdbaf5c6cfc1939f3eaec689a87" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "Cookie" + } +} diff --git a/tests/fixtures/parity/legacy/errors__web_review_rate_limited.json b/tests/fixtures/parity/legacy/errors__web_review_rate_limited.json new file mode 100644 index 0000000..0e7609f --- /dev/null +++ b/tests/fixtures/parity/legacy/errors__web_review_rate_limited.json @@ -0,0 +1,17 @@ +{ + "status": 429, + "body": { + "detail": "This account has used its extractions for today. The daily allowance is shared with the Lenz API. It resets at 00:00 UTC.", + "code": "extract_daily_limit", + "limit": 1000, + "reset_in_seconds": 777, + "doc_url": "https://lenz.io/docs/errors#rate-limits", + "upgrade_url": "https://lenz.io/plans" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "777", + "Cache-Control": "no-store", + "Vary": "Cookie" + } +} diff --git a/tests/fixtures/parity/legacy/extract__401_no_key.json b/tests/fixtures/parity/legacy/extract__401_no_key.json new file mode 100644 index 0000000..54ec0b6 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__401_no_key.json @@ -0,0 +1,11 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__422_blank_text.json b/tests/fixtures/parity/legacy/extract__422_blank_text.json new file mode 100644 index 0000000..367f620 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__422_blank_text.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Text is required." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__422_focus_too_long.json b/tests/fixtures/parity/legacy/extract__422_focus_too_long.json new file mode 100644 index 0000000..2f948a8 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__422_focus_too_long.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "focus must be at most 300 characters of plain text." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__422_missing_text.json b/tests/fixtures/parity/legacy/extract__422_missing_text.json new file mode 100644 index 0000000..d0c7bfd --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__422_missing_text.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": [ + { + "type": "missing", + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__429_daily_limit.json b/tests/fixtures/parity/legacy/extract__429_daily_limit.json new file mode 100644 index 0000000..1181cbb --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__429_daily_limit.json @@ -0,0 +1,17 @@ +{ + "status": 429, + "body": { + "detail": "Daily /extract limit of 1000 reached for this account. The allowance is shared by every key on the account and by extractions run from the Lenz website.", + "code": "extract_daily_limit", + "limit": 1000, + "reset_in_seconds": 3600, + "doc_url": "https://lenz.io/docs/errors#rate-limits", + "upgrade_url": "https://lenz.io/plans" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "3600", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__502_extraction_failed.json b/tests/fixtures/parity/legacy/extract__502_extraction_failed.json new file mode 100644 index 0000000..529fe27 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__502_extraction_failed.json @@ -0,0 +1,13 @@ +{ + "status": 502, + "body": { + "detail": "Extraction failed", + "code": "extraction_failed", + "error": "extraction_failed" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__503_upstream_unavailable.json b/tests/fixtures/parity/legacy/extract__503_upstream_unavailable.json new file mode 100644 index 0000000..9308b85 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__503_upstream_unavailable.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Our model providers are temporarily unavailable. Please retry shortly.", + "code": "upstream_unavailable", + "retry_after": 90, + "doc_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__focus_ready.json b/tests/fixtures/parity/legacy/extract__focus_ready.json new file mode 100644 index 0000000..2ded502 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__focus_ready.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claim": "Beta fell 3% last year.", + "identified_claims": [], + "candidate_claims": [], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "locations": null + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__idempotency_body_mismatch_422.json b/tests/fixtures/parity/legacy/extract__idempotency_body_mismatch_422.json new file mode 100644 index 0000000..2425649 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__idempotency_body_mismatch_422.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Idempotency-Key reused with a different request body." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__idempotency_replay.json b/tests/fixtures/parity/legacy/extract__idempotency_replay.json new file mode 100644 index 0000000..8f23ae8 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__idempotency_replay.json @@ -0,0 +1,31 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claim": "Alpha rose 5% in 2024.", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "candidate_claims": [], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "locations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__locate_all_dropped.json b/tests/fixtures/parity/legacy/extract__locate_all_dropped.json new file mode 100644 index 0000000..b1365bf --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__locate_all_dropped.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "status": "not_a_claim", + "claim": "", + "identified_claims": [], + "candidate_claims": [], + "domain": "", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "locations": [] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__locate_failed.json b/tests/fixtures/parity/legacy/extract__locate_failed.json new file mode 100644 index 0000000..e31d700 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__locate_failed.json @@ -0,0 +1,31 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claim": "Alpha rose 5% in 2024.", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "candidate_claims": [], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "locations": null + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__locate_leading_whitespace.json b/tests/fixtures/parity/legacy/extract__locate_leading_whitespace.json new file mode 100644 index 0000000..b59ad27 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__locate_leading_whitespace.json @@ -0,0 +1,39 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claim": "Alpha rose 5% in 2024.", + "identified_claims": [], + "candidate_claims": [], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "locations": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "start": 3, + "end": 25, + "text": "Alpha rose 5% in 2024." + } + ] + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__locate_some_dropped.json b/tests/fixtures/parity/legacy/extract__locate_some_dropped.json new file mode 100644 index 0000000..c059de8 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__locate_some_dropped.json @@ -0,0 +1,52 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claim": "Alpha rose 5% in 2024.", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "candidate_claims": [], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "locations": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "start": 0, + "end": 22, + "text": "Alpha rose 5% in 2024." + } + ] + }, + { + "claim": "Beta fell 3% last year.", + "positions": [ + { + "start": 23, + "end": 46, + "text": "Beta fell 3% last year." + } + ] + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__locate_true.json b/tests/fixtures/parity/legacy/extract__locate_true.json new file mode 100644 index 0000000..c059de8 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__locate_true.json @@ -0,0 +1,52 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claim": "Alpha rose 5% in 2024.", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "candidate_claims": [], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "locations": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "start": 0, + "end": 22, + "text": "Alpha rose 5% in 2024." + } + ] + }, + { + "claim": "Beta fell 3% last year.", + "positions": [ + { + "start": 23, + "end": 46, + "text": "Beta fell 3% last year." + } + ] + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__no_match_with_focus.json b/tests/fixtures/parity/legacy/extract__no_match_with_focus.json new file mode 100644 index 0000000..45eb087 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__no_match_with_focus.json @@ -0,0 +1,19 @@ +{ + "status": 200, + "body": { + "status": "no_match", + "claim": "", + "identified_claims": [], + "candidate_claims": [], + "domain": "", + "key_entities": [], + "presumed_intent": "", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "locations": null + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__not_a_claim.json b/tests/fixtures/parity/legacy/extract__not_a_claim.json new file mode 100644 index 0000000..a9af794 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__not_a_claim.json @@ -0,0 +1,19 @@ +{ + "status": 200, + "body": { + "status": "not_a_claim", + "claim": "", + "identified_claims": [], + "candidate_claims": [], + "domain": "", + "key_entities": [], + "presumed_intent": "", + "original_input": "What a lovely day.", + "locations": null + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__not_a_claim_beside_claims.json b/tests/fixtures/parity/legacy/extract__not_a_claim_beside_claims.json new file mode 100644 index 0000000..4e6718b --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__not_a_claim_beside_claims.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "status": "not_a_claim", + "claim": "Alpha rose 5% in 2024.", + "identified_claims": [], + "candidate_claims": [], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024.", + "locations": null + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__ready_one_claim.json b/tests/fixtures/parity/legacy/extract__ready_one_claim.json new file mode 100644 index 0000000..1b9b2b6 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__ready_one_claim.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claim": "Alpha rose 5% in 2024.", + "identified_claims": [], + "candidate_claims": [], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024.", + "locations": null + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__ready_several_claims.json b/tests/fixtures/parity/legacy/extract__ready_several_claims.json new file mode 100644 index 0000000..e31d700 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__ready_several_claims.json @@ -0,0 +1,31 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claim": "Alpha rose 5% in 2024.", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "candidate_claims": [], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "locations": null + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__replay_later_200.json b/tests/fixtures/parity/legacy/extract__replay_later_200.json new file mode 100644 index 0000000..8f23ae8 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__replay_later_200.json @@ -0,0 +1,31 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claim": "Alpha rose 5% in 2024.", + "identified_claims": [ + "Alpha rose 5% in 2024.", + "Beta fell 3% last year." + ], + "candidate_claims": [], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "Alpha rose 5% in 2024. Beta fell 3% last year.", + "locations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__url_fetch_502_unreadable.json b/tests/fixtures/parity/legacy/extract__url_fetch_502_unreadable.json new file mode 100644 index 0000000..529fe27 --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__url_fetch_502_unreadable.json @@ -0,0 +1,13 @@ +{ + "status": 502, + "body": { + "detail": "Extraction failed", + "code": "extraction_failed", + "error": "extraction_failed" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__url_fetch_503_upstream.json b/tests/fixtures/parity/legacy/extract__url_fetch_503_upstream.json new file mode 100644 index 0000000..3b1746c --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__url_fetch_503_upstream.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "The page could not be read right now. Please retry shortly.", + "code": "upstream_unavailable", + "retry_after": 90, + "doc_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/extract__url_input_located.json b/tests/fixtures/parity/legacy/extract__url_input_located.json new file mode 100644 index 0000000..8505b1e --- /dev/null +++ b/tests/fixtures/parity/legacy/extract__url_input_located.json @@ -0,0 +1,39 @@ +{ + "status": 200, + "body": { + "status": "ready", + "claim": "Alpha rose 5% in 2024.", + "identified_claims": [], + "candidate_claims": [], + "domain": "Economics", + "key_entities": [ + { + "name": "Alpha", + "type": "organization" + }, + { + "name": "Beta", + "type": "organization" + } + ], + "presumed_intent": "Verify reported figures", + "original_input": "https://example.com/an-article", + "locations": [ + { + "claim": "Alpha rose 5% in 2024.", + "positions": [ + { + "start": null, + "end": null, + "text": "Alpha rose 5% in 2024." + } + ] + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__401_no_credentials.json b/tests/fixtures/parity/legacy/review__401_no_credentials.json new file mode 100644 index 0000000..54ec0b6 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__401_no_credentials.json @@ -0,0 +1,11 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__402_no_credits.json b/tests/fixtures/parity/legacy/review__402_no_credits.json new file mode 100644 index 0000000..8fd4d67 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__402_no_credits.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining credits to assess the draft.", + "code": "no_credits", + "doc_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 100, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 100, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__402_no_credits_exhausted.json b/tests/fixtures/parity/legacy/review__402_no_credits_exhausted.json new file mode 100644 index 0000000..591f328 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__402_no_credits_exhausted.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining credits to assess the draft.", + "code": "no_credits", + "doc_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 1 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_blank_text.json b/tests/fixtures/parity/legacy/review__422_blank_text.json new file mode 100644 index 0000000..b62d04a --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_blank_text.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": "text: send the draft, or one public http(s) URL.", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "text" + ], + "msg": "text: send the draft, or one public http(s) URL." + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_citations_options_object.json b/tests/fixtures/parity/legacy/review__422_citations_options_object.json new file mode 100644 index 0000000..a09435f --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_citations_options_object.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "payload.citations: Extra inputs are not permitted", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "citations" + ], + "msg": "Extra inputs are not permitted" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_depth_unknown.json b/tests/fixtures/parity/legacy/review__422_depth_unknown.json new file mode 100644 index 0000000..e2c2889 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_depth_unknown.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "payload.escalate.depth: Input should be 'standard' or 'low'", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "depth" + ], + "msg": "Input should be 'standard' or 'low'" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_invalid_confidence_band.json b/tests/fixtures/parity/legacy/review__422_invalid_confidence_band.json new file mode 100644 index 0000000..32e16e2 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_invalid_confidence_band.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "payload.escalate.confidence: Unknown confidence band 'certain'; use low, medium or high.", + "code": "invalid_confidence_band", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "confidence" + ], + "msg": "Unknown confidence band 'certain'; use low, medium or high." + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_invalid_verdict_label.json b/tests/fixtures/parity/legacy/review__422_invalid_verdict_label.json new file mode 100644 index 0000000..320e56a --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_invalid_verdict_label.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "payload.escalate.verdicts: Unknown verdict label 'Misleading'; use one of: False, Mostly False, Mixed, Mostly True, True.", + "code": "invalid_verdict_label", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "verdicts" + ], + "msg": "Unknown verdict label 'Misleading'; use one of: False, Mostly False, Mixed, Mostly True, True." + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_max_assessments_negative.json b/tests/fixtures/parity/legacy/review__422_max_assessments_negative.json new file mode 100644 index 0000000..0715227 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_max_assessments_negative.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "payload.escalate.max_assessments: Input should be greater than or equal to 0", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "max_assessments" + ], + "msg": "Input should be greater than or equal to 0" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_max_citations_negative.json b/tests/fixtures/parity/legacy/review__422_max_citations_negative.json new file mode 100644 index 0000000..46dc9ee --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_max_citations_negative.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "payload.escalate.max_citations: Input should be greater than or equal to 0", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "max_citations" + ], + "msg": "Input should be greater than or equal to 0" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_max_citations_too_big.json b/tests/fixtures/parity/legacy/review__422_max_citations_too_big.json new file mode 100644 index 0000000..7ec1805 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_max_citations_too_big.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "payload.escalate.max_citations: Input should be less than or equal to 20", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "max_citations" + ], + "msg": "Input should be less than or equal to 20" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_max_verifications_too_big.json b/tests/fixtures/parity/legacy/review__422_max_verifications_too_big.json new file mode 100644 index 0000000..c5c773b --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_max_verifications_too_big.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "payload.escalate.max_verifications: Input should be less than or equal to 20", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "max_verifications" + ], + "msg": "Input should be less than or equal to 20" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_text_missing.json b/tests/fixtures/parity/legacy/review__422_text_missing.json new file mode 100644 index 0000000..8380243 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_text_missing.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "payload.text: Field required", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_text_wrong_type.json b/tests/fixtures/parity/legacy/review__422_text_wrong_type.json new file mode 100644 index 0000000..696b78e --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_text_wrong_type.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "payload.text: Input should be a valid string", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Input should be a valid string" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_unknown_escalate_field.json b/tests/fixtures/parity/legacy/review__422_unknown_escalate_field.json new file mode 100644 index 0000000..d188f40 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_unknown_escalate_field.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": "payload.escalate.nope: Extra inputs are not permitted", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "escalate", + "nope" + ], + "msg": "Extra inputs are not permitted" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_unknown_top_level_field.json b/tests/fixtures/parity/legacy/review__422_unknown_top_level_field.json new file mode 100644 index 0000000..ea96224 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_unknown_top_level_field.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "payload.max_verifications: Extra inputs are not permitted", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "max_verifications" + ], + "msg": "Extra inputs are not permitted" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_unsupported_language.json b/tests/fixtures/parity/legacy/review__422_unsupported_language.json new file mode 100644 index 0000000..ef3d68b --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_unsupported_language.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": "language: Unsupported language 'xx'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact.", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "language" + ], + "msg": "language: Unsupported language 'xx'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact." + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_visibility_public.json b/tests/fixtures/parity/legacy/review__422_visibility_public.json new file mode 100644 index 0000000..3b923ea --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_visibility_public.json @@ -0,0 +1,22 @@ +{ + "status": 422, + "body": { + "detail": "payload.visibility: Input should be 'private' or 'unlisted'", + "code": "validation_error", + "errors": [ + { + "loc": [ + "body", + "payload", + "visibility" + ], + "msg": "Input should be 'private' or 'unlisted'" + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__422_webhook_secret_missing.json b/tests/fixtures/parity/legacy/review__422_webhook_secret_missing.json new file mode 100644 index 0000000..1ecf2d1 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__422_webhook_secret_missing.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend.", + "code": "webhook_secret_missing", + "errors": [ + { + "loc": [ + "body", + "webhook_url" + ], + "msg": "webhook_url was supplied but this credential has no webhook signing secret. Create one on the API credentials page (an API key) or read GET /me/webhook-secret (an OAuth connection), then resend." + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__429_extract_daily_limit.json b/tests/fixtures/parity/legacy/review__429_extract_daily_limit.json new file mode 100644 index 0000000..1bc25ba --- /dev/null +++ b/tests/fixtures/parity/legacy/review__429_extract_daily_limit.json @@ -0,0 +1,17 @@ +{ + "status": 429, + "body": { + "detail": "Daily /extract limit of 1000 reached for this account. A review of a URL reads the page like /extract and counts as one /extract call.", + "code": "extract_daily_limit", + "limit": 1000, + "reset_in_seconds": 60, + "doc_url": "https://lenz.io/docs/errors#rate-limits", + "upgrade_url": "https://lenz.io/plans" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "60", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__429_review_in_flight.json b/tests/fixtures/parity/legacy/review__429_review_in_flight.json new file mode 100644 index 0000000..2129d2a --- /dev/null +++ b/tests/fixtures/parity/legacy/review__429_review_in_flight.json @@ -0,0 +1,14 @@ +{ + "status": 429, + "body": { + "detail": "This account already has 3 reviews running. Retry when one completes.", + "code": "review_in_flight", + "retry_after_seconds": 60 + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "60", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__503_capacity.json b/tests/fixtures/parity/legacy/review__503_capacity.json new file mode 100644 index 0000000..085990c --- /dev/null +++ b/tests/fixtures/parity/legacy/review__503_capacity.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": 90, + "doc_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__503_citations_capacity.json b/tests/fixtures/parity/legacy/review__503_citations_capacity.json new file mode 100644 index 0000000..085990c --- /dev/null +++ b/tests/fixtures/parity/legacy/review__503_citations_capacity.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": 90, + "doc_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "90", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__delete_not_a_route.json b/tests/fixtures/parity/legacy/review__delete_not_a_route.json new file mode 100644 index 0000000..a769f68 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__delete_not_a_route.json @@ -0,0 +1,11 @@ +{ + "status": 405, + "body": { + "": "Method not allowed" + }, + "headers": { + "Content-Type": "text/html; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_403_insufficient_scope.json b/tests/fixtures/parity/legacy/review__get_403_insufficient_scope.json new file mode 100644 index 0000000..b6b8f4f --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_403_insufficient_scope.json @@ -0,0 +1,14 @@ +{ + "status": 403, + "body": { + "detail": "The access token does not allow this call.", + "code": "insufficient_scope", + "scope": "history:read" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "WWW-Authenticate": "Bearer error=\"insufficient_scope\", scope=\"history:read\", resource_metadata=\"https://lenz.io/.well-known/oauth-protected-resource/api/v1\"", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_404_not_found.json b/tests/fixtures/parity/legacy/review__get_404_not_found.json new file mode 100644 index 0000000..e73d347 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_404_not_found.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Review not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_404_other_account.json b/tests/fixtures/parity/legacy/review__get_404_other_account.json new file mode 100644 index 0000000..e73d347 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_404_other_account.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Review not found.", + "code": "not_found" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_410_purged.json b/tests/fixtures/parity/legacy/review__get_410_purged.json new file mode 100644 index 0000000..396b15a --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_410_purged.json @@ -0,0 +1,13 @@ +{ + "status": 410, + "body": { + "detail": "This review is no longer available: its account removes content after a set period.", + "code": "purged", + "purged_at": "2026-10-01T09:07:00.123456Z" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_422_unknown_view.json b/tests/fixtures/parity/legacy/review__get_422_unknown_view.json new file mode 100644 index 0000000..c73271c --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_422_unknown_view.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": "view: use full or issues.", + "code": "validation_error", + "errors": [ + { + "loc": [ + "query", + "view" + ], + "msg": "view: use full or issues." + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_assessing.json b/tests/fixtures/parity/legacy/review__get_assessing.json new file mode 100644 index 0000000..15f9bb2 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_assessing.json @@ -0,0 +1,110 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "assessing", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 0, + "failed": 0 + }, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": 10, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": null, + "assessment": { + "status": "running", + "verdict": null, + "confidence": null, + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": null, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": null, + "result": null, + "assessment": { + "status": "running", + "verdict": null, + "confidence": null, + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": null, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_assessment_rows_full_fields.json b/tests/fixtures/parity/legacy/review__get_assessment_rows_full_fields.json new file mode 100644 index 0000000..a63744a --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_assessment_rows_full_fields.json @@ -0,0 +1,170 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "incomplete", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 0, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 1 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 1, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": null, + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "cap" + }, + "key_finding": null, + "rationale": "Two reviewers found the date wrong.", + "suggested_rewrite": "The EU AI Act entered into force in August 2024.", + "failure": null, + "suggested_edits": null + } + ], + "failures": [ + { + "claim_index": 1, + "claim": "The Eiffel Tower is in Berlin.", + "stage": "assessment", + "failure": { + "failure_reason": "timeout", + "failure_class": "upstream_unavailable", + "retryable": true, + "hint": "The check ran out of time. Retry it; nothing was charged.", + "docs_url": null + } + } + ], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "assessment", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "rationale": "Two reviewers found the date wrong.", + "dissent": "One reviewer read the claim as about the entry into force.", + "verification_url": null, + "error_code": null, + "identified_claims": [ + "The EU AI Act took effect in 2024.", + "It took effect in March." + ], + "hint": "This text holds more than one claim.", + "suggested_rewrite": "The EU AI Act entered into force in August 2024.", + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "cap" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": null, + "assessment": { + "status": "failed", + "verdict": null, + "confidence": null, + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": "timeout", + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": { + "failure_reason": "timeout", + "failure_class": "upstream_unavailable", + "retryable": true, + "hint": "The check ran out of time. Retry it; nothing was charged.", + "docs_url": null + } + }, + "escalation": null, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_clean.json b/tests/fixtures/parity/legacy/review__get_citations_clean.json new file mode 100644 index 0000000..8b713d8 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_clean.json @@ -0,0 +1,183 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_reached": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 3 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_failed_and_unchecked.json b/tests/fixtures/parity/legacy/review__get_citations_failed_and_unchecked.json new file mode 100644 index 0000000..3d74122 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_failed_and_unchecked.json @@ -0,0 +1,199 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "incomplete", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_reached": false, + "citation_checks": { + "checked": 0, + "unchecked": 1, + "failed": 1 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [ + { + "citation_index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "failure": { + "hint": "The check failed on our side. Try again later.", + "docs_url": "https://lenz.io/docs/errors#internal", + "retryable": false, + "failure_class": "internal", + "failure_reason": "internal" + } + } + ], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": null, + "check": { + "status": "failed", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": "The check failed on our side. Try again later.", + "failure": { + "hint": "The check failed on our side. Try again later.", + "docs_url": "https://lenz.io/docs/errors#internal", + "retryable": false, + "failure_class": "internal", + "failure_reason": "internal" + }, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "unchecked", + "source": null, + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "unchecked", + "snippet": null, + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": "no_text", + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_issue_full.json b/tests/fixtures/parity/legacy/review__get_citations_issue_full.json new file mode 100644 index 0000000..90333a3 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_issue_full.json @@ -0,0 +1,205 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_reached": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 1, + "citations_skipped": null + }, + "credits": { + "charged": 3 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [ + { + "citation_index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "finding": "contradicted", + "source": "support", + "snippet": "The source says so.", + "rationale": "The page states it.", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "failure": null + } + ], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "contradicted", + "source": "support", + "is_issue": true + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "contradicted", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_issue_issues_view.json b/tests/fixtures/parity/legacy/review__get_citations_issue_issues_view.json new file mode 100644 index 0000000..676571c --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_issue_issues_view.json @@ -0,0 +1,93 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "issues", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_reached": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 1, + "citations_skipped": null + }, + "credits": { + "charged": 3 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [ + { + "citation_index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "finding": "contradicted", + "source": "support", + "snippet": "The source says so.", + "rationale": "The page states it.", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "failure": null + } + ], + "citation_failures": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_limit_exactly_at_limit.json b/tests/fixtures/parity/legacy/review__get_citations_limit_exactly_at_limit.json new file mode 100644 index 0000000..117f684 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_limit_exactly_at_limit.json @@ -0,0 +1,183 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 2, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_reached": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 3 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_limit_reached.json b/tests/fixtures/parity/legacy/review__get_citations_limit_reached.json new file mode 100644 index 0000000..e4dd5cd --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_limit_reached.json @@ -0,0 +1,157 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 1, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 1, + "citation_limit": 1, + "citation_limit_reached": true, + "citation_checks": { + "checked": 1, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [ + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "sentence": "The agency said so in a statement.", + "position": { + "start": 111, + "end": 178, + "text": null + } + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_no_claim_but_citations.json b/tests/fixtures/parity/legacy/review__get_citations_no_claim_but_citations.json new file mode 100644 index 0000000..3025e57 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_no_claim_but_citations.json @@ -0,0 +1,152 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_selected": 0, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 0, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_reached": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_no_claim_no_citation.json b/tests/fixtures/parity/legacy/review__get_citations_no_claim_no_citation.json new file mode 100644 index 0000000..eca6db3 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_no_claim_no_citation.json @@ -0,0 +1,68 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_selected": null, + "claim_limit": 20, + "claim_limit_reached": null, + "input_truncated": false, + "assessments": null, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": 20, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [], + "failure": { + "failure_reason": "no_claim", + "failure_class": "invalid_input", + "retryable": false, + "hint": "No factual statement that can be checked against evidence was found in the input. Send one factual claim, or run the text through /extract to enumerate its claims.", + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "more_claims": null, + "more_claim_locations": null, + "more_citations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_not_asked.json b/tests/fixtures/parity/legacy/review__get_citations_not_asked.json new file mode 100644 index 0000000..f6afdaa --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_not_asked.json @@ -0,0 +1,100 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_only.json b/tests/fixtures/parity/legacy/review__get_citations_only.json new file mode 100644 index 0000000..c5863b1 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_only.json @@ -0,0 +1,159 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 0, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_selected": 0, + "claim_limit": 0, + "claim_limit_reached": true, + "input_truncated": false, + "assessments": { + "completed": 0, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_reached": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [ + "The EU AI Act took effect in March 2024." + ], + "more_claim_locations": [ + { + "claim": "The EU AI Act took effect in March 2024.", + "positions": null + } + ], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_partly_supported.json b/tests/fixtures/parity/legacy/review__get_citations_partly_supported.json new file mode 100644 index 0000000..51ae0f4 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_partly_supported.json @@ -0,0 +1,183 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_reached": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 3 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024, according to a report from the ministry.", + "quotes": [], + "position": { + "start": 0, + "end": 110, + "text": null + }, + "result": { + "finding": "partly_supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "partly_supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": { + "start": 111, + "end": 178, + "text": null + }, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_running.json b/tests/fixtures/parity/legacy/review__get_citations_running.json new file mode 100644 index 0000000..b7ea324 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_running.json @@ -0,0 +1,167 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "verifying", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 20, + "citation_limit_reached": false, + "citation_checks": { + "checked": 0, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": 15, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [ + { + "index": 0, + "reference": "a report from the ministry", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": null, + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "pending", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "a statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": null, + "quotes": [], + "position": null, + "result": null, + "check": { + "status": "pending", + "page_read": null, + "page_title": null, + "page_published_date": null, + "page_language": null, + "source_url": null, + "source_version": null, + "support": null, + "snippet": null, + "rationale": null, + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_skipped_switched_off.json b/tests/fixtures/parity/legacy/review__get_citations_skipped_switched_off.json new file mode 100644 index 0000000..23514b6 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_skipped_switched_off.json @@ -0,0 +1,100 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": 20, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": "switched_off" + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_citations_skipped_url_input.json b/tests/fixtures/parity/legacy/review__get_citations_skipped_url_input.json new file mode 100644 index 0000000..976d0d6 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_citations_skipped_url_input.json @@ -0,0 +1,68 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 20, + "suggest_edits": false + }, + "summary": { + "claims_selected": null, + "claim_limit": 20, + "claim_limit_reached": null, + "input_truncated": false, + "assessments": null, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": 20, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": "url_input" + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [], + "failure": { + "failure_reason": "upstream_unavailable", + "failure_class": "upstream_unavailable", + "retryable": true, + "hint": null, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + }, + "more_claims": null, + "more_claim_locations": null, + "more_citations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_claim_limit_not_reached.json b/tests/fixtures/parity/legacy/review__get_claim_limit_not_reached.json new file mode 100644 index 0000000..3e0cb66 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_claim_limit_not_reached.json @@ -0,0 +1,130 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 3, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 2, + "claim_limit": 3, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_claim_limit_reached_exact.json b/tests/fixtures/parity/legacy/review__get_claim_limit_reached_exact.json new file mode 100644 index 0000000..d044437 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_claim_limit_reached_exact.json @@ -0,0 +1,130 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 2, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 2, + "claim_limit": 2, + "claim_limit_reached": true, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_completed_assess_only.json b/tests/fixtures/parity/legacy/review__get_completed_assess_only.json new file mode 100644 index 0000000..da57c84 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_completed_assess_only.json @@ -0,0 +1,156 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 0, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 1, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 1, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": null, + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "cap" + }, + "key_finding": null, + "rationale": null, + "suggested_rewrite": null, + "failure": null, + "suggested_edits": null + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "assessment", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "cap" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_completed_clean.json b/tests/fixtures/parity/legacy/review__get_completed_clean.json new file mode 100644 index 0000000..6c37fea --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_completed_clean.json @@ -0,0 +1,130 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Paris is the capital of France.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_completed_issues_all_verified.json b/tests/fixtures/parity/legacy/review__get_completed_issues_all_verified.json new file mode 100644 index 0000000..03453bf --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_completed_issues_all_verified.json @@ -0,0 +1,261 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 3, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 3, + "failed": 0 + }, + "verifications": { + "planned": 2, + "completed": 2, + "failed": 0 + }, + "issues": 2, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 23 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "rationale": null, + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "failure": null, + "suggested_edits": null + }, + { + "claim_index": 1, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "4d44dfaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/4d44dfaf", + "url": "https://lenz.io/c/the-earth-is-round-4d44dfaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "failure": null, + "suggested_edits": null + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "Mostly False", + "confidence": "medium", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "claim": "The EU AI Act took effect in March 2024.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "executive_summary": "Summary for The EU AI Act took effect in March 2024.", + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T09:14:00.123456+00:00", + "modified_at": null, + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "failure": null + }, + "suggested_edits": null + }, + { + "index": 1, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "verification_id": "4d44dfaf", + "claim": "The Eiffel Tower is in Berlin.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T09:14:00.123456+00:00", + "modified_at": null, + "verification_url": "https://lenz.io/api/v1/verifications/4d44dfaf", + "url": "https://lenz.io/c/the-earth-is-round-4d44dfaf", + "failure": null + }, + "suggested_edits": null + }, + { + "index": 2, + "claim": "Paris is the capital of France.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_completed_issues_full.json b/tests/fixtures/parity/legacy/review__get_completed_issues_full.json new file mode 100644 index 0000000..7f38ed6 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_completed_issues_full.json @@ -0,0 +1,312 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "incomplete", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 4, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 3, + "failed": 1 + }, + "verifications": { + "planned": 2, + "completed": 1, + "failed": 1 + }, + "issues": 2, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 13 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "rationale": null, + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "failure": null, + "suggested_edits": null + }, + { + "claim_index": 2, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": "failed", + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": null, + "rationale": null, + "suggested_rewrite": null, + "failure": { + "failure_reason": "research_empty", + "failure_class": "insufficient_evidence", + "retryable": false, + "hint": null, + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence" + }, + "suggested_edits": null + } + ], + "failures": [ + { + "claim_index": 1, + "claim": "Water boils at 100 C at sea level.", + "stage": "assessment", + "failure": { + "failure_reason": "upstream_unavailable", + "failure_class": "upstream_unavailable", + "retryable": true, + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + } + ], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "Mostly False", + "confidence": "medium", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "claim": "The EU AI Act took effect in March 2024.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "executive_summary": "Summary for The EU AI Act took effect in March 2024.", + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T09:14:00.123456+00:00", + "modified_at": null, + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "failure": null + }, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": null, + "result": null, + "assessment": { + "status": "failed", + "verdict": null, + "confidence": null, + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": "upstream_unavailable", + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": { + "failure_reason": "upstream_unavailable", + "failure_class": "upstream_unavailable", + "retryable": true, + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + "escalation": null, + "verification": null, + "suggested_edits": null + }, + { + "index": 2, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "assessment", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "verification_id": null, + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "claim": null, + "language": null, + "visibility": null, + "depth": null, + "domain": null, + "entities": [], + "verdict": null, + "confidence": null, + "lenz_score": null, + "key_finding": null, + "executive_summary": null, + "suggested_rewrite": null, + "warnings": [], + "created_at": null, + "modified_at": null, + "verification_url": null, + "url": null, + "failure": { + "failure_reason": "research_empty", + "failure_class": "insufficient_evidence", + "retryable": false, + "hint": null, + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence" + }, + "status": "failed", + "content_status": "available" + }, + "suggested_edits": null + }, + { + "index": 3, + "claim": "Paris is the capital of France.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_completed_issues_view_issues.json b/tests/fixtures/parity/legacy/review__get_completed_issues_view_issues.json new file mode 100644 index 0000000..c6f0f7d --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_completed_issues_view_issues.json @@ -0,0 +1,133 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "issues", + "status": "completed", + "outcome": "incomplete", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 4, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 3, + "failed": 1 + }, + "verifications": { + "planned": 2, + "completed": 1, + "failed": 1 + }, + "issues": 2, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 13 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The EU AI Act took effect in March 2024.", + "rationale": null, + "suggested_rewrite": "Fixed: The EU AI Act took effect in March 2024.", + "failure": null, + "suggested_edits": null + }, + { + "claim_index": 2, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": "failed", + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": null, + "rationale": null, + "suggested_rewrite": null, + "failure": { + "failure_reason": "research_empty", + "failure_class": "insufficient_evidence", + "retryable": false, + "hint": null, + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence" + }, + "suggested_edits": null + } + ], + "failures": [ + { + "claim_index": 1, + "claim": "Water boils at 100 C at sea level.", + "stage": "assessment", + "failure": { + "failure_reason": "upstream_unavailable", + "failure_class": "upstream_unavailable", + "retryable": true, + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + } + ], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_completed_positions.json b/tests/fixtures/parity/legacy/review__get_completed_positions.json new file mode 100644 index 0000000..be3456b --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_completed_positions.json @@ -0,0 +1,142 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": [ + { + "start": 0, + "end": 40, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": [ + { + "start": 55, + "end": 89, + "text": "Water boils at 100 C at sea level." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_completed_recovered_claim.json b/tests/fixtures/parity/legacy/review__get_completed_recovered_claim.json new file mode 100644 index 0000000..5320c8c --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_completed_recovered_claim.json @@ -0,0 +1,100 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "Orbit Motors stock increased by 40% in 2022.", + "positions": [], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_completed_with_untraced_claim.json b/tests/fixtures/parity/legacy/review__get_completed_with_untraced_claim.json new file mode 100644 index 0000000..b46dc3c --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_completed_with_untraced_claim.json @@ -0,0 +1,142 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": [ + { + "start": 0, + "end": 40, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": [ + { + "start": 50, + "end": 84, + "text": "Water boils at 100 C at sea level." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_during_quick_check.json b/tests/fixtures/parity/legacy/review__get_during_quick_check.json new file mode 100644 index 0000000..967b16c --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_during_quick_check.json @@ -0,0 +1,88 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "assessing", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 0, + "failed": 0 + }, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": 10, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": null, + "assessment": { + "status": "running", + "verdict": null, + "confidence": null, + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": null, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_failed_every_assessment_failed.json b/tests/fixtures/parity/legacy/review__get_failed_every_assessment_failed.json new file mode 100644 index 0000000..d117ab8 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_failed_every_assessment_failed.json @@ -0,0 +1,157 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "failed", + "outcome": "incomplete", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 0, + "failed": 2 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [ + { + "claim_index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "stage": "assessment", + "failure": { + "failure_reason": "upstream_unavailable", + "failure_class": "upstream_unavailable", + "retryable": true, + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + { + "claim_index": 1, + "claim": "Water boils at 100 C at sea level.", + "stage": "assessment", + "failure": { + "failure_reason": "upstream_unavailable", + "failure_class": "upstream_unavailable", + "retryable": true, + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + } + ], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": null, + "assessment": { + "status": "failed", + "verdict": null, + "confidence": null, + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": "upstream_unavailable", + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": { + "failure_reason": "upstream_unavailable", + "failure_class": "upstream_unavailable", + "retryable": true, + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + "escalation": null, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": null, + "result": null, + "assessment": { + "status": "failed", + "verdict": null, + "confidence": null, + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": "upstream_unavailable", + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": { + "failure_reason": "upstream_unavailable", + "failure_class": "upstream_unavailable", + "retryable": true, + "hint": "A model provider was unavailable for this item. Retry it; nothing was charged.", + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + } + }, + "escalation": null, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": { + "failure_reason": "assessment_failed", + "failure_class": "upstream_unavailable", + "retryable": true, + "hint": "No claim could be assessed. Retry the review with a new Idempotency-Key; nothing was charged.", + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + }, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_failed_no_claim.json b/tests/fixtures/parity/legacy/review__get_failed_no_claim.json new file mode 100644 index 0000000..4a274ab --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_failed_no_claim.json @@ -0,0 +1,68 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": null, + "claim_limit": 20, + "claim_limit_reached": null, + "input_truncated": false, + "assessments": null, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [], + "failure": { + "failure_reason": "no_claim", + "failure_class": "invalid_input", + "retryable": false, + "hint": "The text is a greeting, not a statement about the world. Send one factual claim, or run the text through /extract to enumerate its claims.", + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "more_claims": null, + "more_claim_locations": null, + "more_citations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_failed_no_claim_untraced.json b/tests/fixtures/parity/legacy/review__get_failed_no_claim_untraced.json new file mode 100644 index 0000000..afdea14 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_failed_no_claim_untraced.json @@ -0,0 +1,68 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": null, + "claim_limit": 20, + "claim_limit_reached": null, + "input_truncated": false, + "assessments": null, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [], + "failure": { + "failure_reason": "no_claim", + "failure_class": "invalid_input", + "retryable": false, + "hint": "None of the claims found in the text could be traced back to it. Send one factual claim, or run the text through /extract to enumerate its claims.", + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "more_claims": null, + "more_claim_locations": null, + "more_citations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_more_claims.json b/tests/fixtures/parity/legacy/review__get_more_claims.json new file mode 100644 index 0000000..fc21fb8 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_more_claims.json @@ -0,0 +1,155 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 2, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 2, + "claim_limit": 2, + "claim_limit_reached": true, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": [ + { + "start": 0, + "end": 40, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": [ + { + "start": 50, + "end": 84, + "text": "Water boils at 100 C at sea level." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [ + "The Eiffel Tower is in Berlin." + ], + "more_claim_locations": [ + { + "claim": "The Eiffel Tower is in Berlin.", + "positions": [ + { + "start": 91, + "end": 121, + "text": "The Eiffel Tower is in Berlin." + } + ] + } + ], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_nested_verification_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/legacy/review__get_nested_verification_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..b3c18bb --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_nested_verification_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,151 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 1, + "completed": 1, + "failed": 0 + }, + "issues": 1, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 11 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "failure": null, + "suggested_edits": null + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T23:55:00.123456+00:00", + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "failure": null + }, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_nested_verification_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/legacy/review__get_nested_verification_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..12724a6 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_nested_verification_modified_at_same_day_hours_apart.json @@ -0,0 +1,151 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 1, + "completed": 1, + "failed": 0 + }, + "issues": 1, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 11 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "failure": null, + "suggested_edits": null + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T08:00:00.123456+00:00", + "modified_at": null, + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "failure": null + }, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_policy_resolved.json b/tests/fixtures/parity/legacy/review__get_policy_resolved.json new file mode 100644 index 0000000..20bfc3f --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_policy_resolved.json @@ -0,0 +1,98 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 2, + "depth": "low", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_queued.json b/tests/fixtures/parity/legacy/review__get_queued.json new file mode 100644 index 0000000..7e2880c --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_queued.json @@ -0,0 +1,62 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "queued", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": null, + "claim_limit": 20, + "claim_limit_reached": null, + "input_truncated": false, + "assessments": null, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": 10, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [], + "failure": null, + "more_claims": null, + "more_claim_locations": null, + "more_citations": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_suggested_edits.json b/tests/fixtures/parity/legacy/review__get_suggested_edits.json new file mode 100644 index 0000000..159dab2 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_suggested_edits.json @@ -0,0 +1,269 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "verifying", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "suggest_edits": true, + "max_citations": 0 + }, + "summary": { + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 2, + "completed": 1, + "failed": 0 + }, + "issues": 2, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 12 + }, + "poll_after_seconds": 15, + "issues": [ + { + "claim_index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "failure": null, + "suggested_edits": { + "status": "completed", + "edits": [ + { + "position": 0, + "start": 23, + "end": 29, + "text": "Berlin", + "replacement": "Paris" + } + ] + } + }, + { + "claim_index": 1, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": "processing", + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": null, + "rationale": null, + "suggested_rewrite": null, + "failure": null, + "suggested_edits": { + "status": "pending", + "edits": null + } + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "positions": [ + { + "start": 0, + "end": 30, + "text": "The Eiffel Tower is in Berlin." + } + ], + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T09:14:00.123456+00:00", + "modified_at": null, + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "failure": null + }, + "suggested_edits": { + "status": "completed", + "edits": [ + { + "position": 0, + "start": 23, + "end": 29, + "text": "Berlin", + "replacement": "Paris" + } + ] + } + }, + { + "index": 1, + "claim": "The EU AI Act took effect in March 2024.", + "positions": [ + { + "start": 45, + "end": 85, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "verdict": "False", + "confidence": "high", + "source": "assessment", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "processing", + "content_status": "available", + "verification_id": null, + "task_id": null, + "claim": null, + "language": null, + "visibility": null, + "depth": null, + "domain": null, + "entities": [], + "verdict": null, + "confidence": null, + "lenz_score": null, + "key_finding": null, + "executive_summary": null, + "suggested_rewrite": null, + "warnings": [], + "created_at": null, + "modified_at": null, + "verification_url": null, + "url": null, + "failure": null + }, + "suggested_edits": { + "status": "pending", + "edits": null + } + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_suggested_edits_issues_view.json b/tests/fixtures/parity/legacy/review__get_suggested_edits_issues_view.json new file mode 100644 index 0000000..a3f8882 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_suggested_edits_issues_view.json @@ -0,0 +1,128 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "issues", + "status": "verifying", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "suggest_edits": true, + "max_citations": 0 + }, + "summary": { + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 2, + "completed": 1, + "failed": 0 + }, + "issues": 2, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 12 + }, + "poll_after_seconds": 15, + "issues": [ + { + "claim_index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "failure": null, + "suggested_edits": { + "status": "completed", + "edits": [ + { + "position": 0, + "start": 23, + "end": 29, + "text": "Berlin", + "replacement": "Paris" + } + ] + } + }, + { + "claim_index": 1, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": "processing", + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": null, + "rationale": null, + "suggested_rewrite": null, + "failure": null, + "suggested_edits": { + "status": "pending", + "edits": null + } + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_url_review.json b/tests/fixtures/parity/legacy/review__get_url_review.json new file mode 100644 index 0000000..cbc4a81 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_url_review.json @@ -0,0 +1,106 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": [ + { + "start": null, + "end": null, + "text": "The EU AI Act took effect in March 2024." + } + ], + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__get_verifying.json b/tests/fixtures/parity/legacy/review__get_verifying.json new file mode 100644 index 0000000..39f630e --- /dev/null +++ b/tests/fixtures/parity/legacy/review__get_verifying.json @@ -0,0 +1,179 @@ +{ + "status": 200, + "body": { + "review_id": "d6b2bd72", + "view": "full", + "status": "verifying", + "outcome": null, + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": null, + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 2, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 2, + "failed": 0 + }, + "verifications": { + "planned": 1, + "completed": 0, + "failed": 0 + }, + "issues": 1, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 2 + }, + "poll_after_seconds": 15, + "issues": [ + { + "claim_index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "assessment", + "verification_id": null, + "verification_status": "processing", + "verification_url": null, + "url": null, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": null, + "rationale": null, + "suggested_rewrite": null, + "failure": null, + "suggested_edits": null + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The EU AI Act took effect in March 2024.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "assessment", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "processing", + "content_status": "available", + "verification_id": null, + "task_id": null, + "claim": null, + "language": null, + "visibility": null, + "depth": null, + "domain": null, + "entities": [], + "verdict": null, + "confidence": null, + "lenz_score": null, + "key_finding": null, + "executive_summary": null, + "suggested_rewrite": null, + "warnings": [], + "created_at": null, + "modified_at": null, + "verification_url": null, + "url": null, + "failure": null + }, + "suggested_edits": null + }, + { + "index": 1, + "claim": "Water boils at 100 C at sea level.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__idempotency_body_mismatch_422.json b/tests/fixtures/parity/legacy/review__idempotency_body_mismatch_422.json new file mode 100644 index 0000000..1c526f0 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__idempotency_body_mismatch_422.json @@ -0,0 +1,20 @@ +{ + "status": 422, + "body": { + "detail": "Idempotency-Key reused with a different request body.", + "code": "idempotency_body_mismatch", + "errors": [ + { + "loc": [ + "header" + ], + "msg": "Idempotency-Key reused with a different request body." + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__idempotency_conflict_409.json b/tests/fixtures/parity/legacy/review__idempotency_conflict_409.json new file mode 100644 index 0000000..e0a63b2 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__idempotency_conflict_409.json @@ -0,0 +1,13 @@ +{ + "status": 409, + "body": { + "detail": "A review with this Idempotency-Key is still being created. Retry shortly.", + "code": "idempotency_conflict", + "review_id": null + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__idempotency_conflict_409_existing_review.json b/tests/fixtures/parity/legacy/review__idempotency_conflict_409_existing_review.json new file mode 100644 index 0000000..e91fe17 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__idempotency_conflict_409_existing_review.json @@ -0,0 +1,13 @@ +{ + "status": 409, + "body": { + "detail": "A review with this Idempotency-Key is still being created. Retry shortly.", + "code": "idempotency_conflict", + "review_id": "d6b2bd72" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__idempotent_replay_202.json b/tests/fixtures/parity/legacy/review__idempotent_replay_202.json new file mode 100644 index 0000000..ea99cf8 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__idempotent_replay_202.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/reviews/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__receipt_202.json b/tests/fixtures/parity/legacy/review__receipt_202.json new file mode 100644 index 0000000..ea99cf8 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__receipt_202.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/reviews/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__receipt_202_empty_webhook_url.json b/tests/fixtures/parity/legacy/review__receipt_202_empty_webhook_url.json new file mode 100644 index 0000000..ea99cf8 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__receipt_202_empty_webhook_url.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/reviews/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__receipt_202_webhook_url.json b/tests/fixtures/parity/legacy/review__receipt_202_webhook_url.json new file mode 100644 index 0000000..ea99cf8 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__receipt_202_webhook_url.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/reviews/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/review__replay_later_202.json b/tests/fixtures/parity/legacy/review__replay_later_202.json new file mode 100644 index 0000000..ea99cf8 --- /dev/null +++ b/tests/fixtures/parity/legacy/review__replay_later_202.json @@ -0,0 +1,14 @@ +{ + "status": 202, + "body": { + "review_id": "d6b2bd72", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "20", + "Location": "/api/v1/reviews/d6b2bd72", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__batch_202.json b/tests/fixtures/parity/legacy/verify__batch_202.json new file mode 100644 index 0000000..f35e0ac --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__batch_202.json @@ -0,0 +1,21 @@ +{ + "status": 202, + "body": { + "batch_id": "7ea9cdbd4064e3cf", + "items": [ + { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "claim_text": "The Earth is round." + }, + { + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "claim_text": "Water boils at 100C at sea level." + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__batch_capacity_503.json b/tests/fixtures/parity/legacy/verify__batch_capacity_503.json new file mode 100644 index 0000000..ea99c5b --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__batch_capacity_503.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": "", + "doc_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__batch_empty_422.json b/tests/fixtures/parity/legacy/verify__batch_empty_422.json new file mode 100644 index 0000000..8cda82f --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__batch_empty_422.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "claims is required and must be non-empty." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__batch_idempotency_conflict_409.json b/tests/fixtures/parity/legacy/verify__batch_idempotency_conflict_409.json new file mode 100644 index 0000000..ece0599 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__batch_idempotency_conflict_409.json @@ -0,0 +1,12 @@ +{ + "status": 409, + "body": { + "detail": "A request with this Idempotency-Key is already in progress.", + "task_id": "7cff18d" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__batch_item_missing_claim_422.json b/tests/fixtures/parity/legacy/verify__batch_item_missing_claim_422.json new file mode 100644 index 0000000..aa586cc --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__batch_item_missing_claim_422.json @@ -0,0 +1,23 @@ +{ + "status": 422, + "body": { + "detail": [ + { + "type": "missing", + "loc": [ + "body", + "payload", + "claims", + 1, + "text" + ], + "msg": "Field required" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__batch_no_credits_402.json b/tests/fixtures/parity/legacy/verify__batch_no_credits_402.json new file mode 100644 index 0000000..3bc3035 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__batch_no_credits_402.json @@ -0,0 +1,20 @@ +{ + "status": 402, + "body": { + "detail": "Insufficient credits for batch.", + "code": "no_credits", + "doc_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "requested": 1, + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 10 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__batch_partial_202.json b/tests/fixtures/parity/legacy/verify__batch_partial_202.json new file mode 100644 index 0000000..8b689ea --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__batch_partial_202.json @@ -0,0 +1,18 @@ +{ + "status": 202, + "body": { + "batch_id": "7ea9cdbd4064e3cf", + "items": [ + { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "claim_text": "First claim." + } + ], + "partial": true + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__batch_too_many_422.json b/tests/fixtures/parity/legacy/verify__batch_too_many_422.json new file mode 100644 index 0000000..95e938a --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__batch_too_many_422.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Batch size exceeds maximum of 20." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__blank_claim_422.json b/tests/fixtures/parity/legacy/verify__blank_claim_422.json new file mode 100644 index 0000000..367f620 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__blank_claim_422.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Text is required." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__capacity_503.json b/tests/fixtures/parity/legacy/verify__capacity_503.json new file mode 100644 index 0000000..ea99c5b --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__capacity_503.json @@ -0,0 +1,15 @@ +{ + "status": 503, + "body": { + "detail": "Lenz is at capacity right now — please resubmit after the stated wait. Nothing was charged.", + "code": "capacity", + "retry_after": "", + "doc_url": "https://lenz.io/docs/errors#unavailable" + }, + "headers": { + "Content-Type": "application/json", + "Retry-After": "", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__delete_200.json b/tests/fixtures/parity/legacy/verify__delete_200.json new file mode 100644 index 0000000..cddadae --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__delete_200.json @@ -0,0 +1,11 @@ +{ + "status": 200, + "body": { + "ok": true + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__delete_404.json b/tests/fixtures/parity/legacy/verify__delete_404.json new file mode 100644 index 0000000..538732c --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__delete_404.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "detail": "Not found." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__delete_not_yours_404.json b/tests/fixtures/parity/legacy/verify__delete_not_yours_404.json new file mode 100644 index 0000000..538732c --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__delete_not_yours_404.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "detail": "Not found." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__idempotency_body_mismatch_422.json b/tests/fixtures/parity/legacy/verify__idempotency_body_mismatch_422.json new file mode 100644 index 0000000..2425649 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__idempotency_body_mismatch_422.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Idempotency-Key reused with a different request body." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__idempotency_conflict_409.json b/tests/fixtures/parity/legacy/verify__idempotency_conflict_409.json new file mode 100644 index 0000000..7f1510e --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__idempotency_conflict_409.json @@ -0,0 +1,12 @@ +{ + "status": 409, + "body": { + "detail": "A request with this Idempotency-Key is already in progress.", + "task_id": "7cff18da2d979d6370e54a160be121ad" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__idempotency_key_replay.json b/tests/fixtures/parity/legacy/verify__idempotency_key_replay.json new file mode 100644 index 0000000..1991e8a --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__idempotency_key_replay.json @@ -0,0 +1,13 @@ +{ + "status": 202, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued", + "chain_id": "99a0a9ca89e1e72c" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__implicit_dedup_200.json b/tests/fixtures/parity/legacy/verify__implicit_dedup_200.json new file mode 100644 index 0000000..79d39ad --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__implicit_dedup_200.json @@ -0,0 +1,12 @@ +{ + "status": 200, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__implicit_repeat_replay.json b/tests/fixtures/parity/legacy/verify__implicit_repeat_replay.json new file mode 100644 index 0000000..1991e8a --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__implicit_repeat_replay.json @@ -0,0 +1,13 @@ +{ + "status": 202, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued", + "chain_id": "99a0a9ca89e1e72c" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__invalid_depth_422.json b/tests/fixtures/parity/legacy/verify__invalid_depth_422.json new file mode 100644 index 0000000..6f04ccd --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__invalid_depth_422.json @@ -0,0 +1,24 @@ +{ + "status": 422, + "body": { + "detail": [ + { + "type": "literal_error", + "loc": [ + "body", + "payload", + "depth" + ], + "msg": "Input should be 'standard' or 'low'", + "ctx": { + "expected": "'standard' or 'low'" + } + } + ] + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__invalid_language_422.json b/tests/fixtures/parity/legacy/verify__invalid_language_422.json new file mode 100644 index 0000000..20922c8 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__invalid_language_422.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Unsupported language 'xx-not-a-language'. Supported: en, es, de, fr, it, pt, nl, sv, da, no, fi, bg. To ask for another language, contact us at https://lenz.io/contact." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__list_200.json b/tests/fixtures/parity/legacy/verify__list_200.json new file mode 100644 index 0000000..d7f28ec --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__list_200.json @@ -0,0 +1,45 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "language": "en" + }, + { + "verification_id": "4d44dfaf", + "claim": "The Earth is round.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:14:00.123456+00:00", + "modified_at": null, + "language": "en" + } + ], + "total": 2, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__list_200_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/legacy/verify__list_200_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..e2419b1 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__list_200_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "language": "en" + } + ], + "total": 1, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__list_200_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/legacy/verify__list_200_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..f5c69c0 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__list_200_modified_at_same_day_hours_apart.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "modified_at": null, + "language": "en" + } + ], + "total": 1, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__list_clamped_200.json b/tests/fixtures/parity/legacy/verify__list_clamped_200.json new file mode 100644 index 0000000..c208418 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__list_clamped_200.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "items": [], + "total": 0, + "page": 1, + "page_size": 100 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__list_empty_200.json b/tests/fixtures/parity/legacy/verify__list_empty_200.json new file mode 100644 index 0000000..406be8e --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__list_empty_200.json @@ -0,0 +1,14 @@ +{ + "status": 200, + "body": { + "items": [], + "total": 0, + "page": 1, + "page_size": 20 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__list_page2_200.json b/tests/fixtures/parity/legacy/verify__list_page2_200.json new file mode 100644 index 0000000..438afdc --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__list_page2_200.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "items": [ + { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "domain": "Science", + "entities": [], + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "language": "en" + } + ], + "total": 3, + "page": 2, + "page_size": 2 + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__misnamed_field_422.json b/tests/fixtures/parity/legacy/verify__misnamed_field_422.json new file mode 100644 index 0000000..c83cdc2 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__misnamed_field_422.json @@ -0,0 +1,26 @@ +{ + "status": 422, + "body": { + "detail": [ + { + "type": "missing", + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required" + } + ], + "hint": "Required field 'claim' is missing. Unrecognised fields: statement.", + "doc_url": "https://lenz.io/docs/errors#validation", + "unrecognized_fields": [ + "statement" + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__missing_claim_422.json b/tests/fixtures/parity/legacy/verify__missing_claim_422.json new file mode 100644 index 0000000..591c22f --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__missing_claim_422.json @@ -0,0 +1,21 @@ +{ + "status": 422, + "body": { + "detail": [ + { + "type": "missing", + "loc": [ + "body", + "payload", + "text" + ], + "msg": "Field required" + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__no_credits_402.json b/tests/fixtures/parity/legacy/verify__no_credits_402.json new file mode 100644 index 0000000..bf3a6b1 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__no_credits_402.json @@ -0,0 +1,19 @@ +{ + "status": 402, + "body": { + "detail": "No remaining claim checks.", + "code": "no_credits", + "doc_url": "https://lenz.io/docs/errors#quota", + "upgrade_url": "https://lenz.io/plans?wall=6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "wall_id": "6b86b273-ff34-4ce1-8d6b-804eff5a3f57", + "remaining": 0, + "resets_at": "2026-10-01T14:07:00+00:00", + "credits_remaining": 0, + "cost": 10 + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__replay_later_202.json b/tests/fixtures/parity/legacy/verify__replay_later_202.json new file mode 100644 index 0000000..1991e8a --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__replay_later_202.json @@ -0,0 +1,13 @@ +{ + "status": 202, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued", + "chain_id": "99a0a9ca89e1e72c" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__select_202.json b/tests/fixtures/parity/legacy/verify__select_202.json new file mode 100644 index 0000000..f35e0ac --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__select_202.json @@ -0,0 +1,21 @@ +{ + "status": 202, + "body": { + "batch_id": "7ea9cdbd4064e3cf", + "items": [ + { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "claim_text": "The Earth is round." + }, + { + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "claim_text": "Water boils at 100C at sea level." + } + ] + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__select_empty_422.json b/tests/fixtures/parity/legacy/verify__select_empty_422.json new file mode 100644 index 0000000..a688edc --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__select_empty_422.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "texts is required and must be non-empty." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__select_invalid_selection_422.json b/tests/fixtures/parity/legacy/verify__select_invalid_selection_422.json new file mode 100644 index 0000000..1102de9 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__select_invalid_selection_422.json @@ -0,0 +1,13 @@ +{ + "status": 422, + "body": { + "detail": "Selected text was not one of the offered claims: 'The Moon is made of cheese.'", + "code": "invalid_selection", + "error": "invalid_selection" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__select_no_selection_pending_409.json b/tests/fixtures/parity/legacy/verify__select_no_selection_pending_409.json new file mode 100644 index 0000000..9d0e763 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__select_no_selection_pending_409.json @@ -0,0 +1,13 @@ +{ + "status": 409, + "body": { + "detail": "This task has no pending claim selection.", + "code": "no_selection_pending", + "error": "no_selection_pending" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__select_too_many_422.json b/tests/fixtures/parity/legacy/verify__select_too_many_422.json new file mode 100644 index 0000000..8cab81a --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__select_too_many_422.json @@ -0,0 +1,11 @@ +{ + "status": 422, + "body": { + "detail": "Cannot select more than 20 claims." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__select_unknown_task_404.json b/tests/fixtures/parity/legacy/verify__select_unknown_task_404.json new file mode 100644 index 0000000..d005db5 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__select_unknown_task_404.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "detail": "Task not found." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_cancelled_after_a_while.json b/tests/fixtures/parity/legacy/verify__status_cancelled_after_a_while.json new file mode 100644 index 0000000..d175b8e --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_cancelled_after_a_while.json @@ -0,0 +1,17 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "error": "Cancelled.", + "failure_reason": "cancelled", + "failure_class": "cancelled", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#cancelled" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_completed.json b/tests/fixtures/parity/legacy/verify__status_completed.json new file mode 100644 index 0000000..2b34cd1 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_completed.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_completed_after_a_while.json b/tests/fixtures/parity/legacy/verify__status_completed_after_a_while.json new file mode 100644 index 0000000..2b34cd1 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_completed_after_a_while.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_completed_after_a_while_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/legacy/verify__status_completed_after_a_while_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..068ec2d --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_completed_after_a_while_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_completed_after_a_while_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/legacy/verify__status_completed_after_a_while_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..346ec77 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_completed_after_a_while_modified_at_same_day_hours_apart.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_completed_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/legacy/verify__status_completed_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..068ec2d --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_completed_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_completed_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/legacy/verify__status_completed_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..346ec77 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_completed_modified_at_same_day_hours_apart.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_failed.json b/tests/fixtures/parity/legacy/verify__status_failed.json new file mode 100644 index 0000000..77f7bff --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_failed.json @@ -0,0 +1,17 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "error": "Pipeline stopped at: research_empty", + "failure_reason": "research_empty", + "failure_class": "insufficient_evidence", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_failed_after_a_while.json b/tests/fixtures/parity/legacy/verify__status_failed_after_a_while.json new file mode 100644 index 0000000..a0010b0 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_failed_after_a_while.json @@ -0,0 +1,17 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "error": "Pipeline stopped: conclusion_failed.", + "failure_reason": "conclusion_failed", + "failure_class": "internal", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#internal" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_failed_after_a_while_framing.json b/tests/fixtures/parity/legacy/verify__status_failed_after_a_while_framing.json new file mode 100644 index 0000000..a0c6b65 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_failed_after_a_while_framing.json @@ -0,0 +1,17 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "error": "Pipeline stopped: framing_failed.", + "failure_reason": "framing_failed", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_failed_retryable.json b/tests/fixtures/parity/legacy/verify__status_failed_retryable.json new file mode 100644 index 0000000..05f97a9 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_failed_retryable.json @@ -0,0 +1,17 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "error": "Pipeline stopped at: adjudication_failed", + "failure_reason": "adjudication_failed", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_needs_input.json b/tests/fixtures/parity/legacy/verify__status_needs_input.json new file mode 100644 index 0000000..4cb32ed --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_needs_input.json @@ -0,0 +1,24 @@ +{ + "status": 200, + "body": { + "status": "needs_input", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "reason": "multi_claim", + "claims": [ + { + "text": "The Earth is round.", + "domain": "Science" + }, + { + "text": "Water boils at 100C at sea level.", + "domain": "Science" + } + ], + "hint": "The text holds several distinct claims. Send the ones to check to POST /verify/{task_id}/select." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_not_a_claim.json b/tests/fixtures/parity/legacy/verify__status_not_a_claim.json new file mode 100644 index 0000000..e900727 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_not_a_claim.json @@ -0,0 +1,18 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "error": "Not a verifiable claim.", + "failure_reason": "not_a_claim", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input", + "hint": "The input is a greeting, not a statement that can be checked. Send one factual claim, or run the text through /extract to enumerate its claims." + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_not_a_claim_after_a_while.json b/tests/fixtures/parity/legacy/verify__status_not_a_claim_after_a_while.json new file mode 100644 index 0000000..cd385ae --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_not_a_claim_after_a_while.json @@ -0,0 +1,17 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "error": "Pipeline stopped: not_a_claim.", + "failure_reason": "not_a_claim", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_not_yours_404.json b/tests/fixtures/parity/legacy/verify__status_not_yours_404.json new file mode 100644 index 0000000..d005db5 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_not_yours_404.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "detail": "Task not found." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_older_run_completed.json b/tests/fixtures/parity/legacy/verify__status_older_run_completed.json new file mode 100644 index 0000000..2b34cd1 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_older_run_completed.json @@ -0,0 +1,99 @@ +{ + "status": 200, + "body": { + "status": "completed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_older_run_failed_crashed.json b/tests/fixtures/parity/legacy/verify__status_older_run_failed_crashed.json new file mode 100644 index 0000000..91a9dc7 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_older_run_failed_crashed.json @@ -0,0 +1,17 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "error": "Pipeline failed.", + "failure_reason": "task_error", + "failure_class": "internal", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#internal" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_older_run_failed_insufficient_evidence.json b/tests/fixtures/parity/legacy/verify__status_older_run_failed_insufficient_evidence.json new file mode 100644 index 0000000..77f7bff --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_older_run_failed_insufficient_evidence.json @@ -0,0 +1,17 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "error": "Pipeline stopped at: research_empty", + "failure_reason": "research_empty", + "failure_class": "insufficient_evidence", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_older_run_in_progress.json b/tests/fixtures/parity/legacy/verify__status_older_run_in_progress.json new file mode 100644 index 0000000..5e5d47b --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_older_run_in_progress.json @@ -0,0 +1,19 @@ +{ + "status": 200, + "body": { + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "progress": { + "step": "research", + "index": 2, + "total": 5, + "elapsed_seconds": 1, + "poll_after_seconds": 5 + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_processing.json b/tests/fixtures/parity/legacy/verify__status_processing.json new file mode 100644 index 0000000..5e5d47b --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_processing.json @@ -0,0 +1,19 @@ +{ + "status": 200, + "body": { + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "progress": { + "step": "research", + "index": 2, + "total": 5, + "elapsed_seconds": 1, + "poll_after_seconds": 5 + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_processing_after_a_while.json b/tests/fixtures/parity/legacy/verify__status_processing_after_a_while.json new file mode 100644 index 0000000..e0638f1 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_processing_after_a_while.json @@ -0,0 +1,19 @@ +{ + "status": 200, + "body": { + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "progress": { + "step": "adjudication", + "index": 4, + "total": 5, + "elapsed_seconds": 1, + "poll_after_seconds": 5 + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_task_stuck.json b/tests/fixtures/parity/legacy/verify__status_task_stuck.json new file mode 100644 index 0000000..383a365 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_task_stuck.json @@ -0,0 +1,17 @@ +{ + "status": 200, + "body": { + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "error": "The task was never completed and has been marked failed.", + "failure_reason": "task_stuck", + "failure_class": "upstream_unavailable", + "retryable": true, + "docs_url": "https://lenz.io/docs/errors#upstream-unavailable" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__status_unknown_404.json b/tests/fixtures/parity/legacy/verify__status_unknown_404.json new file mode 100644 index 0000000..d005db5 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__status_unknown_404.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "detail": "Task not found." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__submit_202.json b/tests/fixtures/parity/legacy/verify__submit_202.json new file mode 100644 index 0000000..1991e8a --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__submit_202.json @@ -0,0 +1,13 @@ +{ + "status": 202, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued", + "chain_id": "99a0a9ca89e1e72c" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__submit_202_options.json b/tests/fixtures/parity/legacy/verify__submit_202_options.json new file mode 100644 index 0000000..1991e8a --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__submit_202_options.json @@ -0,0 +1,13 @@ +{ + "status": 202, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued", + "chain_id": "99a0a9ca89e1e72c" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__submit_202_text_alias.json b/tests/fixtures/parity/legacy/verify__submit_202_text_alias.json new file mode 100644 index 0000000..1991e8a --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__submit_202_text_alias.json @@ -0,0 +1,13 @@ +{ + "status": 202, + "body": { + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "queued", + "chain_id": "99a0a9ca89e1e72c" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__unauthenticated_401.json b/tests/fixtures/parity/legacy/verify__unauthenticated_401.json new file mode 100644 index 0000000..54ec0b6 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__unauthenticated_401.json @@ -0,0 +1,11 @@ +{ + "status": 401, + "body": { + "detail": "Unauthorized" + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_200.json b/tests/fixtures/parity/legacy/verify__verification_200.json new file mode 100644 index 0000000..50599ee --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_200.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_200_covered.json b/tests/fixtures/parity/legacy/verify__verification_200_covered.json new file mode 100644 index 0000000..fa6aef7 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_200_covered.json @@ -0,0 +1,93 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "covered", + "reasons": [], + "certificate_id": "95b0f3dd008b46846b6dd6b15099e2b3", + "certificate_url": "https://lenz.io/certificate/95b0f3dd008b46846b6dd6b15099e2b3", + "as_of": "2026-03-10T12:01:30+00:00", + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_200_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/legacy/verify__verification_200_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..2376a58 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_200_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_200_modified_at_null.json b/tests/fixtures/parity/legacy/verify__verification_200_modified_at_null.json new file mode 100644 index 0000000..50599ee --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_200_modified_at_null.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_200_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/legacy/verify__verification_200_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..47e455c --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_200_modified_at_same_day_hours_apart.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T08:00:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_200_modified_at_set.json b/tests/fixtures/parity/legacy/verify__verification_200_modified_at_set.json new file mode 100644 index 0000000..2376a58 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_200_modified_at_set.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T23:55:00.123456+00:00", + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_200_result_json_conclusion_only.json b/tests/fixtures/parity/legacy/verify__verification_200_result_json_conclusion_only.json new file mode 100644 index 0000000..b5cdcd6 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_200_result_json_conclusion_only.json @@ -0,0 +1,56 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [], + "presumed_intent": "", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [], + "audit": { + "adjudication_summary": "", + "assessments": [], + "debate_pro": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "debate_con": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "panel_agreement": "split" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_200_result_json_empty.json b/tests/fixtures/parity/legacy/verify__verification_200_result_json_empty.json new file mode 100644 index 0000000..b5cdcd6 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_200_result_json_empty.json @@ -0,0 +1,56 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [], + "presumed_intent": "", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [], + "audit": { + "adjudication_summary": "", + "assessments": [], + "debate_pro": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "debate_con": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "panel_agreement": "split" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_200_result_json_old_shape_strings.json b/tests/fixtures/parity/legacy/verify__verification_200_result_json_old_shape_strings.json new file mode 100644 index 0000000..3250756 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_200_result_json_old_shape_strings.json @@ -0,0 +1,72 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [], + "presumed_intent": "", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "", + "title": "", + "url": "https://old.example/a", + "snippet": "Old row.", + "date": "" + } + ], + "audit": { + "adjudication_summary": "", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "", + "score": null, + "reasoning": "", + "warnings": [] + } + ], + "debate_pro": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "debate_con": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "panel_agreement": "split" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_404.json b/tests/fixtures/parity/legacy/verify__verification_404.json new file mode 100644 index 0000000..538732c --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_404.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "detail": "Not found." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_by_task_id_200.json b/tests/fixtures/parity/legacy/verify__verification_by_task_id_200.json new file mode 100644 index 0000000..50599ee --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_by_task_id_200.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_failed_409.json b/tests/fixtures/parity/legacy/verify__verification_failed_409.json new file mode 100644 index 0000000..fdb3f4f --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_failed_409.json @@ -0,0 +1,19 @@ +{ + "status": 409, + "body": { + "detail": "This check failed and has no result.", + "code": "verification_failed", + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "hint": "Resubmit to POST /verify if retryable is true. GET /verify/status/7cff18da2d979d6370e54a160be121ad has the full failure.", + "failure_reason": "research_empty", + "failure_class": "insufficient_evidence", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#insufficient-evidence" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_failed_409_not_a_claim_after_a_while.json b/tests/fixtures/parity/legacy/verify__verification_failed_409_not_a_claim_after_a_while.json new file mode 100644 index 0000000..41c53e8 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_failed_409_not_a_claim_after_a_while.json @@ -0,0 +1,19 @@ +{ + "status": 409, + "body": { + "detail": "This check failed and has no result.", + "code": "verification_failed", + "status": "failed", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "hint": "Resubmit to POST /verify if retryable is true. GET /verify/status/7cff18da2d979d6370e54a160be121ad has the full failure.", + "failure_reason": "not_a_claim", + "failure_class": "invalid_input", + "retryable": false, + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_not_ready_409.json b/tests/fixtures/parity/legacy/verify__verification_not_ready_409.json new file mode 100644 index 0000000..dae092f --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_not_ready_409.json @@ -0,0 +1,15 @@ +{ + "status": 409, + "body": { + "detail": "This check is still running.", + "code": "verification_not_ready", + "status": "processing", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "hint": "Poll GET /verify/status/7cff18da2d979d6370e54a160be121ad until it completes, then read its result." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_not_yours_404.json b/tests/fixtures/parity/legacy/verify__verification_not_yours_404.json new file mode 100644 index 0000000..538732c --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_not_yours_404.json @@ -0,0 +1,11 @@ +{ + "status": 404, + "body": { + "detail": "Not found." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_public_anonymous.json b/tests/fixtures/parity/legacy/verify__verification_public_anonymous.json new file mode 100644 index 0000000..2500a41 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_public_anonymous.json @@ -0,0 +1,83 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "public", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": null + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_public_of_another_user.json b/tests/fixtures/parity/legacy/verify__verification_public_of_another_user.json new file mode 100644 index 0000000..1bd991f --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_public_of_another_user.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "public", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical in shape.", + "executive_summary": "The claim is verified.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_unknown_task_404.json b/tests/fixtures/parity/legacy/verify__verification_unknown_task_404.json new file mode 100644 index 0000000..379c918 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_unknown_task_404.json @@ -0,0 +1,12 @@ +{ + "status": 404, + "body": { + "detail": "Not found.", + "hint": "Unknown id. If this is a task_id, poll GET /verify/status/dddddddddddddddddddddddddddddddd for its status." + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_zero_retention_expired_410.json b/tests/fixtures/parity/legacy/verify__verification_zero_retention_expired_410.json new file mode 100644 index 0000000..924d468 --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_zero_retention_expired_410.json @@ -0,0 +1,13 @@ +{ + "status": 410, + "body": { + "detail": "This verification is no longer available: its account removes verifications after a set period.", + "code": "purged", + "purged_at": "2026-10-01T09:07:00.123456+00:00" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__verification_zero_retention_served.json b/tests/fixtures/parity/legacy/verify__verification_zero_retention_served.json new file mode 100644 index 0000000..89895ad --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__verification_zero_retention_served.json @@ -0,0 +1,95 @@ +{ + "status": 200, + "body": { + "verification_id": "68ca4aaf", + "claim": "The Earth is round.", + "visibility": "private", + "depth": "standard", + "domain": "Science", + "entities": [ + { + "name": "Earth", + "qid": null + } + ], + "presumed_intent": "Verify a basic scientific fact", + "verdict": "True", + "confidence": "high", + "lenz_score": 9, + "key_finding": "The Earth is approximately spherical.", + "executive_summary": "The claim is well supported by evidence.", + "warnings": [ + "Relies on limited sources" + ], + "suggested_rewrite": null, + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "NASA", + "title": "The shape of the Earth", + "url": "https://nasa.example/shape", + "snippet": "Satellite imagery shows an oblate spheroid.", + "date": "2025-01-15" + }, + { + "source_name": "ESA", + "title": "Earth from space", + "url": "https://esa.example/earth", + "snippet": "Orbital measurements confirm the curvature.", + "date": "2025-01-16" + } + ], + "audit": { + "adjudication_summary": "Both reviewers agreed.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Claim Precision & Quantitative Accuracy", + "score": 9.0, + "reasoning": "Precision analysis reasoning.", + "warnings": [] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Sources", + "score": 9.0, + "reasoning": "Source audit reasoning.", + "warnings": [ + "weak source A" + ] + } + ], + "debate_pro": { + "role": "Advocate", + "argument": "Satellite imagery and geodesy agree.", + "rebuttal": "Flat-Earth objections do not hold." + }, + "debate_con": { + "role": "Skeptic", + "argument": "The Earth is not a perfect sphere.", + "rebuttal": "Oblate, but round for the claim." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "headers": { + "Content-Type": "application/json; charset=utf-8", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/verify__webhook_secret_missing_422.json b/tests/fixtures/parity/legacy/verify__webhook_secret_missing_422.json new file mode 100644 index 0000000..bae889d --- /dev/null +++ b/tests/fixtures/parity/legacy/verify__webhook_secret_missing_422.json @@ -0,0 +1,12 @@ +{ + "status": 422, + "body": { + "detail": "webhook_url was supplied but this API key has no HMAC secret. Generate one at https://lenz.io/api-credentials (Webhooks panel) before submitting webhook-delivered calls.", + "code": "webhook_secret_missing" + }, + "headers": { + "Content-Type": "application/json", + "Cache-Control": "no-store", + "Vary": "origin" + } +} diff --git a/tests/fixtures/parity/legacy/webhook__certificate_timestamped.json b/tests/fixtures/parity/legacy/webhook__certificate_timestamped.json new file mode 100644 index 0000000..eaeb5fb --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__certificate_timestamped.json @@ -0,0 +1,27 @@ +{ + "status": 200, + "body": { + "event": "certificate.timestamped", + "verification_id": "68ca4aaf", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "batch_id": null, + "status": "completed", + "result": null, + "needs_input": null, + "coverage": { + "status": "covered", + "reasons": [], + "certificate_id": "95b0f3dd008b46846b6dd6b15099e2b3", + "certificate_url": "https://lenz.io/certificate/95b0f3dd008b46846b6dd6b15099e2b3", + "as_of": "2026-09-03T10:00:00+00:00", + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + }, + "error": null, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__certificate_timestamped_review_child.json b/tests/fixtures/parity/legacy/webhook__certificate_timestamped_review_child.json new file mode 100644 index 0000000..6c67b46 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__certificate_timestamped_review_child.json @@ -0,0 +1,28 @@ +{ + "status": 200, + "body": { + "event": "certificate.timestamped", + "verification_id": "68ca4aaf", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "batch_id": null, + "status": "completed", + "result": null, + "needs_input": null, + "coverage": { + "status": "covered", + "reasons": [], + "certificate_id": "95b0f3dd008b46846b6dd6b15099e2b3", + "certificate_url": "https://lenz.io/certificate/95b0f3dd008b46846b6dd6b15099e2b3", + "as_of": "2026-09-03T10:00:00+00:00", + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + }, + "error": null, + "review_id": "d6b2bd72", + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__citecheck_completed.json b/tests/fixtures/parity/legacy/webhook__citecheck_completed.json new file mode 100644 index 0000000..b8a79a6 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__citecheck_completed.json @@ -0,0 +1,134 @@ +{ + "status": 200, + "body": { + "event": "citecheck.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "citecheck_id": "8eb49302", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "completed", + "citecheck": { + "citecheck_id": "8eb49302", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 2 + }, + "summary": { + "citations_found": 2, + "citations_selected": 2, + "citation_limit": 2, + "citation_limit_reached": false, + "citation_checks": { + "checked": 2, + "unchecked": 0, + "failed": 0 + }, + "citation_issues": 1 + }, + "credits": { + "charged": 2 + }, + "citations": [ + { + "index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "result": { + "finding": "contradicted", + "source": "support", + "is_issue": true + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.gov/report-2024", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.gov/report-2024", + "source_version": null, + "support": "contradicted", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + }, + { + "index": 1, + "reference": "https://example.org/statement", + "cited_url": "https://example.org/statement", + "doi": null, + "statement": "The agency said so in a statement.", + "quotes": [], + "position": null, + "result": { + "finding": "supported", + "source": "support", + "is_issue": false + }, + "check": { + "status": "completed", + "page_read": "full", + "page_title": "Page at https://example.org/statement", + "page_published_date": null, + "page_language": "en", + "source_url": "https://example.org/statement", + "source_version": null, + "support": "supported", + "snippet": "The source says so.", + "rationale": "The page states it.", + "quote": null, + "doi_registered": null, + "metadata": null, + "metadata_differences": [], + "registered": null, + "unchecked_reason": null, + "hint": null, + "failure": null, + "missing_quote": null + } + } + ], + "citation_issues": [ + { + "citation_index": 0, + "reference": "https://example.gov/report-2024", + "cited_url": "https://example.gov/report-2024", + "doi": null, + "statement": "Unemployment fell to 4.1% in 2024.", + "quotes": [], + "position": null, + "finding": "contradicted", + "source": "support", + "snippet": "The source says so.", + "rationale": "The page states it.", + "metadata_differences": [], + "missing_quote": null, + "page_title": "Page at https://example.gov/report-2024", + "failure": null + } + ], + "citation_failures": [], + "failure": null, + "more_citations": [] + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__citecheck_failed.json b/tests/fixtures/parity/legacy/webhook__citecheck_failed.json new file mode 100644 index 0000000..7738080 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__citecheck_failed.json @@ -0,0 +1,47 @@ +{ + "status": 200, + "body": { + "event": "citecheck.failed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "citecheck_id": "8eb49302", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "failed", + "citecheck": { + "citecheck_id": "8eb49302", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "poll_after_seconds": null, + "policy": { + "max_citations": 20 + }, + "summary": { + "citations_found": null, + "citations_selected": null, + "citation_limit": 20, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0 + }, + "credits": { + "charged": 0 + }, + "citations": [], + "citation_issues": [], + "citation_failures": [], + "failure": { + "failure_reason": "no_citations", + "failure_class": "invalid_input", + "retryable": false, + "hint": "The text has no citation to check: no link, DOI or numbered reference with one.", + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "more_citations": null + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__review_completed.json b/tests/fixtures/parity/legacy/webhook__review_completed.json new file mode 100644 index 0000000..ea72c1c --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__review_completed.json @@ -0,0 +1,156 @@ +{ + "status": 200, + "body": { + "event": "review.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "review_id": "d6b2bd72", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "completed", + "review": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "issues_found", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 1, + "completed": 1, + "failed": 0 + }, + "issues": 1, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 11 + }, + "poll_after_seconds": null, + "issues": [ + { + "claim_index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "verified_claim": null, + "verdict": "False", + "confidence": "high", + "source": "verification", + "verification_id": "68ca4aaf", + "verification_status": "completed", + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "rationale": null, + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "failure": null, + "suggested_edits": null + } + ], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "False", + "confidence": "high", + "source": "verification", + "is_issue": true + }, + "assessment": { + "status": "completed", + "verdict": "False", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [ + "verdict" + ], + "disposition": "planned" + }, + "verification": { + "status": "completed", + "content_status": "available", + "task_id": "0b92b443eb69b9c71434fdc64f2ca8be", + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "language": "en", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "verdict": "False", + "confidence": "high", + "lenz_score": 2, + "key_finding": "Finding for The Eiffel Tower is in Berlin.", + "executive_summary": "Summary for The Eiffel Tower is in Berlin.", + "suggested_rewrite": "Fixed: The Eiffel Tower is in Berlin.", + "warnings": [ + "w1" + ], + "created_at": "2026-10-01T09:14:00.123456+00:00", + "modified_at": null, + "verification_url": "https://lenz.io/api/v1/verifications/68ca4aaf", + "url": "https://lenz.io/c/the-earth-is-round-68ca4aaf", + "failure": null + }, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__review_completed_key_default_url.json b/tests/fixtures/parity/legacy/webhook__review_completed_key_default_url.json new file mode 100644 index 0000000..7c98f76 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__review_completed_key_default_url.json @@ -0,0 +1,105 @@ +{ + "status": 200, + "body": { + "event": "review.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "review_id": "d6b2bd72", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "completed", + "review": { + "review_id": "d6b2bd72", + "view": "full", + "status": "completed", + "outcome": "clean", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": 1, + "claim_limit": 20, + "claim_limit_reached": false, + "input_truncated": false, + "assessments": { + "completed": 1, + "failed": 0 + }, + "verifications": { + "planned": 0, + "completed": 0, + "failed": 0 + }, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 1 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [ + { + "index": 0, + "claim": "The Eiffel Tower is in Berlin.", + "positions": null, + "result": { + "verdict": "True", + "confidence": "high", + "source": "assessment", + "is_issue": false + }, + "assessment": { + "status": "completed", + "verdict": "True", + "confidence": "high", + "rationale": null, + "dissent": null, + "verification_url": null, + "error_code": null, + "identified_claims": [], + "hint": null, + "suggested_rewrite": null, + "failure": null + }, + "escalation": { + "matched_rules": [], + "disposition": "not_selected" + }, + "verification": null, + "suggested_edits": null + } + ], + "citations": [], + "failure": null, + "more_claims": [], + "more_claim_locations": [], + "more_citations": [] + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__review_completed_oversized_rebuilt.json b/tests/fixtures/parity/legacy/webhook__review_completed_oversized_rebuilt.json new file mode 100644 index 0000000..cd09384 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__review_completed_oversized_rebuilt.json @@ -0,0 +1,11 @@ +{ + "status": 200, + "body": { + "event": "review.completed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "review_id": "d6b2bd72", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "completed" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__review_failed.json b/tests/fixtures/parity/legacy/webhook__review_failed.json new file mode 100644 index 0000000..364b930 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__review_failed.json @@ -0,0 +1,73 @@ +{ + "status": 200, + "body": { + "event": "review.failed", + "event_id": "evt_09301870aba4e8f6ae33ff60", + "review_id": "d6b2bd72", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "status": "failed", + "review": { + "review_id": "d6b2bd72", + "view": "full", + "status": "failed", + "outcome": "unchecked", + "created_at": "2026-10-01T09:07:00.123456Z", + "completed_at": "2026-10-01T10:07:00.123456Z", + "language": "en", + "policy": { + "verdicts": [ + "False", + "Mostly False", + "Mixed" + ], + "confidence": [ + "low" + ], + "max_assessments": 20, + "max_verifications": 5, + "depth": "standard", + "max_citations": 0, + "suggest_edits": false + }, + "summary": { + "claims_selected": null, + "claim_limit": 20, + "claim_limit_reached": null, + "input_truncated": false, + "assessments": null, + "verifications": null, + "issues": 0, + "citations_found": null, + "citations_selected": null, + "citation_limit": null, + "citation_limit_reached": null, + "citation_checks": null, + "citation_issues": 0, + "citations_skipped": null + }, + "credits": { + "charged": 0 + }, + "poll_after_seconds": null, + "issues": [], + "failures": [], + "citation_issues": [], + "citation_failures": [], + "claims": [], + "citations": [], + "failure": { + "failure_reason": "no_claim", + "failure_class": "invalid_input", + "retryable": false, + "hint": "No factual statement that can be checked against evidence was found in the input. Send one factual claim, or run the text through /extract to enumerate its claims.", + "docs_url": "https://lenz.io/docs/errors#invalid-input" + }, + "more_claims": null, + "more_claim_locations": null, + "more_citations": null + }, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__test_fire.json b/tests/fixtures/parity/legacy/webhook__test_fire.json new file mode 100644 index 0000000..131b2f2 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__test_fire.json @@ -0,0 +1,17 @@ +{ + "status": 200, + "body": { + "attempt": 1, + "batch_id": null, + "coverage": null, + "delivered_at": "2026-10-01T11:07:00.123456+00:00", + "error": null, + "event": "webhook.test", + "needs_input": null, + "result": null, + "status": "test", + "task_id": "test_7cff18da2d979d63", + "verification_id": null + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__verification_completed.json b/tests/fixtures/parity/legacy/webhook__verification_completed.json new file mode 100644 index 0000000..04dae69 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__verification_completed.json @@ -0,0 +1,107 @@ +{ + "status": 200, + "body": { + "event": "verification.completed", + "verification_id": "68ca4aaf", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "batch_id": null, + "status": "completed", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "visibility": "private", + "depth": "standard", + "domain": "Geography", + "entities": [ + { + "name": "Eiffel Tower", + "qid": null + }, + { + "name": "Berlin", + "qid": null + } + ], + "presumed_intent": "Check where a landmark is.", + "verdict": "False", + "confidence": "high", + "lenz_score": 1, + "key_finding": "The Eiffel Tower is in Paris.", + "executive_summary": "The Eiffel Tower stands in Paris, France, not in Berlin.", + "warnings": [ + "Only two sources were found." + ], + "suggested_rewrite": "The Eiffel Tower is in Paris.", + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "Example Encyclopedia", + "title": "Eiffel Tower", + "url": "https://example.org/eiffel-tower", + "snippet": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.", + "date": "2025-01-15" + }, + { + "source_name": "Example Travel", + "title": "Visiting Paris", + "url": "https://example.com/visit-paris", + "snippet": "Most visitors climb the tower on their first day in Paris.", + "date": "" + } + ], + "audit": { + "adjudication_summary": "Both reviewers found it false.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Evidence", + "score": 1.0, + "reasoning": "Both sources place the tower in Paris.", + "warnings": [ + "Example Travel is a travel blog." + ] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Evidence", + "score": 2.0, + "reasoning": "The encyclopedia entry is unambiguous.", + "warnings": [] + } + ], + "debate_pro": { + "role": "pro", + "argument": "Some guides place it in Berlin.", + "rebuttal": "None of them are reliable." + }, + "debate_con": { + "role": "con", + "argument": "Every source places it in Paris.", + "rebuttal": "The pro case cites no source." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "needs_input": null, + "coverage": null, + "error": null, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__verification_completed_in_batch.json b/tests/fixtures/parity/legacy/webhook__verification_completed_in_batch.json new file mode 100644 index 0000000..efa7cc2 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__verification_completed_in_batch.json @@ -0,0 +1,107 @@ +{ + "status": 200, + "body": { + "event": "verification.completed", + "verification_id": "68ca4aaf", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "batch_id": "7ea9cdbd4064e3cf", + "status": "completed", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "visibility": "private", + "depth": "standard", + "domain": "Geography", + "entities": [ + { + "name": "Eiffel Tower", + "qid": null + }, + { + "name": "Berlin", + "qid": null + } + ], + "presumed_intent": "Check where a landmark is.", + "verdict": "False", + "confidence": "high", + "lenz_score": 1, + "key_finding": "The Eiffel Tower is in Paris.", + "executive_summary": "The Eiffel Tower stands in Paris, France, not in Berlin.", + "warnings": [ + "Only two sources were found." + ], + "suggested_rewrite": "The Eiffel Tower is in Paris.", + "created_at": "2026-10-01T09:07:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "Example Encyclopedia", + "title": "Eiffel Tower", + "url": "https://example.org/eiffel-tower", + "snippet": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.", + "date": "2025-01-15" + }, + { + "source_name": "Example Travel", + "title": "Visiting Paris", + "url": "https://example.com/visit-paris", + "snippet": "Most visitors climb the tower on their first day in Paris.", + "date": "" + } + ], + "audit": { + "adjudication_summary": "Both reviewers found it false.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Evidence", + "score": 1.0, + "reasoning": "Both sources place the tower in Paris.", + "warnings": [ + "Example Travel is a travel blog." + ] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Evidence", + "score": 2.0, + "reasoning": "The encyclopedia entry is unambiguous.", + "warnings": [] + } + ], + "debate_pro": { + "role": "pro", + "argument": "Some guides place it in Berlin.", + "rebuttal": "None of them are reliable." + }, + "debate_con": { + "role": "con", + "argument": "Every source places it in Paris.", + "rebuttal": "The pro case cites no source." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "needs_input": null, + "coverage": null, + "error": null, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__verification_completed_modified_at_crosses_midnight_by_minutes.json b/tests/fixtures/parity/legacy/webhook__verification_completed_modified_at_crosses_midnight_by_minutes.json new file mode 100644 index 0000000..558176e --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__verification_completed_modified_at_crosses_midnight_by_minutes.json @@ -0,0 +1,107 @@ +{ + "status": 200, + "body": { + "event": "verification.completed", + "verification_id": "68ca4aaf", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "batch_id": null, + "status": "completed", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "visibility": "private", + "depth": "standard", + "domain": "Geography", + "entities": [ + { + "name": "Eiffel Tower", + "qid": null + }, + { + "name": "Berlin", + "qid": null + } + ], + "presumed_intent": "Check where a landmark is.", + "verdict": "False", + "confidence": "high", + "lenz_score": 1, + "key_finding": "The Eiffel Tower is in Paris.", + "executive_summary": "The Eiffel Tower stands in Paris, France, not in Berlin.", + "warnings": [ + "Only two sources were found." + ], + "suggested_rewrite": "The Eiffel Tower is in Paris.", + "created_at": "2026-10-01T23:55:00.123456+00:00", + "modified_at": "2026-10-02T00:03:00.123456+00:00", + "sources": [ + { + "source_name": "Example Encyclopedia", + "title": "Eiffel Tower", + "url": "https://example.org/eiffel-tower", + "snippet": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.", + "date": "2025-01-15" + }, + { + "source_name": "Example Travel", + "title": "Visiting Paris", + "url": "https://example.com/visit-paris", + "snippet": "Most visitors climb the tower on their first day in Paris.", + "date": "" + } + ], + "audit": { + "adjudication_summary": "Both reviewers found it false.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Evidence", + "score": 1.0, + "reasoning": "Both sources place the tower in Paris.", + "warnings": [ + "Example Travel is a travel blog." + ] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Evidence", + "score": 2.0, + "reasoning": "The encyclopedia entry is unambiguous.", + "warnings": [] + } + ], + "debate_pro": { + "role": "pro", + "argument": "Some guides place it in Berlin.", + "rebuttal": "None of them are reliable." + }, + "debate_con": { + "role": "con", + "argument": "Every source places it in Paris.", + "rebuttal": "The pro case cites no source." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "needs_input": null, + "coverage": null, + "error": null, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__verification_completed_modified_at_same_day_hours_apart.json b/tests/fixtures/parity/legacy/webhook__verification_completed_modified_at_same_day_hours_apart.json new file mode 100644 index 0000000..dee4598 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__verification_completed_modified_at_same_day_hours_apart.json @@ -0,0 +1,107 @@ +{ + "status": 200, + "body": { + "event": "verification.completed", + "verification_id": "68ca4aaf", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "batch_id": null, + "status": "completed", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "visibility": "private", + "depth": "standard", + "domain": "Geography", + "entities": [ + { + "name": "Eiffel Tower", + "qid": null + }, + { + "name": "Berlin", + "qid": null + } + ], + "presumed_intent": "Check where a landmark is.", + "verdict": "False", + "confidence": "high", + "lenz_score": 1, + "key_finding": "The Eiffel Tower is in Paris.", + "executive_summary": "The Eiffel Tower stands in Paris, France, not in Berlin.", + "warnings": [ + "Only two sources were found." + ], + "suggested_rewrite": "The Eiffel Tower is in Paris.", + "created_at": "2026-10-01T08:00:00.123456+00:00", + "modified_at": null, + "sources": [ + { + "source_name": "Example Encyclopedia", + "title": "Eiffel Tower", + "url": "https://example.org/eiffel-tower", + "snippet": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France.", + "date": "2025-01-15" + }, + { + "source_name": "Example Travel", + "title": "Visiting Paris", + "url": "https://example.com/visit-paris", + "snippet": "Most visitors climb the tower on their first day in Paris.", + "date": "" + } + ], + "audit": { + "adjudication_summary": "Both reviewers found it false.", + "assessments": [ + { + "panelist_name": "Reviewer A", + "focus_area": "Evidence", + "score": 1.0, + "reasoning": "Both sources place the tower in Paris.", + "warnings": [ + "Example Travel is a travel blog." + ] + }, + { + "panelist_name": "Reviewer B", + "focus_area": "Evidence", + "score": 2.0, + "reasoning": "The encyclopedia entry is unambiguous.", + "warnings": [] + } + ], + "debate_pro": { + "role": "pro", + "argument": "Some guides place it in Berlin.", + "rebuttal": "None of them are reliable." + }, + "debate_con": { + "role": "con", + "argument": "Every source places it in Paris.", + "rebuttal": "The pro case cites no source." + }, + "panel_agreement": "unanimous" + }, + "language": "en", + "coverage": { + "status": "uncovered", + "reasons": [ + "plan" + ], + "certificate_id": null, + "certificate_url": null, + "as_of": null, + "currency": "EUR", + "cap": 10000, + "aggregate": 500000, + "terms_version": "v1" + } + }, + "needs_input": null, + "coverage": null, + "error": null, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__verification_completed_sparse_result.json b/tests/fixtures/parity/legacy/webhook__verification_completed_sparse_result.json new file mode 100644 index 0000000..643b479 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__verification_completed_sparse_result.json @@ -0,0 +1,52 @@ +{ + "status": 200, + "body": { + "event": "verification.completed", + "verification_id": "68ca4aaf", + "task_id": "7cff18da2d979d6370e54a160be121ad", + "batch_id": null, + "status": "completed", + "result": { + "verification_id": "68ca4aaf", + "claim": "The Eiffel Tower is in Berlin.", + "visibility": "private", + "depth": "standard", + "domain": "", + "entities": [], + "presumed_intent": "", + "verdict": "", + "confidence": "low", + "lenz_score": null, + "key_finding": "", + "executive_summary": "", + "warnings": [], + "suggested_rewrite": null, + "created_at": "", + "modified_at": null, + "sources": [], + "audit": { + "adjudication_summary": "", + "assessments": [], + "debate_pro": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "debate_con": { + "role": "", + "argument": "", + "rebuttal": "" + }, + "panel_agreement": "" + }, + "language": "en", + "coverage": null + }, + "needs_input": null, + "coverage": null, + "error": null, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__verification_failed_error_none.json b/tests/fixtures/parity/legacy/webhook__verification_failed_error_none.json new file mode 100644 index 0000000..6647535 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__verification_failed_error_none.json @@ -0,0 +1,19 @@ +{ + "status": 200, + "body": { + "event": "verification.failed", + "verification_id": null, + "task_id": "7cff18da2d979d6370e54a160be121ad", + "batch_id": null, + "status": "failed", + "result": null, + "needs_input": null, + "coverage": null, + "error": null, + "failure_class": "internal", + "retryable": false, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__verification_failed_insufficient_evidence.json b/tests/fixtures/parity/legacy/webhook__verification_failed_insufficient_evidence.json new file mode 100644 index 0000000..ecfcdbd --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__verification_failed_insufficient_evidence.json @@ -0,0 +1,19 @@ +{ + "status": 200, + "body": { + "event": "verification.failed", + "verification_id": null, + "task_id": "7cff18da2d979d6370e54a160be121ad", + "batch_id": null, + "status": "failed", + "result": null, + "needs_input": null, + "coverage": null, + "error": "research_insufficient", + "failure_class": "insufficient_evidence", + "retryable": false, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__verification_failed_not_a_claim.json b/tests/fixtures/parity/legacy/webhook__verification_failed_not_a_claim.json new file mode 100644 index 0000000..5dc356d --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__verification_failed_not_a_claim.json @@ -0,0 +1,19 @@ +{ + "status": 200, + "body": { + "event": "verification.failed", + "verification_id": null, + "task_id": "7cff18da2d979d6370e54a160be121ad", + "batch_id": null, + "status": "failed", + "result": null, + "needs_input": null, + "coverage": null, + "error": "not_a_claim", + "failure_class": "invalid_input", + "retryable": false, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__verification_failed_upstream_unavailable.json b/tests/fixtures/parity/legacy/webhook__verification_failed_upstream_unavailable.json new file mode 100644 index 0000000..867b62b --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__verification_failed_upstream_unavailable.json @@ -0,0 +1,19 @@ +{ + "status": 200, + "body": { + "event": "verification.failed", + "verification_id": null, + "task_id": "7cff18da2d979d6370e54a160be121ad", + "batch_id": null, + "status": "failed", + "result": null, + "needs_input": null, + "coverage": null, + "error": "framing_failed", + "failure_class": "upstream_unavailable", + "retryable": true, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__verification_needs_input_hint_none.json b/tests/fixtures/parity/legacy/webhook__verification_needs_input_hint_none.json new file mode 100644 index 0000000..0a349f3 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__verification_needs_input_hint_none.json @@ -0,0 +1,27 @@ +{ + "status": 200, + "body": { + "event": "verification.needs_input", + "verification_id": null, + "task_id": "7cff18da2d979d6370e54a160be121ad", + "batch_id": null, + "status": "needs_input", + "result": null, + "needs_input": { + "reason": "multi_claim", + "claims": [ + { + "text": "The Eiffel Tower is in Berlin.", + "domain": "" + } + ], + "hint": null + }, + "error": null, + "coverage": null, + "review_id": null, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/legacy/webhook__verification_needs_input_multi_claim.json b/tests/fixtures/parity/legacy/webhook__verification_needs_input_multi_claim.json new file mode 100644 index 0000000..9395c84 --- /dev/null +++ b/tests/fixtures/parity/legacy/webhook__verification_needs_input_multi_claim.json @@ -0,0 +1,30 @@ +{ + "status": 200, + "body": { + "event": "verification.needs_input", + "verification_id": null, + "task_id": "7cff18da2d979d6370e54a160be121ad", + "batch_id": null, + "status": "needs_input", + "result": null, + "needs_input": { + "reason": "multi_claim", + "claims": [ + { + "text": "The Earth is round.", + "domain": "" + }, + { + "text": "The Moon is made of cheese.", + "domain": "Science" + } + ], + "hint": "The text holds several distinct claims. Send the ones to check to POST /verify/{task_id}/select." + }, + "coverage": null, + "error": null, + "attempt": 1, + "delivered_at": "2026-10-01T11:07:00.123456+00:00" + }, + "headers": {} +} diff --git a/tests/fixtures/parity/pickles.json b/tests/fixtures/parity/pickles.json new file mode 100644 index 0000000..cf1551e --- /dev/null +++ b/tests/fixtures/parity/pickles.json @@ -0,0 +1,156 @@ +{ + "account__library_empty.json": "gASVuQAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwLTGlicmFyeUxpc3SUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwFaXRlbXOUXZSMBXRvdGFslEsAjARwYWdllEsBjAlwYWdlX3NpemWUSxR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgKaAtoCWgHkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnViLg==", + "account__library_item_modified_at_crosses_midnight_by_minutes.json": "gASVdwIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwLTGlicmFyeUxpc3SUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwFaXRlbXOUXZRoAIwLTGlicmFyeUl0ZW2Uk5QpgZR9lChoBX2UKIwPdmVyaWZpY2F0aW9uX2lklIwINjhjYTRhYWaUjAVjbGFpbZSMEEEgbGlicmFyeSBjbGFpbS6UjAZkb21haW6UjACUjAhlbnRpdGllc5RdlIwHdmVyZGljdJSMBFRydWWUjApjb25maWRlbmNllIwDbG93lIwKbGVuel9zY29yZZRLCowLa2V5X2ZpbmRpbmeUjC5UaGUgRWFydGggaXMgYXBwcm94aW1hdGVseSBzcGhlcmljYWwgaW4gc2hhcGUulIwRZXhlY3V0aXZlX3N1bW1hcnmUjBZUaGUgY2xhaW0gaXMgdmVyaWZpZWQulIwRc3VnZ2VzdGVkX3Jld3JpdGWUTowKY3JlYXRlZF9hdJSMIDIwMjYtMTAtMDFUMjM6NTU6MDAuMTIzNDU2KzAwOjAwlIwLbW9kaWZpZWRfYXSUjCAyMDI2LTEwLTAyVDAwOjAzOjAwLjEyMzQ1NiswMDowMJSMCGxhbmd1YWdllIwCZW6UdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoEGgOaBRoGGggaBJoFmgkaCJoHWgaaBtoH5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMBXRvdGFslEsBjARwYWdllEsBjAlwYWdlX3NpemWUSxR1aCZ9lGgoj5QoaCxoLWgraAeQaCpOdWIu", + "account__library_item_modified_at_same_day_hours_apart.json": "gASVVQIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwLTGlicmFyeUxpc3SUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwFaXRlbXOUXZRoAIwLTGlicmFyeUl0ZW2Uk5QpgZR9lChoBX2UKIwPdmVyaWZpY2F0aW9uX2lklIwINjhjYTRhYWaUjAVjbGFpbZSMEEEgbGlicmFyeSBjbGFpbS6UjAZkb21haW6UjACUjAhlbnRpdGllc5RdlIwHdmVyZGljdJSMBFRydWWUjApjb25maWRlbmNllIwDbG93lIwKbGVuel9zY29yZZRLCowLa2V5X2ZpbmRpbmeUjC5UaGUgRWFydGggaXMgYXBwcm94aW1hdGVseSBzcGhlcmljYWwgaW4gc2hhcGUulIwRZXhlY3V0aXZlX3N1bW1hcnmUjBZUaGUgY2xhaW0gaXMgdmVyaWZpZWQulIwRc3VnZ2VzdGVkX3Jld3JpdGWUTowKY3JlYXRlZF9hdJSMIDIwMjYtMTAtMDFUMDg6MDA6MDAuMTIzNDU2KzAwOjAwlIwLbW9kaWZpZWRfYXSUTowIbGFuZ3VhZ2WUjAJlbpR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgQaA5oFGgYaCBoEmgWaCNoImgdaBpoG2gfkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnViYYwFdG90YWyUSwGMBHBhZ2WUSwGMCXBhZ2Vfc2l6ZZRLFHVoJX2UaCePlChoK2gsaCpoB5BoKU51Yi4=", + "account__library_items.json": "gASVWQQAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwLTGlicmFyeUxpc3SUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwFaXRlbXOUXZQoaACMC0xpYnJhcnlJdGVtlJOUKYGUfZQoaAV9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBBMaWJyYXJ5IGNsYWltIDAulIwGZG9tYWlulIwHU2NpZW5jZZSMCGVudGl0aWVzlF2UjAd2ZXJkaWN0lIwEVHJ1ZZSMCmNvbmZpZGVuY2WUjANsb3eUjApsZW56X3Njb3JllEsKjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjBFzdWdnZXN0ZWRfcmV3cml0ZZROjApjcmVhdGVkX2F0lIwgMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTYrMDA6MDCUjAttb2RpZmllZF9hdJROjAhsYW5ndWFnZZSMAmVulHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBBoDmgUaBhoIGgSaBZoI2giaB1oGmgbaB+QjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWJoCimBlH2UKGgFfZQoaA6MCDRkNDRkZmFmlGgQjBBMaWJyYXJ5IGNsYWltIDEulGgSjAdTY2llbmNllGgUXZRoFowEVHJ1ZZRoGIwDbG93lGgaSwpoG4wuVGhlIEVhcnRoIGlzIGFwcHJveGltYXRlbHkgc3BoZXJpY2FsIGluIHNoYXBlLpRoHYwWVGhlIGNsYWltIGlzIHZlcmlmaWVkLpRoH05oIIwgMjAyNi0xMC0wMVQwOToxNDowMC4xMjM0NTYrMDA6MDCUaCJOaCOMAmVulHVoJX2UaCePlChoEGgOaBRoGGggaBJoFmgjaCJoHWgaaBtoH5BoKU51YmgKKYGUfZQoaAV9lChoDowIN2M4MzI0N2OUaBCMEExpYnJhcnkgY2xhaW0gMi6UaBKMB1NjaWVuY2WUaBRdlGgWjARUcnVllGgYjANsb3eUaBpLCmgbjC5UaGUgRWFydGggaXMgYXBwcm94aW1hdGVseSBzcGhlcmljYWwgaW4gc2hhcGUulGgdjBZUaGUgY2xhaW0gaXMgdmVyaWZpZWQulGgfTmggjCAyMDI2LTEwLTAxVDA5OjIxOjAwLjEyMzQ1NiswMDowMJRoIk5oI4wCZW6UdWglfZRoJ4+UKGgQaA5oFGgYaCBoEmgWaCNoImgdaBpoG2gfkGgpTnViZYwFdG90YWyUSwOMBHBhZ2WUSwGMCXBhZ2Vfc2l6ZZRLFHVoJX2UaCePlChoSWhKaEhoB5BoKU51Yi4=", + "account__library_no_match.json": "gASVuQAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwLTGlicmFyeUxpc3SUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwFaXRlbXOUXZSMBXRvdGFslEsAjARwYWdllEsBjAlwYWdlX3NpemWUSxR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgKaAtoCWgHkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnViLg==", + "account__library_page_past_end.json": "gASVuQAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwLTGlicmFyeUxpc3SUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwFaXRlbXOUXZSMBXRvdGFslEsBjARwYWdllEsCjAlwYWdlX3NpemWUSxR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgKaAtoCWgHkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnViLg==", + "account__library_paginated_second_page.json": "gASVTAMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwLTGlicmFyeUxpc3SUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwFaXRlbXOUXZQoaACMC0xpYnJhcnlJdGVtlJOUKYGUfZQoaAV9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBBQYWdlZCBjbGFpbSAwMjAulIwGZG9tYWlulIwAlIwIZW50aXRpZXOUXZSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMA2xvd5SMCmxlbnpfc2NvcmWUSwqMC2tleV9maW5kaW5nlIwuVGhlIEVhcnRoIGlzIGFwcHJveGltYXRlbHkgc3BoZXJpY2FsIGluIHNoYXBlLpSMEWV4ZWN1dGl2ZV9zdW1tYXJ5lIwWVGhlIGNsYWltIGlzIHZlcmlmaWVkLpSMEXN1Z2dlc3RlZF9yZXdyaXRllE6MCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoEGgOaBRoGGggaBJoFmgjaCJoHWgaaBtoH5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmgKKYGUfZQoaAV9lChoDowINGQ0NGRmYWaUaBCMEFBhZ2VkIGNsYWltIDAyMS6UaBJoE2gUXZRoFowEVHJ1ZZRoGIwDbG93lGgaSwpoG4wuVGhlIEVhcnRoIGlzIGFwcHJveGltYXRlbHkgc3BoZXJpY2FsIGluIHNoYXBlLpRoHYwWVGhlIGNsYWltIGlzIHZlcmlmaWVkLpRoH05oIIwgMjAyNi0xMC0wMVQwOToxNDowMC4xMjM0NTYrMDA6MDCUaCJOaCOMAmVulHVoJX2UaCePlChoEGgOaBRoGGggaBJoFmgjaCJoHWgaaBtoH5BoKU51YmWMBXRvdGFslEsWjARwYWdllEsCjAlwYWdlX3NpemWUSxR1aCV9lGgnj5QoaDloOmg4aAeQaClOdWIu", + "account__me_usage_extra_credits.json": "gASVoAMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwFVXNhZ2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwEcGxhbpSMBGZyZWWUjApwbGFuX2xhYmVslIwERnJlZZSMD3F1b3RhX3Jlc2V0c19hdJSMGTIwMjYtMTAtMDFUMTQ6MDc6MDArMDA6MDCUjAdjcmVkaXRzlGgAjAxVc2FnZUNyZWRpdHOUk5QpgZR9lChoBX2UKIwFdG90YWyUTV4BjAR1c2VklEsAjAlyZW1haW5pbmeUTV4BjAVleHRyYZRL+owFYm9udXOUS/qMCXJlc2V0c19hdJSMGTIwMjYtMTAtMDFUMTQ6MDc6MDArMDA6MDCUdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoFGgYaBNoFWgWaBeQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMBWNvc3RzlH2UKIwGdmVyaWZ5lEsKjAZhc3Nlc3OUSwGMA2Fza5RLAYwIY2l0YXRpb26USwGMB2V4dHJhY3SUSwB1jAxjb3N0X29wdGlvbnOUfZRoIX2UjAVkZXB0aJR9lCiMCHN0YW5kYXJklEsKjANsb3eUSwV1c3OMBnZlcmlmeZRoAIwNVXNhZ2VDYXBhY2l0eZSTlCmBlH2UKGgFfZQojApxdW90YV91c2VklEsAjAtxdW90YV90b3RhbJRLI4wPcXVvdGFfcmVtYWluaW5nlEsjaBdLGWgNSxloFUsjdWgafZRoHI+UKGgNaDNoNGgVaDVoF5BoHk51YowDYXNrlGgvKYGUfZQoaAV9lChoM0sAaDRNXgFoNU1eAWgXS/poDUv6aBVNXgF1aBp9lGgcj5QoaA1oM2g0aBVoNWgXkGgeTnVijAZhc3Nlc3OUaC8pgZR9lChoBX2UKGgzSwBoNE1eAWg1TV4BaBdL+mgNS/poFU1eAXVoGn2UaByPlChoDWgzaDRoFWg1aBeQaB5OdWKMB2V4dHJhY3SUaACMDFVzYWdlRXh0cmFjdJSTlCmBlH2UKGgFfZQojAtjYWxsc190b2RheZRLAIwLZGFpbHlfbGltaXSUTegDjAl1bmxpbWl0ZWSUiXVoGn2UaByPlChoS2hMaEqQaB5OdWKMEmhhc193ZWJob29rX3NlY3JldJSJdWgafZRoHI+UKGgtaDhoDWg+aAdoC2gmaE9oH2hEaAmQaB5OdWIu", + "account__me_usage_extra_only.json": "gASVmAMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwFVXNhZ2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwEcGxhbpSMBGZyZWWUjApwbGFuX2xhYmVslIwERnJlZZSMD3F1b3RhX3Jlc2V0c19hdJSMGTIwMjYtMTAtMDFUMTQ6MDc6MDArMDA6MDCUjAdjcmVkaXRzlGgAjAxVc2FnZUNyZWRpdHOUk5QpgZR9lChoBX2UKIwFdG90YWyUS4mMBHVzZWSUS2SMCXJlbWFpbmluZ5RLJYwFZXh0cmGUSyWMBWJvbnVzlEsljAlyZXNldHNfYXSUjBkyMDI2LTEwLTAxVDE0OjA3OjAwKzAwOjAwlHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBRoGGgTaBVoFmgXkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAVjb3N0c5R9lCiMBnZlcmlmeZRLCowGYXNzZXNzlEsBjANhc2uUSwGMCGNpdGF0aW9ulEsBjAdleHRyYWN0lEsAdYwMY29zdF9vcHRpb25zlH2UaCF9lIwFZGVwdGiUfZQojAhzdGFuZGFyZJRLCowDbG93lEsFdXNzjAZ2ZXJpZnmUaACMDVVzYWdlQ2FwYWNpdHmUk5QpgZR9lChoBX2UKIwKcXVvdGFfdXNlZJRLCowLcXVvdGFfdG90YWyUSw2MD3F1b3RhX3JlbWFpbmluZ5RLA2gXSwNoDUsDaBVLA3VoGn2UaByPlChoDWgzaDRoFWg1aBeQaB5OdWKMA2Fza5RoLymBlH2UKGgFfZQoaDNLZGg0S4loNUslaBdLJWgNSyVoFUsldWgafZRoHI+UKGgNaDNoNGgVaDVoF5BoHk51YowGYXNzZXNzlGgvKYGUfZQoaAV9lChoM0tkaDRLiWg1SyVoF0slaA1LJWgVSyV1aBp9lGgcj5QoaA1oM2g0aBVoNWgXkGgeTnVijAdleHRyYWN0lGgAjAxVc2FnZUV4dHJhY3SUk5QpgZR9lChoBX2UKIwLY2FsbHNfdG9kYXmUSwCMC2RhaWx5X2xpbWl0lE3oA4wJdW5saW1pdGVklIl1aBp9lGgcj5QoaEtoTGhKkGgeTnVijBJoYXNfd2ViaG9va19zZWNyZXSUiXVoGn2UaByPlChoLWg4aA1oPmgHaAtoJmhPaB9oRGgJkGgeTnViLg==", + "account__me_usage_extract_calls.json": "gASVmAMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwFVXNhZ2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwEcGxhbpSMBGZyZWWUjApwbGFuX2xhYmVslIwERnJlZZSMD3F1b3RhX3Jlc2V0c19hdJSMGTIwMjYtMTAtMDFUMTQ6MDc6MDArMDA6MDCUjAdjcmVkaXRzlGgAjAxVc2FnZUNyZWRpdHOUk5QpgZR9lChoBX2UKIwFdG90YWyUS2SMBHVzZWSUSwCMCXJlbWFpbmluZ5RLZIwFZXh0cmGUSwCMBWJvbnVzlEsAjAlyZXNldHNfYXSUjBkyMDI2LTEwLTAxVDE0OjA3OjAwKzAwOjAwlHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBRoGGgTaBVoFmgXkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAVjb3N0c5R9lCiMBnZlcmlmeZRLCowGYXNzZXNzlEsBjANhc2uUSwGMCGNpdGF0aW9ulEsBjAdleHRyYWN0lEsAdYwMY29zdF9vcHRpb25zlH2UaCF9lIwFZGVwdGiUfZQojAhzdGFuZGFyZJRLCowDbG93lEsFdXNzjAZ2ZXJpZnmUaACMDVVzYWdlQ2FwYWNpdHmUk5QpgZR9lChoBX2UKIwKcXVvdGFfdXNlZJRLAIwLcXVvdGFfdG90YWyUSwqMD3F1b3RhX3JlbWFpbmluZ5RLCmgXSwBoDUsAaBVLCnVoGn2UaByPlChoDWgzaDRoFWg1aBeQaB5OdWKMA2Fza5RoLymBlH2UKGgFfZQoaDNLAGg0S2RoNUtkaBdLAGgNSwBoFUtkdWgafZRoHI+UKGgNaDNoNGgVaDVoF5BoHk51YowGYXNzZXNzlGgvKYGUfZQoaAV9lChoM0sAaDRLZGg1S2RoF0sAaA1LAGgVS2R1aBp9lGgcj5QoaA1oM2g0aBVoNWgXkGgeTnVijAdleHRyYWN0lGgAjAxVc2FnZUV4dHJhY3SUk5QpgZR9lChoBX2UKIwLY2FsbHNfdG9kYXmUSweMC2RhaWx5X2xpbWl0lE3oA4wJdW5saW1pdGVklIl1aBp9lGgcj5QoaEtoTGhKkGgeTnVijBJoYXNfd2ViaG9va19zZWNyZXSUiXVoGn2UaByPlChoLWg4aA1oPmgHaAtoJmhPaB9oRGgJkGgeTnViLg==", + "account__me_usage_free.json": "gASVmAMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwFVXNhZ2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwEcGxhbpSMBGZyZWWUjApwbGFuX2xhYmVslIwERnJlZZSMD3F1b3RhX3Jlc2V0c19hdJSMGTIwMjYtMTAtMDFUMTQ6MDc6MDArMDA6MDCUjAdjcmVkaXRzlGgAjAxVc2FnZUNyZWRpdHOUk5QpgZR9lChoBX2UKIwFdG90YWyUS2SMBHVzZWSUSwCMCXJlbWFpbmluZ5RLZIwFZXh0cmGUSwCMBWJvbnVzlEsAjAlyZXNldHNfYXSUjBkyMDI2LTEwLTAxVDE0OjA3OjAwKzAwOjAwlHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBRoGGgTaBVoFmgXkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAVjb3N0c5R9lCiMBnZlcmlmeZRLCowGYXNzZXNzlEsBjANhc2uUSwGMCGNpdGF0aW9ulEsBjAdleHRyYWN0lEsAdYwMY29zdF9vcHRpb25zlH2UaCF9lIwFZGVwdGiUfZQojAhzdGFuZGFyZJRLCowDbG93lEsFdXNzjAZ2ZXJpZnmUaACMDVVzYWdlQ2FwYWNpdHmUk5QpgZR9lChoBX2UKIwKcXVvdGFfdXNlZJRLAIwLcXVvdGFfdG90YWyUSwqMD3F1b3RhX3JlbWFpbmluZ5RLCmgXSwBoDUsAaBVLCnVoGn2UaByPlChoDWgzaDRoFWg1aBeQaB5OdWKMA2Fza5RoLymBlH2UKGgFfZQoaDNLAGg0S2RoNUtkaBdLAGgNSwBoFUtkdWgafZRoHI+UKGgNaDNoNGgVaDVoF5BoHk51YowGYXNzZXNzlGgvKYGUfZQoaAV9lChoM0sAaDRLZGg1S2RoF0sAaA1LAGgVS2R1aBp9lGgcj5QoaA1oM2g0aBVoNWgXkGgeTnVijAdleHRyYWN0lGgAjAxVc2FnZUV4dHJhY3SUk5QpgZR9lChoBX2UKIwLY2FsbHNfdG9kYXmUSwCMC2RhaWx5X2xpbWl0lE3oA4wJdW5saW1pdGVklIl1aBp9lGgcj5QoaEtoTGhKkGgeTnVijBJoYXNfd2ViaG9va19zZWNyZXSUiXVoGn2UaByPlChoLWg4aA1oPmgHaAtoJmhPaB9oRGgJkGgeTnViLg==", + "account__me_usage_free_partly_spent.json": "gASVmAMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwFVXNhZ2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwEcGxhbpSMBGZyZWWUjApwbGFuX2xhYmVslIwERnJlZZSMD3F1b3RhX3Jlc2V0c19hdJSMGTIwMjYtMTAtMDFUMTQ6MDc6MDArMDA6MDCUjAdjcmVkaXRzlGgAjAxVc2FnZUNyZWRpdHOUk5QpgZR9lChoBX2UKIwFdG90YWyUS2SMBHVzZWSUSxGMCXJlbWFpbmluZ5RLU4wFZXh0cmGUSwCMBWJvbnVzlEsAjAlyZXNldHNfYXSUjBkyMDI2LTEwLTAxVDE0OjA3OjAwKzAwOjAwlHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBRoGGgTaBVoFmgXkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAVjb3N0c5R9lCiMBnZlcmlmeZRLCowGYXNzZXNzlEsBjANhc2uUSwGMCGNpdGF0aW9ulEsBjAdleHRyYWN0lEsAdYwMY29zdF9vcHRpb25zlH2UaCF9lIwFZGVwdGiUfZQojAhzdGFuZGFyZJRLCowDbG93lEsFdXNzjAZ2ZXJpZnmUaACMDVVzYWdlQ2FwYWNpdHmUk5QpgZR9lChoBX2UKIwKcXVvdGFfdXNlZJRLAowLcXVvdGFfdG90YWyUSwqMD3F1b3RhX3JlbWFpbmluZ5RLCGgXSwBoDUsAaBVLCHVoGn2UaByPlChoDWgzaDRoFWg1aBeQaB5OdWKMA2Fza5RoLymBlH2UKGgFfZQoaDNLEWg0S2RoNUtTaBdLAGgNSwBoFUtTdWgafZRoHI+UKGgNaDNoNGgVaDVoF5BoHk51YowGYXNzZXNzlGgvKYGUfZQoaAV9lChoM0sRaDRLZGg1S1NoF0sAaA1LAGgVS1N1aBp9lGgcj5QoaA1oM2g0aBVoNWgXkGgeTnVijAdleHRyYWN0lGgAjAxVc2FnZUV4dHJhY3SUk5QpgZR9lChoBX2UKIwLY2FsbHNfdG9kYXmUSwCMC2RhaWx5X2xpbWl0lE3oA4wJdW5saW1pdGVklIl1aBp9lGgcj5QoaEtoTGhKkGgeTnVijBJoYXNfd2ViaG9va19zZWNyZXSUiXVoGn2UaByPlChoLWg4aA1oPmgHaAtoJmhPaB9oRGgJkGgeTnViLg==", + "account__me_usage_oauth.json": "gASVmAMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwFVXNhZ2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwEcGxhbpSMBGZyZWWUjApwbGFuX2xhYmVslIwERnJlZZSMD3F1b3RhX3Jlc2V0c19hdJSMGTIwMjYtMTAtMDFUMTQ6MDc6MDArMDA6MDCUjAdjcmVkaXRzlGgAjAxVc2FnZUNyZWRpdHOUk5QpgZR9lChoBX2UKIwFdG90YWyUS2SMBHVzZWSUSwCMCXJlbWFpbmluZ5RLZIwFZXh0cmGUSwCMBWJvbnVzlEsAjAlyZXNldHNfYXSUjBkyMDI2LTEwLTAxVDE0OjA3OjAwKzAwOjAwlHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBRoGGgTaBVoFmgXkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAVjb3N0c5R9lCiMBnZlcmlmeZRLCowGYXNzZXNzlEsBjANhc2uUSwGMCGNpdGF0aW9ulEsBjAdleHRyYWN0lEsAdYwMY29zdF9vcHRpb25zlH2UaCF9lIwFZGVwdGiUfZQojAhzdGFuZGFyZJRLCowDbG93lEsFdXNzjAZ2ZXJpZnmUaACMDVVzYWdlQ2FwYWNpdHmUk5QpgZR9lChoBX2UKIwKcXVvdGFfdXNlZJRLAIwLcXVvdGFfdG90YWyUSwqMD3F1b3RhX3JlbWFpbmluZ5RLCmgXSwBoDUsAaBVLCnVoGn2UaByPlChoDWgzaDRoFWg1aBeQaB5OdWKMA2Fza5RoLymBlH2UKGgFfZQoaDNLAGg0S2RoNUtkaBdLAGgNSwBoFUtkdWgafZRoHI+UKGgNaDNoNGgVaDVoF5BoHk51YowGYXNzZXNzlGgvKYGUfZQoaAV9lChoM0sAaDRLZGg1S2RoF0sAaA1LAGgVS2R1aBp9lGgcj5QoaA1oM2g0aBVoNWgXkGgeTnVijAdleHRyYWN0lGgAjAxVc2FnZUV4dHJhY3SUk5QpgZR9lChoBX2UKIwLY2FsbHNfdG9kYXmUSwCMC2RhaWx5X2xpbWl0lE3oA4wJdW5saW1pdGVklIl1aBp9lGgcj5QoaEtoTGhKkGgeTnVijBJoYXNfd2ViaG9va19zZWNyZXSUiXVoGn2UaByPlChoLWg4aA1oPmgHaAtoJmhPaB9oRGgJkGgeTnViLg==", + "account__me_usage_plus.json": "gASVrgMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwFVXNhZ2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwEcGxhbpSMBHBsdXOUjApwbGFuX2xhYmVslIwEUGx1c5SMD3F1b3RhX3Jlc2V0c19hdJSMIDIwMjYtMTAtMDFUMTQ6MDc6MDAuMTIzNDU2KzAwOjAwlIwHY3JlZGl0c5RoAIwMVXNhZ2VDcmVkaXRzlJOUKYGUfZQoaAV9lCiMBXRvdGFslE30AYwEdXNlZJRLAIwJcmVtYWluaW5nlE30AYwFZXh0cmGUSwCMBWJvbnVzlEsAjAlyZXNldHNfYXSUjCAyMDI2LTEwLTAxVDE0OjA3OjAwLjEyMzQ1NiswMDowMJR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgUaBhoE2gVaBZoF5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowFY29zdHOUfZQojAZ2ZXJpZnmUSwqMBmFzc2Vzc5RLAYwDYXNrlEsBjAhjaXRhdGlvbpRLAYwHZXh0cmFjdJRLAHWMDGNvc3Rfb3B0aW9uc5R9lGghfZSMBWRlcHRolH2UKIwIc3RhbmRhcmSUSwqMA2xvd5RLBXVzc4wGdmVyaWZ5lGgAjA1Vc2FnZUNhcGFjaXR5lJOUKYGUfZQoaAV9lCiMCnF1b3RhX3VzZWSUSwCMC3F1b3RhX3RvdGFslEsyjA9xdW90YV9yZW1haW5pbmeUSzJoF0sAaA1LAGgVSzJ1aBp9lGgcj5QoaA1oM2g0aBVoNWgXkGgeTnVijANhc2uUaC8pgZR9lChoBX2UKGgzSwBoNE30AWg1TfQBaBdLAGgNSwBoFU30AXVoGn2UaByPlChoDWgzaDRoFWg1aBeQaB5OdWKMBmFzc2Vzc5RoLymBlH2UKGgFfZQoaDNLAGg0TfQBaDVN9AFoF0sAaA1LAGgVTfQBdWgafZRoHI+UKGgNaDNoNGgVaDVoF5BoHk51YowHZXh0cmFjdJRoAIwMVXNhZ2VFeHRyYWN0lJOUKYGUfZQoaAV9lCiMC2NhbGxzX3RvZGF5lEsAjAtkYWlseV9saW1pdJRN6AOMCXVubGltaXRlZJSJdWgafZRoHI+UKGhLaExoSpBoHk51YowSaGFzX3dlYmhvb2tfc2VjcmV0lIl1aBp9lGgcj5QoaC1oOGgNaD5oB2gLaCZoT2gfaERoCZBoHk51Yi4=", + "account__me_usage_pro.json": "gASVrwMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwFVXNhZ2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwEcGxhbpSMA3Byb5SMCnBsYW5fbGFiZWyUjANQcm+UjA9xdW90YV9yZXNldHNfYXSUjCAyMDI2LTEwLTAxVDE0OjA3OjAwLjEyMzQ1NiswMDowMJSMB2NyZWRpdHOUaACMDFVzYWdlQ3JlZGl0c5STlCmBlH2UKGgFfZQojAV0b3RhbJRNiBOMBHVzZWSUSwCMCXJlbWFpbmluZ5RNiBOMBWV4dHJhlEsAjAVib251c5RLAIwJcmVzZXRzX2F0lIwgMjAyNi0xMC0wMVQxNDowNzowMC4xMjM0NTYrMDA6MDCUdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoFGgYaBNoFWgWaBeQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMBWNvc3RzlH2UKIwGdmVyaWZ5lEsKjAZhc3Nlc3OUSwGMA2Fza5RLAYwIY2l0YXRpb26USwGMB2V4dHJhY3SUSwB1jAxjb3N0X29wdGlvbnOUfZRoIX2UjAVkZXB0aJR9lCiMCHN0YW5kYXJklEsKjANsb3eUSwV1c3OMBnZlcmlmeZRoAIwNVXNhZ2VDYXBhY2l0eZSTlCmBlH2UKGgFfZQojApxdW90YV91c2VklEsAjAtxdW90YV90b3RhbJRN9AGMD3F1b3RhX3JlbWFpbmluZ5RN9AFoF0sAaA1LAGgVTfQBdWgafZRoHI+UKGgNaDNoNGgVaDVoF5BoHk51YowDYXNrlGgvKYGUfZQoaAV9lChoM0sAaDRNiBNoNU2IE2gXSwBoDUsAaBVNiBN1aBp9lGgcj5QoaA1oM2g0aBVoNWgXkGgeTnVijAZhc3Nlc3OUaC8pgZR9lChoBX2UKGgzSwBoNE2IE2g1TYgTaBdLAGgNSwBoFU2IE3VoGn2UaByPlChoDWgzaDRoFWg1aBeQaB5OdWKMB2V4dHJhY3SUaACMDFVzYWdlRXh0cmFjdJSTlCmBlH2UKGgFfZQojAtjYWxsc190b2RheZRLAIwLZGFpbHlfbGltaXSUTegDjAl1bmxpbWl0ZWSUiXVoGn2UaByPlChoS2hMaEqQaB5OdWKMEmhhc193ZWJob29rX3NlY3JldJSJdWgafZRoHI+UKGgtaDhoDWg+aAdoC2gmaE9oH2hEaAmQaB5OdWIu", + "account__me_usage_pro_extra.json": "gASVtQMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwFVXNhZ2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwEcGxhbpSMA3Byb5SMCnBsYW5fbGFiZWyUjANQcm+UjA9xdW90YV9yZXNldHNfYXSUjCAyMDI2LTEwLTAxVDE0OjA3OjAwLjEyMzQ1NiswMDowMJSMB2NyZWRpdHOUaACMDFVzYWdlQ3JlZGl0c5STlCmBlH2UKGgFfZQojAV0b3RhbJRNcBeMBHVzZWSUSwCMCXJlbWFpbmluZ5RNcBeMBWV4dHJhlE3oA4wFYm9udXOUTegDjAlyZXNldHNfYXSUjCAyMDI2LTEwLTAxVDE0OjA3OjAwLjEyMzQ1NiswMDowMJR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgUaBhoE2gVaBZoF5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowFY29zdHOUfZQojAZ2ZXJpZnmUSwqMBmFzc2Vzc5RLAYwDYXNrlEsBjAhjaXRhdGlvbpRLAYwHZXh0cmFjdJRLAHWMDGNvc3Rfb3B0aW9uc5R9lGghfZSMBWRlcHRolH2UKIwIc3RhbmRhcmSUSwqMA2xvd5RLBXVzc4wGdmVyaWZ5lGgAjA1Vc2FnZUNhcGFjaXR5lJOUKYGUfZQoaAV9lCiMCnF1b3RhX3VzZWSUSwCMC3F1b3RhX3RvdGFslE1YAowPcXVvdGFfcmVtYWluaW5nlE1YAmgXS2RoDUtkaBVNWAJ1aBp9lGgcj5QoaA1oM2g0aBVoNWgXkGgeTnVijANhc2uUaC8pgZR9lChoBX2UKGgzSwBoNE1wF2g1TXAXaBdN6ANoDU3oA2gVTXAXdWgafZRoHI+UKGgNaDNoNGgVaDVoF5BoHk51YowGYXNzZXNzlGgvKYGUfZQoaAV9lChoM0sAaDRNcBdoNU1wF2gXTegDaA1N6ANoFU1wF3VoGn2UaByPlChoDWgzaDRoFWg1aBeQaB5OdWKMB2V4dHJhY3SUaACMDFVzYWdlRXh0cmFjdJSTlCmBlH2UKGgFfZQojAtjYWxsc190b2RheZRLAIwLZGFpbHlfbGltaXSUTegDjAl1bmxpbWl0ZWSUiXVoGn2UaByPlChoS2hMaEqQaB5OdWKMEmhhc193ZWJob29rX3NlY3JldJSJdWgafZRoHI+UKGgtaDhoDWg+aAdoC2gmaE9oH2hEaAmQaB5OdWIu", + "account__me_usage_stale_quota_row.json": "gASVmAMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwFVXNhZ2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwEcGxhbpSMBGZyZWWUjApwbGFuX2xhYmVslIwERnJlZZSMD3F1b3RhX3Jlc2V0c19hdJSMGTIwMjYtMTAtMDFUMTQ6MDc6MDArMDA6MDCUjAdjcmVkaXRzlGgAjAxVc2FnZUNyZWRpdHOUk5QpgZR9lChoBX2UKIwFdG90YWyUS2SMBHVzZWSUSwCMCXJlbWFpbmluZ5RLZIwFZXh0cmGUSwCMBWJvbnVzlEsAjAlyZXNldHNfYXSUjBkyMDI2LTEwLTAxVDE0OjA3OjAwKzAwOjAwlHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBRoGGgTaBVoFmgXkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAVjb3N0c5R9lCiMBnZlcmlmeZRLCowGYXNzZXNzlEsBjANhc2uUSwGMCGNpdGF0aW9ulEsBjAdleHRyYWN0lEsAdYwMY29zdF9vcHRpb25zlH2UaCF9lIwFZGVwdGiUfZQojAhzdGFuZGFyZJRLCowDbG93lEsFdXNzjAZ2ZXJpZnmUaACMDVVzYWdlQ2FwYWNpdHmUk5QpgZR9lChoBX2UKIwKcXVvdGFfdXNlZJRLAIwLcXVvdGFfdG90YWyUSwqMD3F1b3RhX3JlbWFpbmluZ5RLCmgXSwBoDUsAaBVLCnVoGn2UaByPlChoDWgzaDRoFWg1aBeQaB5OdWKMA2Fza5RoLymBlH2UKGgFfZQoaDNLAGg0S2RoNUtkaBdLAGgNSwBoFUtkdWgafZRoHI+UKGgNaDNoNGgVaDVoF5BoHk51YowGYXNzZXNzlGgvKYGUfZQoaAV9lChoM0sAaDRLZGg1S2RoF0sAaA1LAGgVS2R1aBp9lGgcj5QoaA1oM2g0aBVoNWgXkGgeTnVijAdleHRyYWN0lGgAjAxVc2FnZUV4dHJhY3SUk5QpgZR9lChoBX2UKIwLY2FsbHNfdG9kYXmUSwCMC2RhaWx5X2xpbWl0lE3oA4wJdW5saW1pdGVklIl1aBp9lGgcj5QoaEtoTGhKkGgeTnVijBJoYXNfd2ViaG9va19zZWNyZXSUiXVoGn2UaByPlChoLWg4aA1oPmgHaAtoJmhPaB9oRGgJkGgeTnViLg==", + "assess__deep_tier_hit.json": "gASVHwIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwOQXNzZXNzUmVzcG9uc2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwGY2xhaW1zlF2UaACMC0Fzc2Vzc0NsYWltlJOUKYGUfZQoaAV9lCiMBWNsYWltlIwUV2F0ZXIgYm9pbHMgYXQgMTAwQy6UjAhsYW5ndWFnZZSMAmVulIwHdmVyZGljdJSMBFRydWWUjApjb25maWRlbmNllIwEaGlnaJSMEHZlcmlmaWNhdGlvbl91cmyUjC1odHRwczovL2xlbnouaW8vYXBpL3YxL3ZlcmlmaWNhdGlvbnMvZjM0MzZmNTCUjAlyYXRpb25hbGWUjBZUaGUgY2xhaW0gaXMgdmVyaWZpZWQulIwHZGlzc2VudJROjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAplcnJvcl9jb2RllE6MEGNhbmRpZGF0ZV9jbGFpbXOUXZSMEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE51jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgOaCFoGmgdaBZoEGgUaB9oEmgYaBxoG5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMBWVycm9ylE5oHIwAlGgdXZSMC21vcmVfY2xhaW1zlF2UdWgifZRoJI+UKGgHaCpoJ5BoJk51Yi4=", + "assess__idempotency_first.json": "gASV3QEAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwOQXNzZXNzUmVzcG9uc2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwGY2xhaW1zlF2UaACMC0Fzc2Vzc0NsYWltlJOUKYGUfZQoaAV9lCiMBWNsYWltlIwZVGhlIEVhcnRoIG9yYml0cyB0aGUgU3VuLpSMCGxhbmd1YWdllIwCZW6UjAd2ZXJkaWN0lIwEVHJ1ZZSMCmNvbmZpZGVuY2WUjARoaWdolIwQdmVyaWZpY2F0aW9uX3VybJROjAlyYXRpb25hbGWUTowHZGlzc2VudJROjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAplcnJvcl9jb2RllE6MEGNhbmRpZGF0ZV9jbGFpbXOUXZSMEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE51jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgOaB9oGGgbaBZoEGgUaB1oEmgXaBpoGZCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMBWVycm9ylE5oGowAlGgbXZSMC21vcmVfY2xhaW1zlF2UdWggfZRoIo+UKGgHaChoJZBoJE51Yi4=", + "assess__idempotency_replay.json": "gASV3QEAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwOQXNzZXNzUmVzcG9uc2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwGY2xhaW1zlF2UaACMC0Fzc2Vzc0NsYWltlJOUKYGUfZQoaAV9lCiMBWNsYWltlIwZVGhlIEVhcnRoIG9yYml0cyB0aGUgU3VuLpSMCGxhbmd1YWdllIwCZW6UjAd2ZXJkaWN0lIwEVHJ1ZZSMCmNvbmZpZGVuY2WUjARoaWdolIwQdmVyaWZpY2F0aW9uX3VybJROjAlyYXRpb25hbGWUTowHZGlzc2VudJROjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAplcnJvcl9jb2RllE6MEGNhbmRpZGF0ZV9jbGFpbXOUXZSMEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE51jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgOaB9oGGgbaBZoEGgUaB1oEmgXaBpoGZCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMBWVycm9ylE5oGowAlGgbXZSMC21vcmVfY2xhaW1zlF2UdWggfZRoIo+UKGgHaChoJZBoJE51Yi4=", + "assess__list_all_error_rows.json": "gASVJQMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwOQXNzZXNzUmVzcG9uc2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwGY2xhaW1zlF2UKGgAjAtBc3Nlc3NDbGFpbZSTlCmBlH2UKGgFfZQojAVjbGFpbZSMAmhplIwIbGFuZ3VhZ2WUjAJlbpSMB3ZlcmRpY3SUjAVFcnJvcpSMCmNvbmZpZGVuY2WUjANsb3eUjBB2ZXJpZmljYXRpb25fdXJslE6MCXJhdGlvbmFsZZROjAdkaXNzZW50lE6MEXN1Z2dlc3RlZF9yZXdyaXRllE6MCmVycm9yX2NvZGWUjAhub19jbGFpbZSMEGNhbmRpZGF0ZV9jbGFpbXOUXZSMEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lIxqVGhlIGlucHV0IGlzIGEgZ3JlZXRpbmcuIFNlbmQgb25lIGZhY3R1YWwgY2xhaW0sIG9yIHJ1biB0aGUgdGV4dCB0aHJvdWdoIC9leHRyYWN0IHRvIGVudW1lcmF0ZSBpdHMgY2xhaW1zLpR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgOaCBoGGgcaBZoEGgUaB5oEmgXaBpoGZCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmgKKYGUfZQoaAV9lChoDowFaGVsbG+UaBCMAmVulGgSjAVFcnJvcpRoFIwDbG93lGgWTmgXTmgYTmgZTmgajAhub19jbGFpbZRoHF2UaB5dlGggjGpUaGUgaW5wdXQgaXMgYSBncmVldGluZy4gU2VuZCBvbmUgZmFjdHVhbCBjbGFpbSwgb3IgcnVuIHRoZSB0ZXh0IHRocm91Z2ggL2V4dHJhY3QgdG8gZW51bWVyYXRlIGl0cyBjbGFpbXMulHVoIn2UaCSPlChoDmggaBhoHGgWaBBoFGgeaBJoF2gaaBmQaCZOdWJljAVlcnJvcpROaBqMAJRoHF2UjAttb3JlX2NsYWltc5RdlHVoIn2UaCSPlChoB2g3aDSQaCZOdWIu", + "assess__list_compound_item.json": "gASV2wIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwOQXNzZXNzUmVzcG9uc2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwGY2xhaW1zlF2UKGgAjAtBc3Nlc3NDbGFpbZSTlCmBlH2UKGgFfZQojAVjbGFpbZSMDlByaW1hcnkgY2xhaW0ulIwIbGFuZ3VhZ2WUjAJlbpSMB3ZlcmRpY3SUjAxNb3N0bHkgRmFsc2WUjApjb25maWRlbmNllIwEaGlnaJSMEHZlcmlmaWNhdGlvbl91cmyUTowJcmF0aW9uYWxllE6MB2Rpc3NlbnSUTowRc3VnZ2VzdGVkX3Jld3JpdGWUTowKZXJyb3JfY29kZZROjBBjYW5kaWRhdGVfY2xhaW1zlF2UjBFpZGVudGlmaWVkX2NsYWltc5RdlCiMDVNlY29uZCBjbGFpbS6UjAxUaGlyZCBjbGFpbS6UZYwEaGludJSMWkFzc2Vzc2VkIHRoZSBtYWluIGNsYWltIG9ubHkuIFNlbmQgaWRlbnRpZmllZF9jbGFpbXMgYXMgdGhlaXIgb3duIGl0ZW1zIHRvIGNoZWNrIHRoZSByZXN0LpR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgOaCFoGGgbaBZoEGgUaB1oEmgXaBpoGZCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmgKKYGUfZQoaAV9lChoDowOQSBwbGFpbiBjbGFpbS6UaBCMAmVulGgSjAxNb3N0bHkgRmFsc2WUaBSMBGhpZ2iUaBZOaBdOaBhOaBlOaBpOaBtdlGgdXZRoIU51aCN9lGglj5QoaA5oIWgYaBtoFmgQaBRoHWgSaBdoGmgZkGgnTnViZYwFZXJyb3KUTmgajACUaBtdlIwLbW9yZV9jbGFpbXOUXZR1aCN9lGglj5QoaAdoNmgzkGgnTnViLg==", + "assess__list_mixed_rows.json": "gASVxAQAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwOQXNzZXNzUmVzcG9uc2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwGY2xhaW1zlF2UKGgAjAtBc3Nlc3NDbGFpbZSTlCmBlH2UKGgFfZQojAVjbGFpbZSMIldhdGVyIGJvaWxzIGF0IDEwMCBDIGF0IHNlYSBsZXZlbC6UjAhsYW5ndWFnZZSMAmVulIwHdmVyZGljdJSMBFRydWWUjApjb25maWRlbmNllIwEaGlnaJSMEHZlcmlmaWNhdGlvbl91cmyUTowJcmF0aW9uYWxllE6MB2Rpc3NlbnSUTowRc3VnZ2VzdGVkX3Jld3JpdGWUTowKZXJyb3JfY29kZZROjBBjYW5kaWRhdGVfY2xhaW1zlF2UjBFpZGVudGlmaWVkX2NsYWltc5RdlIwEaGludJROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoDmgfaBhoG2gWaBBoFGgdaBJoF2gaaBmQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWJoCimBlH2UKGgFfZQoaA6MC2hlbGxvIHRoZXJllGgQjAJlbpRoEowFRXJyb3KUaBSMA2xvd5RoFk5oF05oGE5oGU5oGowIbm9fY2xhaW2UaBtdlGgdXZRoH4xqVGhlIGlucHV0IGlzIGEgZ3JlZXRpbmcuIFNlbmQgb25lIGZhY3R1YWwgY2xhaW0sIG9yIHJ1biB0aGUgdGV4dCB0aHJvdWdoIC9leHRyYWN0IHRvIGVudW1lcmF0ZSBpdHMgY2xhaW1zLpR1aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjA52ZW5kb3IgaXMgZG93bpRoEIwCZW6UaBKMBUVycm9ylGgUjANsb3eUaBZOaBdOaBhOaBlOaBqMFHVwc3RyZWFtX3VuYXZhaWxhYmxllGgbXZRoHV2UaB+MTkEgbW9kZWwgcHJvdmlkZXIgd2FzIHVuYXZhaWxhYmxlIGZvciB0aGlzIGl0ZW0uIFJldHJ5IGl0OyBub3RoaW5nIHdhcyBjaGFyZ2VkLpR1aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjAxjYW5ub3QgZnJhbWWUaBCMAmVulGgSjAVFcnJvcpRoFIwDbG93lGgWTmgXTmgYTmgZTmgajA5mcmFtaW5nX2ZhaWxlZJRoG12UaB1dlGgfjINUaGlzIGl0ZW0gY291bGQgbm90IGJlIHByb2Nlc3NlZDsgcmV0cnlpbmcgaXQgYXMtaXMgd2lsbCBub3QgaGVscC4gU2VuZCBpdCByZXBocmFzZWQgYXMgb25lIGZhY3R1YWwgc3RhdGVtZW50OyBub3RoaW5nIHdhcyBjaGFyZ2VkLpR1aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViZYwFZXJyb3KUTmgajACUaBtdlIwLbW9yZV9jbGFpbXOUXZR1aCB9lGgij5QoaAdoT2hMkGgkTnViLg==", + "assess__memo_hit.json": "gASVBgIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwOQXNzZXNzUmVzcG9uc2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwGY2xhaW1zlF2UaACMC0Fzc2Vzc0NsYWltlJOUKYGUfZQoaAV9lCiMBWNsYWltlIwgVGhlIERhbnViZSBmbG93cyB0aHJvdWdoIFZpZW5uYS6UjAhsYW5ndWFnZZSMAmVulIwHdmVyZGljdJSMBFRydWWUjApjb25maWRlbmNllIwEaGlnaJSMEHZlcmlmaWNhdGlvbl91cmyUTowJcmF0aW9uYWxllIwgVGhlIHJpdmVyIHJ1bnMgdGhyb3VnaCB0aGUgY2l0eS6UjAdkaXNzZW50lE6MEXN1Z2dlc3RlZF9yZXdyaXRllE6MCmVycm9yX2NvZGWUTowQY2FuZGlkYXRlX2NsYWltc5RdlIwRaWRlbnRpZmllZF9jbGFpbXOUXZSMBGhpbnSUTnWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaA5oIGgZaBxoFmgQaBRoHmgSaBdoG2gakIwUX19weWRhbnRpY19wcml2YXRlX1+UTnViYYwFZXJyb3KUTmgbjACUaBxdlIwLbW9yZV9jbGFpbXOUXZR1aCF9lGgjj5QoaAdoKWgmkGglTnViLg==", + "assess__replay_later_200.json": "gASV3QEAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwOQXNzZXNzUmVzcG9uc2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwGY2xhaW1zlF2UaACMC0Fzc2Vzc0NsYWltlJOUKYGUfZQoaAV9lCiMBWNsYWltlIwZVGhlIEVhcnRoIG9yYml0cyB0aGUgU3VuLpSMCGxhbmd1YWdllIwCZW6UjAd2ZXJkaWN0lIwEVHJ1ZZSMCmNvbmZpZGVuY2WUjARoaWdolIwQdmVyaWZpY2F0aW9uX3VybJROjAlyYXRpb25hbGWUTowHZGlzc2VudJROjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAplcnJvcl9jb2RllE6MEGNhbmRpZGF0ZV9jbGFpbXOUXZSMEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE51jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgOaB9oGGgbaBZoEGgUaB1oEmgXaBpoGZCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMBWVycm9ylE5oGowAlGgbXZSMC21vcmVfY2xhaW1zlF2UdWggfZRoIo+UKGgHaChoJZBoJE51Yi4=", + "assess__single_no_claim.json": "gASVAgEAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwOQXNzZXNzUmVzcG9uc2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwGY2xhaW1zlF2UjAVlcnJvcpSMHE5vIHZlcmlmaWFibGUgY2xhaW0gZGV0ZWN0ZWSUjAplcnJvcl9jb2RllIwIbm9fY2xhaW2UjBBjYW5kaWRhdGVfY2xhaW1zlF2UjAttb3JlX2NsYWltc5RdlHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaA1oD2gLaAdoCZCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51Yi4=", + "assess__single_one_claim.json": "gASViwIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwOQXNzZXNzUmVzcG9uc2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwGY2xhaW1zlF2UaACMC0Fzc2Vzc0NsYWltlJOUKYGUfZQoaAV9lCiMBWNsYWltlIwsVGhlIHJlZ2lzdHJ5IHJlcG9ydGVkIDQsMjAwIGZpbGluZ3MgaW4gMjAyNC6UjAhsYW5ndWFnZZSMAmVulIwHdmVyZGljdJSMBFRydWWUjApjb25maWRlbmNllIwEaGlnaJSMEHZlcmlmaWNhdGlvbl91cmyUTowJcmF0aW9uYWxllIxJVGhlIHJlZ2lzdHJ5IGxpc3RzIDQsMjAwIGZpbGluZ3MgZm9yIDIwMjQgYW5kIGhhcyBub3QgcmV2aXNlZCB0aGUgZmlndXJlLpSMB2Rpc3NlbnSUjE5UaGUgcmVnaXN0cnkgZmlndXJlIGlzIHByb3Zpc2lvbmFsLCBzbyB0aGUgMjAyNCB0b3RhbCBjYW5ub3QgeWV0IGJlIGNvbmZpcm1lZC6UjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAplcnJvcl9jb2RllE6MEGNhbmRpZGF0ZV9jbGFpbXOUXZSMEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE51jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgOaCFoGWgdaBZoEGgUaB9oEmgXaBxoG5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMBWVycm9ylE5oHIwAlGgdXZSMC21vcmVfY2xhaW1zlF2UdWgifZRoJI+UKGgHaCpoJ5BoJk51Yi4=", + "assess__single_text_over_wave_more_claims.json": "gASVbgwAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwOQXNzZXNzUmVzcG9uc2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwGY2xhaW1zlF2UKGgAjAtBc3Nlc3NDbGFpbZSTlCmBlH2UKGgFfZQojAVjbGFpbZSMHUNsYWltIG51bWJlciAwIGlzIGRvY3VtZW50ZWQulIwIbGFuZ3VhZ2WUjAJlbpSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjBB2ZXJpZmljYXRpb25fdXJslE6MCXJhdGlvbmFsZZROjAdkaXNzZW50lE6MEXN1Z2dlc3RlZF9yZXdyaXRllE6MCmVycm9yX2NvZGWUTowQY2FuZGlkYXRlX2NsYWltc5RdlIwRaWRlbnRpZmllZF9jbGFpbXOUXZSMBGhpbnSUTnWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnViaAopgZR9lChoBX2UKGgOjB1DbGFpbSBudW1iZXIgMSBpcyBkb2N1bWVudGVkLpRoEIwCZW6UaBKMBFRydWWUaBSMBGhpZ2iUaBZOaBdOaBhOaBlOaBpOaBtdlGgdXZRoH051aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjB1DbGFpbSBudW1iZXIgMiBpcyBkb2N1bWVudGVkLpRoEIwCZW6UaBKMBFRydWWUaBSMBGhpZ2iUaBZOaBdOaBhOaBlOaBpOaBtdlGgdXZRoH051aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjB1DbGFpbSBudW1iZXIgMyBpcyBkb2N1bWVudGVkLpRoEIwCZW6UaBKMBFRydWWUaBSMBGhpZ2iUaBZOaBdOaBhOaBlOaBpOaBtdlGgdXZRoH051aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjB1DbGFpbSBudW1iZXIgNCBpcyBkb2N1bWVudGVkLpRoEIwCZW6UaBKMBFRydWWUaBSMBGhpZ2iUaBZOaBdOaBhOaBlOaBpOaBtdlGgdXZRoH051aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjB1DbGFpbSBudW1iZXIgNSBpcyBkb2N1bWVudGVkLpRoEIwCZW6UaBKMBFRydWWUaBSMBGhpZ2iUaBZOaBdOaBhOaBlOaBpOaBtdlGgdXZRoH051aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjB1DbGFpbSBudW1iZXIgNiBpcyBkb2N1bWVudGVkLpRoEIwCZW6UaBKMBFRydWWUaBSMBGhpZ2iUaBZOaBdOaBhOaBlOaBpOaBtdlGgdXZRoH051aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjB1DbGFpbSBudW1iZXIgNyBpcyBkb2N1bWVudGVkLpRoEIwCZW6UaBKMBFRydWWUaBSMBGhpZ2iUaBZOaBdOaBhOaBlOaBpOaBtdlGgdXZRoH051aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjB1DbGFpbSBudW1iZXIgOCBpcyBkb2N1bWVudGVkLpRoEIwCZW6UaBKMBFRydWWUaBSMBGhpZ2iUaBZOaBdOaBhOaBlOaBpOaBtdlGgdXZRoH051aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjB1DbGFpbSBudW1iZXIgOSBpcyBkb2N1bWVudGVkLpRoEIwCZW6UaBKMBFRydWWUaBSMBGhpZ2iUaBZOaBdOaBhOaBlOaBpOaBtdlGgdXZRoH051aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjB5DbGFpbSBudW1iZXIgMTAgaXMgZG9jdW1lbnRlZC6UaBCMAmVulGgSjARUcnVllGgUjARoaWdolGgWTmgXTmgYTmgZTmgaTmgbXZRoHV2UaB9OdWggfZRoIo+UKGgOaB9oGGgbaBZoEGgUaB1oEmgXaBpoGZBoJE51YmgKKYGUfZQoaAV9lChoDoweQ2xhaW0gbnVtYmVyIDExIGlzIGRvY3VtZW50ZWQulGgQjAJlbpRoEowEVHJ1ZZRoFIwEaGlnaJRoFk5oF05oGE5oGU5oGk5oG12UaB1dlGgfTnVoIH2UaCKPlChoDmgfaBhoG2gWaBBoFGgdaBJoF2gaaBmQaCROdWJoCimBlH2UKGgFfZQoaA6MHkNsYWltIG51bWJlciAxMiBpcyBkb2N1bWVudGVkLpRoEIwCZW6UaBKMBFRydWWUaBSMBGhpZ2iUaBZOaBdOaBhOaBlOaBpOaBtdlGgdXZRoH051aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjB5DbGFpbSBudW1iZXIgMTMgaXMgZG9jdW1lbnRlZC6UaBCMAmVulGgSjARUcnVllGgUjARoaWdolGgWTmgXTmgYTmgZTmgaTmgbXZRoHV2UaB9OdWggfZRoIo+UKGgOaB9oGGgbaBZoEGgUaB1oEmgXaBpoGZBoJE51YmgKKYGUfZQoaAV9lChoDoweQ2xhaW0gbnVtYmVyIDE0IGlzIGRvY3VtZW50ZWQulGgQjAJlbpRoEowEVHJ1ZZRoFIwEaGlnaJRoFk5oF05oGE5oGU5oGk5oG12UaB1dlGgfTnVoIH2UaCKPlChoDmgfaBhoG2gWaBBoFGgdaBJoF2gaaBmQaCROdWJoCimBlH2UKGgFfZQoaA6MHkNsYWltIG51bWJlciAxNSBpcyBkb2N1bWVudGVkLpRoEIwCZW6UaBKMBFRydWWUaBSMBGhpZ2iUaBZOaBdOaBhOaBlOaBpOaBtdlGgdXZRoH051aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjB5DbGFpbSBudW1iZXIgMTYgaXMgZG9jdW1lbnRlZC6UaBCMAmVulGgSjARUcnVllGgUjARoaWdolGgWTmgXTmgYTmgZTmgaTmgbXZRoHV2UaB9OdWggfZRoIo+UKGgOaB9oGGgbaBZoEGgUaB1oEmgXaBpoGZBoJE51YmgKKYGUfZQoaAV9lChoDoweQ2xhaW0gbnVtYmVyIDE3IGlzIGRvY3VtZW50ZWQulGgQjAJlbpRoEowEVHJ1ZZRoFIwEaGlnaJRoFk5oF05oGE5oGU5oGk5oG12UaB1dlGgfTnVoIH2UaCKPlChoDmgfaBhoG2gWaBBoFGgdaBJoF2gaaBmQaCROdWJoCimBlH2UKGgFfZQoaA6MHkNsYWltIG51bWJlciAxOCBpcyBkb2N1bWVudGVkLpRoEIwCZW6UaBKMBFRydWWUaBSMBGhpZ2iUaBZOaBdOaBhOaBlOaBpOaBtdlGgdXZRoH051aCB9lGgij5QoaA5oH2gYaBtoFmgQaBRoHWgSaBdoGmgZkGgkTnViaAopgZR9lChoBX2UKGgOjB5DbGFpbSBudW1iZXIgMTkgaXMgZG9jdW1lbnRlZC6UaBCMAmVulGgSjARUcnVllGgUjARoaWdolGgWTmgXTmgYTmgZTmgaTmgbXZRoHV2UaB9OdWggfZRoIo+UKGgOaB9oGGgbaBZoEGgUaB1oEmgXaBpoGZBoJE51YmWMBWVycm9ylE5oGowAlGgbXZSMC21vcmVfY2xhaW1zlF2UKIweQ2xhaW0gbnVtYmVyIDIwIGlzIGRvY3VtZW50ZWQulIweQ2xhaW0gbnVtYmVyIDIxIGlzIGRvY3VtZW50ZWQulGV1aCB9lGgij5QoaAdo+Wj2kGgkTnViLg==", + "assess__single_text_several_claims.json": "gASVBwMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwOQXNzZXNzUmVzcG9uc2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwGY2xhaW1zlF2UKGgAjAtBc3Nlc3NDbGFpbZSTlCmBlH2UKGgFfZQojAVjbGFpbZSMIldhdGVyIGJvaWxzIGF0IDEwMCBDIGF0IHNlYSBsZXZlbC6UjAhsYW5ndWFnZZSMAmVulIwHdmVyZGljdJSMBFRydWWUjApjb25maWRlbmNllIwEaGlnaJSMEHZlcmlmaWNhdGlvbl91cmyUTowJcmF0aW9uYWxllE6MB2Rpc3NlbnSUTowRc3VnZ2VzdGVkX3Jld3JpdGWUTowKZXJyb3JfY29kZZROjBBjYW5kaWRhdGVfY2xhaW1zlF2UjBFpZGVudGlmaWVkX2NsYWltc5RdlIwEaGludJROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoDmgfaBhoG2gWaBBoFGgdaBJoF2gaaBmQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWJoCimBlH2UKGgFfZQoaA6MG1RoZSBNb29uIGlzIG1hZGUgb2YgY2hlZXNlLpRoEIwCZW6UaBKMBUZhbHNllGgUjARoaWdolGgWTmgXTmgYTmgZTmgaTmgbXZRoHV2UaB9OdWggfZRoIo+UKGgOaB9oGGgbaBZoEGgUaB1oEmgXaBpoGZBoJE51YmgKKYGUfZQoaAV9lChoDowhVGhlIFBhY2lmaWMgaXMgdGhlIGRlZXBlc3Qgb2NlYW4ulGgQjAJlbpRoEowLTW9zdGx5IFRydWWUaBSMBm1lZGl1bZRoFk5oF05oGE5oGU5oGk5oG12UaB1dlGgfTnVoIH2UaCKPlChoDmgfaBhoG2gWaBBoFGgdaBJoF2gaaBmQaCROdWJljAVlcnJvcpROaBqMAJRoG12UjAttb3JlX2NsYWltc5RdlHVoIH2UaCKPlChoB2g+aDuQaCROdWIu", + "assess__suggest_rewrite.json": "gASVBwMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwOQXNzZXNzUmVzcG9uc2WUk5QpgZR9lCiMCF9fZGljdF9flH2UKIwGY2xhaW1zlF2UKGgAjAtBc3Nlc3NDbGFpbZSTlCmBlH2UKGgFfZQojAVjbGFpbZSMJ1ZlbnVzIGlzIHRoZSBjbG9zZXN0IHBsYW5ldCB0byB0aGUgU3VuLpSMCGxhbmd1YWdllIwCZW6UjAd2ZXJkaWN0lIwFRmFsc2WUjApjb25maWRlbmNllIwEaGlnaJSMEHZlcmlmaWNhdGlvbl91cmyUTowJcmF0aW9uYWxllIw1TWVyY3VyeSwgbm90IFZlbnVzLCBpcyB0aGUgY2xvc2VzdCBwbGFuZXQgdG8gdGhlIFN1bi6UjAdkaXNzZW50lE6MEXN1Z2dlc3RlZF9yZXdyaXRllIwpTWVyY3VyeSBpcyB0aGUgY2xvc2VzdCBwbGFuZXQgdG8gdGhlIFN1bi6UjAplcnJvcl9jb2RllE6MEGNhbmRpZGF0ZV9jbGFpbXOUXZSMEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE51jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgOaCFoGWgdaBZoEGgUaB9oEmgXaBxoGpCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmgKKYGUfZQoaAV9lChoDowpTWVyY3VyeSBpcyB0aGUgY2xvc2VzdCBwbGFuZXQgdG8gdGhlIFN1bi6UaBCMAmVulGgSjARUcnVllGgUjARoaWdolGgWTmgXjCBNZXJjdXJ5IGlzIHRoZSBpbm5lcm1vc3QgcGxhbmV0LpRoGU5oGk5oHE5oHV2UaB9dlGghTnVoIn2UaCSPlChoDmghaBloHWgWaBBoFGgfaBJoF2gcaBqQaCZOdWJljAVlcnJvcpROaByMAJRoHV2UjAttb3JlX2NsYWltc5RdlHVoIn2UaCSPlChoB2g2aDOQaCZOdWIu", + "citecheck__get_checking.json": "gASV7AYAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwJQ2l0ZWNoZWNrlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMDGNpdGVjaGVja19pZJSMCDhlYjQ5MzAylIwGc3RhdHVzlIwIY2hlY2tpbmeUjAdvdXRjb21llE6MCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUTowScG9sbF9hZnRlcl9zZWNvbmRzlEsKjAZwb2xpY3mUaACMD0NpdGVjaGVja1BvbGljeZSTlCmBlH2UKGgFfZSMDW1heF9jaXRhdGlvbnOUSwJzjBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgWkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAdzdW1tYXJ5lGgAjBBDaXRlY2hlY2tTdW1tYXJ5lJOUKYGUfZQoaAV9lCiMD2NpdGF0aW9uc19mb3VuZJRLAowSY2l0YXRpb25zX3NlbGVjdGVklEsCjA5jaXRhdGlvbl9saW1pdJRLAowWY2l0YXRpb25fbGltaXRfcmVhY2hlZJSJjA9jaXRhdGlvbl9jaGVja3OUaACMGVJldmlld0NpdGF0aW9uQ2hlY2tDb3VudHOUk5QpgZR9lChoBX2UKIwHY2hlY2tlZJRLAIwJdW5jaGVja2VklEsAjAZmYWlsZWSUSwB1aBd9lGgZj5QoaCxoLWgukGgbTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwB1aBd9lGgZj5QoaCNoJWgxaCRoJmgikGgbTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAHNoF32UaBmPlChoOpBoG051YowJY2l0YXRpb25zlF2UKGgAjA5SZXZpZXdDaXRhdGlvbpSTlCmBlH2UKGgFfZQojAVpbmRleJRLAIwJcmVmZXJlbmNllIwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSMCWNpdGVkX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjANkb2mUTowJc3RhdGVtZW50lIwiVW5lbXBsb3ltZW50IGZlbGwgdG8gNC4xJSBpbiAyMDI0LpSMBnF1b3Rlc5RdlIwIcG9zaXRpb26UTowGcmVzdWx0lE6MBWNoZWNrlGgAjBNSZXZpZXdDaXRhdGlvbkNoZWNrlJOUKYGUfZQoaAV9lChoCYwHcGVuZGluZ5SMCXBhZ2VfcmVhZJROjApwYWdlX3RpdGxllE6ME3BhZ2VfcHVibGlzaGVkX2RhdGWUTowNcGFnZV9sYW5ndWFnZZROjApzb3VyY2VfdXJslE6MDnNvdXJjZV92ZXJzaW9ulE6MB3N1cHBvcnSUTowHc25pcHBldJROjAlyYXRpb25hbGWUTowFcXVvdGWUTowNbWlzc2luZ19xdW90ZZROjA5kb2lfcmVnaXN0ZXJlZJROjAhtZXRhZGF0YZROjBRtZXRhZGF0YV9kaWZmZXJlbmNlc5RdlIwKcmVnaXN0ZXJlZJROjBB1bmNoZWNrZWRfcmVhc29ulE6MBGhpbnSUTowHZmFpbHVyZZROdWgXfZRoGY+UKGhZaGdoX2haaFtoaGhiaGNoCWhhaGRoYGhYaGZoXWhXaFxoXmhpkGgbTnVidWgXfZRoGY+UKGhKaE9oRWhQaERoSWhMaEdoTpBoG051YmhAKYGUfZQoaAV9lChoREsBaEWMHWh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGhHjB1odHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRoSU5oSowiVGhlIGFnZW5jeSBzYWlkIHNvIGluIGEgc3RhdGVtZW50LpRoTF2UaE5OaE9OaFBoUimBlH2UKGgFfZQoaAmMB3BlbmRpbmeUaFdOaFhOaFlOaFpOaFtOaFxOaF1OaF5OaF9OaGBOaGFOaGJOaGNOaGRdlGhmTmhnTmhoTmhpTnVoF32UaBmPlChoWWhnaF9oWmhbaGhoYmhjaAloYWhkaGBoWGhmaF1oV2hcaF5oaZBoG051YnVoF32UaBmPlChoSmhPaEVoUGhEaEloTGhHaE6QaBtOdWJlaDFdlIwRY2l0YXRpb25fZmFpbHVyZXOUXZSMDm1vcmVfY2l0YXRpb25zlF2UaGlOdWgXfZSMCGxhbmd1YWdllIwCZW6Uc2gZj5QoaAtoNGgOaAxohGgJaBBoPWgxaH9oD2gHaBxogWhpkGgbTnViLg==", + "citecheck__get_completed_clean.json": "gASV0QgAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwJQ2l0ZWNoZWNrlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMDGNpdGVjaGVja19pZJSMCDhlYjQ5MzAylIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROjAZwb2xpY3mUaACMD0NpdGVjaGVja1BvbGljeZSTlCmBlH2UKGgFfZSMDW1heF9jaXRhdGlvbnOUSwJzjBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgYkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAdzdW1tYXJ5lGgAjBBDaXRlY2hlY2tTdW1tYXJ5lJOUKYGUfZQoaAV9lCiMD2NpdGF0aW9uc19mb3VuZJRLAowSY2l0YXRpb25zX3NlbGVjdGVklEsCjA5jaXRhdGlvbl9saW1pdJRLAowWY2l0YXRpb25fbGltaXRfcmVhY2hlZJSJjA9jaXRhdGlvbl9jaGVja3OUaACMGVJldmlld0NpdGF0aW9uQ2hlY2tDb3VudHOUk5QpgZR9lChoBX2UKIwHY2hlY2tlZJRLAowJdW5jaGVja2VklEsAjAZmYWlsZWSUSwB1aBl9lGgbj5QoaC5oL2gwkGgdTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwB1aBl9lGgbj5QoaCVoJ2gzaCZoKGgkkGgdTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAnNoGX2UaBuPlChoPJBoHU51YowJY2l0YXRpb25zlF2UKGgAjA5SZXZpZXdDaXRhdGlvbpSTlCmBlH2UKGgFfZQojAVpbmRleJRLAIwJcmVmZXJlbmNllIwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSMCWNpdGVkX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjANkb2mUTowJc3RhdGVtZW50lIwiVW5lbXBsb3ltZW50IGZlbGwgdG8gNC4xJSBpbiAyMDI0LpSMBnF1b3Rlc5RdlIwIcG9zaXRpb26UTowGcmVzdWx0lGgAjBRSZXZpZXdDaXRhdGlvblJlc3VsdJSTlCmBlH2UKGgFfZQojAdmaW5kaW5nlIwJc3VwcG9ydGVklIwGc291cmNllIwHc3VwcG9ydJSMCGlzX2lzc3VllIl1aBl9lGgbj5QoaFdoW2hZkGgdTnVijAVjaGVja5RoAIwTUmV2aWV3Q2l0YXRpb25DaGVja5STlCmBlH2UKGgFfZQoaAmMCWNvbXBsZXRlZJSMCXBhZ2VfcmVhZJSMBGZ1bGyUjApwYWdlX3RpdGxllIwnUGFnZSBhdCBodHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwTcGFnZV9wdWJsaXNoZWRfZGF0ZZROjA1wYWdlX2xhbmd1YWdllIwCZW6UjApzb3VyY2VfdXJslIwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSMDnNvdXJjZV92ZXJzaW9ulE6MB3N1cHBvcnSUjAlzdXBwb3J0ZWSUjAdzbmlwcGV0lIwTVGhlIHNvdXJjZSBzYXlzIHNvLpSMCXJhdGlvbmFsZZSME1RoZSBwYWdlIHN0YXRlcyBpdC6UjAVxdW90ZZROjA1taXNzaW5nX3F1b3RllE6MDmRvaV9yZWdpc3RlcmVklE6MCG1ldGFkYXRhlE6MFG1ldGFkYXRhX2RpZmZlcmVuY2VzlF2UjApyZWdpc3RlcmVklE6MEHVuY2hlY2tlZF9yZWFzb26UTowEaGludJROjAdmYWlsdXJllE51aBl9lGgbj5QoaGlofGhzaGpobGh9aHdoeGgJaHZoeWh1aGdoe2hvaGVobmhxaH6QaB1OdWJ1aBl9lGgbj5QoaExoUWhHaF5oRmhLaE5oSWhQkGgdTnViaEIpgZR9lChoBX2UKGhGSwFoR4wdaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaEmMHWh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGhLTmhMjCJUaGUgYWdlbmN5IHNhaWQgc28gaW4gYSBzdGF0ZW1lbnQulGhOXZRoUE5oUWhTKYGUfZQoaAV9lChoV4wJc3VwcG9ydGVklGhZjAdzdXBwb3J0lGhbiXVoGX2UaBuPlChoV2hbaFmQaB1OdWJoXmhgKYGUfZQoaAV9lChoCYwJY29tcGxldGVklGhljARmdWxslGhnjCVQYWdlIGF0IGh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGhpTmhqjAJlbpRobIwdaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaG5OaG+MCXN1cHBvcnRlZJRocYwTVGhlIHNvdXJjZSBzYXlzIHNvLpRoc4wTVGhlIHBhZ2Ugc3RhdGVzIGl0LpRodU5odk5od05oeE5oeV2UaHtOaHxOaH1OaH5OdWgZfZRoG4+UKGhpaHxoc2hqaGxofWh3aHhoCWh2aHlodWhnaHtob2hlaG5ocWh+kGgdTnVidWgZfZRoG4+UKGhMaFFoR2heaEZoS2hOaEloUJBoHU51YmVoM12UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwObW9yZV9jaXRhdGlvbnOUXZRofk51aBl9lIwIbGFuZ3VhZ2WUjAJlbpRzaBuPlChoC2g2aA9oDWinaAloEmg/aDNoomgRaAdoHmikaH6QaB1OdWIu", + "citecheck__get_completed_doi_pair.json": "gASVrAYAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwJQ2l0ZWNoZWNrlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMDGNpdGVjaGVja19pZJSMCDhlYjQ5MzAylIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROjAZwb2xpY3mUaACMD0NpdGVjaGVja1BvbGljeZSTlCmBlH2UKGgFfZSMDW1heF9jaXRhdGlvbnOUSwFzjBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgYkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAdzdW1tYXJ5lGgAjBBDaXRlY2hlY2tTdW1tYXJ5lJOUKYGUfZQoaAV9lCiMD2NpdGF0aW9uc19mb3VuZJRLAYwSY2l0YXRpb25zX3NlbGVjdGVklEsBjA5jaXRhdGlvbl9saW1pdJRLAYwWY2l0YXRpb25fbGltaXRfcmVhY2hlZJSJjA9jaXRhdGlvbl9jaGVja3OUaACMGVJldmlld0NpdGF0aW9uQ2hlY2tDb3VudHOUk5QpgZR9lChoBX2UKIwHY2hlY2tlZJRLAYwJdW5jaGVja2VklEsAjAZmYWlsZWSUSwB1aBl9lGgbj5QoaC5oL2gwkGgdTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwB1aBl9lGgbj5QoaCVoJ2gzaCZoKGgkkGgdTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAXNoGX2UaBuPlChoPJBoHU51YowJY2l0YXRpb25zlF2UaACMDlJldmlld0NpdGF0aW9ulJOUKYGUfZQoaAV9lCiMBWluZGV4lEsAjAlyZWZlcmVuY2WUjBMxMC4xMDM4L25hdHVyZTEyMzczlIwJY2l0ZWRfdXJslIwjaHR0cHM6Ly9kb2kub3JnLzEwLjEwMzgvbmF0dXJlMTIzNzOUjANkb2mUjBMxMC4xMDM4L25hdHVyZTEyMzczlIwJc3RhdGVtZW50lIwmRGlhbW9uZCBzZW5zb3JzIG1lYXN1cmUgaGVhdCBpbiBjZWxscy6UjAZxdW90ZXOUXZSMCHBvc2l0aW9ulE6MBnJlc3VsdJRoAIwUUmV2aWV3Q2l0YXRpb25SZXN1bHSUk5QpgZR9lChoBX2UKIwHZmluZGluZ5SMCXN1cHBvcnRlZJSMBnNvdXJjZZSMB3N1cHBvcnSUjAhpc19pc3N1ZZSJdWgZfZRoG4+UKGhYaFxoWpBoHU51YowFY2hlY2uUaACME1Jldmlld0NpdGF0aW9uQ2hlY2uUk5QpgZR9lChoBX2UKGgJjAljb21wbGV0ZWSUjAlwYWdlX3JlYWSUjARmdWxslIwKcGFnZV90aXRsZZSMDFBhZ2UgYXQgTm9uZZSME3BhZ2VfcHVibGlzaGVkX2RhdGWUTowNcGFnZV9sYW5ndWFnZZSMAmVulIwKc291cmNlX3VybJROjA5zb3VyY2VfdmVyc2lvbpROjAdzdXBwb3J0lIwJc3VwcG9ydGVklIwHc25pcHBldJSME1RoZSBzb3VyY2Ugc2F5cyBzby6UjAlyYXRpb25hbGWUjBNUaGUgcGFnZSBzdGF0ZXMgaXQulIwFcXVvdGWUTowNbWlzc2luZ19xdW90ZZROjA5kb2lfcmVnaXN0ZXJlZJROjAhtZXRhZGF0YZROjBRtZXRhZGF0YV9kaWZmZXJlbmNlc5RdlIwKcmVnaXN0ZXJlZJROjBB1bmNoZWNrZWRfcmVhc29ulE6MBGhpbnSUTowHZmFpbHVyZZROdWgZfZRoG4+UKGhqaHxoc2hraG1ofWh3aHhoCWh2aHlodWhoaHtob2hmaG5ocWh+kGgdTnVidWgZfZRoG4+UKGhNaFJoR2hfaEZoS2hPaEloUZBoHU51YmFoM12UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwObW9yZV9jaXRhdGlvbnOUXZRofk51aBl9lIwIbGFuZ3VhZ2WUjAJlbpRzaBuPlChoC2g2aA9oDWiJaAloEmg/aDNohGgRaAdoHmiGaH6QaB1OdWIu", + "citecheck__get_completed_incomplete.json": "gASVXQoAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwJQ2l0ZWNoZWNrlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMDGNpdGVjaGVja19pZJSMCDhlYjQ5MzAylIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMCmluY29tcGxldGWUjApjcmVhdGVkX2F0lIwbMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTZalIwMY29tcGxldGVkX2F0lIwbMjAyNi0xMC0wMVQxMDowNzowMC4xMjM0NTZalIwScG9sbF9hZnRlcl9zZWNvbmRzlE6MBnBvbGljeZRoAIwPQ2l0ZWNoZWNrUG9saWN5lJOUKYGUfZQoaAV9lIwNbWF4X2NpdGF0aW9uc5RLAnOMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBiQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMB3N1bW1hcnmUaACMEENpdGVjaGVja1N1bW1hcnmUk5QpgZR9lChoBX2UKIwPY2l0YXRpb25zX2ZvdW5klEsCjBJjaXRhdGlvbnNfc2VsZWN0ZWSUSwKMDmNpdGF0aW9uX2xpbWl0lEsCjBZjaXRhdGlvbl9saW1pdF9yZWFjaGVklImMD2NpdGF0aW9uX2NoZWNrc5RoAIwZUmV2aWV3Q2l0YXRpb25DaGVja0NvdW50c5STlCmBlH2UKGgFfZQojAdjaGVja2VklEsBjAl1bmNoZWNrZWSUSwCMBmZhaWxlZJRLAXVoGX2UaBuPlChoLmgvaDCQaB1OdWKMD2NpdGF0aW9uX2lzc3Vlc5RLAHVoGX2UaBuPlChoJWgnaDNoJmgoaCSQaB1OdWKMB2NyZWRpdHOUaACMDVJldmlld0NyZWRpdHOUk5QpgZR9lChoBX2UjAdjaGFyZ2VklEsBc2gZfZRoG4+UKGg8kGgdTnVijAljaXRhdGlvbnOUXZQoaACMDlJldmlld0NpdGF0aW9ulJOUKYGUfZQoaAV9lCiMBWluZGV4lEsAjAlyZWZlcmVuY2WUjB9odHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwJY2l0ZWRfdXJslIwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSMA2RvaZROjAlzdGF0ZW1lbnSUjCJVbmVtcGxveW1lbnQgZmVsbCB0byA0LjElIGluIDIwMjQulIwGcXVvdGVzlF2UjAhwb3NpdGlvbpROjAZyZXN1bHSUaACMFFJldmlld0NpdGF0aW9uUmVzdWx0lJOUKYGUfZQoaAV9lCiMB2ZpbmRpbmeUjAlzdXBwb3J0ZWSUjAZzb3VyY2WUjAdzdXBwb3J0lIwIaXNfaXNzdWWUiXVoGX2UaBuPlChoV2hbaFmQaB1OdWKMBWNoZWNrlGgAjBNSZXZpZXdDaXRhdGlvbkNoZWNrlJOUKYGUfZQoaAV9lChoCYwJY29tcGxldGVklIwJcGFnZV9yZWFklIwEZnVsbJSMCnBhZ2VfdGl0bGWUjCdQYWdlIGF0IGh0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjBNwYWdlX3B1Ymxpc2hlZF9kYXRllE6MDXBhZ2VfbGFuZ3VhZ2WUjAJlbpSMCnNvdXJjZV91cmyUjB9odHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwOc291cmNlX3ZlcnNpb26UTowHc3VwcG9ydJSMCXN1cHBvcnRlZJSMB3NuaXBwZXSUjBNUaGUgc291cmNlIHNheXMgc28ulIwJcmF0aW9uYWxllIwTVGhlIHBhZ2Ugc3RhdGVzIGl0LpSMBXF1b3RllE6MDW1pc3NpbmdfcXVvdGWUTowOZG9pX3JlZ2lzdGVyZWSUTowIbWV0YWRhdGGUTowUbWV0YWRhdGFfZGlmZmVyZW5jZXOUXZSMCnJlZ2lzdGVyZWSUTowQdW5jaGVja2VkX3JlYXNvbpROjARoaW50lE6MB2ZhaWx1cmWUTnVoGX2UaBuPlChoaWh8aHNoamhsaH1od2h4aAlodmh5aHVoZ2h7aG9oZWhuaHFofpBoHU51YnVoGX2UaBuPlChoTGhRaEdoXmhGaEtoTmhJaFCQaB1OdWJoQimBlH2UKGgFfZQoaEZLAWhHjB1odHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRoSYwdaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaEtOaEyMIlRoZSBhZ2VuY3kgc2FpZCBzbyBpbiBhIHN0YXRlbWVudC6UaE5dlGhQTmhRTmheaGApgZR9lChoBX2UKGgJjAZmYWlsZWSUaGVOaGdOaGlOaGpOaGxOaG5OaG9OaHFOaHNOaHVOaHZOaHdOaHhOaHldlGh7Tmh8Tmh9jC5UaGUgY2hlY2sgZmFpbGVkIG9uIG91ciBzaWRlLiBUcnkgYWdhaW4gbGF0ZXIulGh+aACMDEZhaWx1cmVCbG9ja5STlCmBlH2UKGgFfZQojA5mYWlsdXJlX3JlYXNvbpSMCGludGVybmFslIwNZmFpbHVyZV9jbGFzc5SMCGludGVybmFslIwJcmV0cnlhYmxllIlofYwuVGhlIGNoZWNrIGZhaWxlZCBvbiBvdXIgc2lkZS4gVHJ5IGFnYWluIGxhdGVyLpSMCGRvY3NfdXJslIwkaHR0cHM6Ly9sZW56LmlvL2RvY3MvZXJyb3JzI2ludGVybmFslHVoGX2UaBuPlChofWiVaJtol2iZkGgdTnVidWgZfZRoG4+UKGhpaHxoc2hqaGxofWh3aHhoCWh2aHlodWhnaHtob2hlaG5ocWh+kGgdTnVidWgZfZRoG4+UKGhMaFFoR2heaEZoS2hOaEloUJBoHU51YmVoM12UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlGgAjBVSZXZpZXdDaXRhdGlvbkZhaWx1cmWUk5QpgZR9lChoBX2UKIwOY2l0YXRpb25faW5kZXiUSwFoR4wdaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaEmMHWh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGhLTmh+aJEpgZR9lChoBX2UKGiVjAhpbnRlcm5hbJRol4wIaW50ZXJuYWyUaJmJaH2MLlRoZSBjaGVjayBmYWlsZWQgb24gb3VyIHNpZGUuIFRyeSBhZ2FpbiBsYXRlci6UaJuMJGh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyNpbnRlcm5hbJR1aBl9lGgbj5QoaH1olWibaJdomZBoHU51YnVoGX2UaBuPlChoR2hLaKtoSWh+kGgdTnViYYwObW9yZV9jaXRhdGlvbnOUXZRofk51aBl9lIwIbGFuZ3VhZ2WUjAJlbpRzaBuPlChoC2g2aA9oDWi8aAloEmg/aDNopGgRaAdoHmi5aH6QaB1OdWIu", + "citecheck__get_completed_issues_found.json": "gASVGgsAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwJQ2l0ZWNoZWNrlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMDGNpdGVjaGVja19pZJSMCDhlYjQ5MzAylIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMDGlzc3Vlc19mb3VuZJSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjBJwb2xsX2FmdGVyX3NlY29uZHOUTowGcG9saWN5lGgAjA9DaXRlY2hlY2tQb2xpY3mUk5QpgZR9lChoBX2UjA1tYXhfY2l0YXRpb25zlEsUc4wSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGJCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwQQ2l0ZWNoZWNrU3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jaXRhdGlvbnNfZm91bmSUSwKMEmNpdGF0aW9uc19zZWxlY3RlZJRLAowOY2l0YXRpb25fbGltaXSUSxSMFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUiYwPY2l0YXRpb25fY2hlY2tzlGgAjBlSZXZpZXdDaXRhdGlvbkNoZWNrQ291bnRzlJOUKYGUfZQoaAV9lCiMB2NoZWNrZWSUSwKMCXVuY2hlY2tlZJRLAIwGZmFpbGVklEsAdWgZfZRoG4+UKGguaC9oMJBoHU51YowPY2l0YXRpb25faXNzdWVzlEsBdWgZfZRoG4+UKGglaCdoM2gmaChoJJBoHU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwJzaBl9lGgbj5QoaDyQaB1OdWKMCWNpdGF0aW9uc5RdlChoAIwOUmV2aWV3Q2l0YXRpb26Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMCXJlZmVyZW5jZZSMGmEgcmVwb3J0IGZyb20gdGhlIG1pbmlzdHJ5lIwJY2l0ZWRfdXJslIwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSMA2RvaZROjAlzdGF0ZW1lbnSUjEtVbmVtcGxveW1lbnQgZmVsbCB0byA0LjElIGluIDIwMjQsIGFjY29yZGluZyB0byBhIHJlcG9ydCBmcm9tIHRoZSBtaW5pc3RyeS6UjAZxdW90ZXOUXZSMCHBvc2l0aW9ulGgAjAhQb3NpdGlvbpSTlCmBlH2UKGgFfZQojAVzdGFydJRLAIwDZW5klEtujAR0ZXh0lE51aBl9lGgbj5QoaFZoV2hYkGgdTnVijAZyZXN1bHSUaACMFFJldmlld0NpdGF0aW9uUmVzdWx0lJOUKYGUfZQoaAV9lCiMB2ZpbmRpbmeUjAxjb250cmFkaWN0ZWSUjAZzb3VyY2WUjAdzdXBwb3J0lIwIaXNfaXNzdWWUiHVoGX2UaBuPlChoYWhlaGOQaB1OdWKMBWNoZWNrlGgAjBNSZXZpZXdDaXRhdGlvbkNoZWNrlJOUKYGUfZQoaAV9lChoCYwJY29tcGxldGVklIwJcGFnZV9yZWFklIwEZnVsbJSMCnBhZ2VfdGl0bGWUjCdQYWdlIGF0IGh0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjBNwYWdlX3B1Ymxpc2hlZF9kYXRllE6MDXBhZ2VfbGFuZ3VhZ2WUjAJlbpSMCnNvdXJjZV91cmyUjB9odHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwOc291cmNlX3ZlcnNpb26UTowHc3VwcG9ydJSMDGNvbnRyYWRpY3RlZJSMB3NuaXBwZXSUjBNUaGUgc291cmNlIHNheXMgc28ulIwJcmF0aW9uYWxllIwTVGhlIHBhZ2Ugc3RhdGVzIGl0LpSMBXF1b3RllE6MDW1pc3NpbmdfcXVvdGWUTowOZG9pX3JlZ2lzdGVyZWSUTowIbWV0YWRhdGGUTowUbWV0YWRhdGFfZGlmZmVyZW5jZXOUXZSMCnJlZ2lzdGVyZWSUTowQdW5jaGVja2VkX3JlYXNvbpROjARoaW50lE6MB2ZhaWx1cmWUTnVoGX2UaBuPlChoc2iGaH1odGh2aIdogWiCaAlogGiDaH9ocWiFaHlob2h4aHtoiJBoHU51YnVoGX2UaBuPlChoTGhbaEdoaGhGaEtoTmhJaFCQaB1OdWJoQimBlH2UKGgFfZQoaEZLAWhHjAthIHN0YXRlbWVudJRoSYwdaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaEtOaEyMIlRoZSBhZ2VuY3kgc2FpZCBzbyBpbiBhIHN0YXRlbWVudC6UaE5dlGhQaFIpgZR9lChoBX2UKGhWS29oV0uyaFhOdWgZfZRoG4+UKGhWaFdoWJBoHU51YmhbaF0pgZR9lChoBX2UKGhhjAlzdXBwb3J0ZWSUaGOMB3N1cHBvcnSUaGWJdWgZfZRoG4+UKGhhaGVoY5BoHU51YmhoaGopgZR9lChoBX2UKGgJjAljb21wbGV0ZWSUaG+MBGZ1bGyUaHGMJVBhZ2UgYXQgaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaHNOaHSMAmVulGh2jB1odHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRoeE5oeYwJc3VwcG9ydGVklGh7jBNUaGUgc291cmNlIHNheXMgc28ulGh9jBNUaGUgcGFnZSBzdGF0ZXMgaXQulGh/TmiATmiBTmiCTmiDXZRohU5ohk5oh05oiE51aBl9lGgbj5QoaHNohmh9aHRodmiHaIFogmgJaIBog2h/aHFohWh5aG9oeGh7aIiQaB1OdWJ1aBl9lGgbj5QoaExoW2hHaGhoRmhLaE5oSWhQkGgdTnViZWgzXZRoAIwTUmV2aWV3Q2l0YXRpb25Jc3N1ZZSTlCmBlH2UKGgFfZQojA5jaXRhdGlvbl9pbmRleJRLAGhHjBphIHJlcG9ydCBmcm9tIHRoZSBtaW5pc3RyeZRoSYwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJRoS05oTIxLVW5lbXBsb3ltZW50IGZlbGwgdG8gNC4xJSBpbiAyMDI0LCBhY2NvcmRpbmcgdG8gYSByZXBvcnQgZnJvbSB0aGUgbWluaXN0cnkulGhOXZRoUGhSKYGUfZQoaAV9lChoVksAaFdLbmhYTnVoGX2UaBuPlChoVmhXaFiQaB1OdWJoYYwMY29udHJhZGljdGVklGhjjAdzdXBwb3J0lGh7jBNUaGUgc291cmNlIHNheXMgc28ulGh9jBNUaGUgcGFnZSBzdGF0ZXMgaXQulGiATmiDXZRocYwnUGFnZSBhdCBodHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lGiITnVoGX2UaBuPlChoTGiAaEdog2hxaEtotmh9aE5oY2hhaEloe2iIaFCQaB1OdWJhjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwObW9yZV9jaXRhdGlvbnOUXZRoiE51aBl9lIwIbGFuZ3VhZ2WUjAJlbpRzaBuPlChoC2g2aA9oDWjNaAloEmg/aDNoyGgRaAdoHmjKaIiQaB1OdWIu", + "citecheck__get_completed_partly_supported.json": "gASV3wgAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwJQ2l0ZWNoZWNrlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMDGNpdGVjaGVja19pZJSMCDhlYjQ5MzAylIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROjAZwb2xpY3mUaACMD0NpdGVjaGVja1BvbGljeZSTlCmBlH2UKGgFfZSMDW1heF9jaXRhdGlvbnOUSwJzjBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgYkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAdzdW1tYXJ5lGgAjBBDaXRlY2hlY2tTdW1tYXJ5lJOUKYGUfZQoaAV9lCiMD2NpdGF0aW9uc19mb3VuZJRLAowSY2l0YXRpb25zX3NlbGVjdGVklEsCjA5jaXRhdGlvbl9saW1pdJRLAowWY2l0YXRpb25fbGltaXRfcmVhY2hlZJSJjA9jaXRhdGlvbl9jaGVja3OUaACMGVJldmlld0NpdGF0aW9uQ2hlY2tDb3VudHOUk5QpgZR9lChoBX2UKIwHY2hlY2tlZJRLAowJdW5jaGVja2VklEsAjAZmYWlsZWSUSwB1aBl9lGgbj5QoaC5oL2gwkGgdTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwB1aBl9lGgbj5QoaCVoJ2gzaCZoKGgkkGgdTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAnNoGX2UaBuPlChoPJBoHU51YowJY2l0YXRpb25zlF2UKGgAjA5SZXZpZXdDaXRhdGlvbpSTlCmBlH2UKGgFfZQojAVpbmRleJRLAIwJcmVmZXJlbmNllIwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSMCWNpdGVkX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjANkb2mUTowJc3RhdGVtZW50lIwiVW5lbXBsb3ltZW50IGZlbGwgdG8gNC4xJSBpbiAyMDI0LpSMBnF1b3Rlc5RdlIwIcG9zaXRpb26UTowGcmVzdWx0lGgAjBRSZXZpZXdDaXRhdGlvblJlc3VsdJSTlCmBlH2UKGgFfZQojAdmaW5kaW5nlIwQcGFydGx5X3N1cHBvcnRlZJSMBnNvdXJjZZSMB3N1cHBvcnSUjAhpc19pc3N1ZZSJdWgZfZRoG4+UKGhXaFtoWZBoHU51YowFY2hlY2uUaACME1Jldmlld0NpdGF0aW9uQ2hlY2uUk5QpgZR9lChoBX2UKGgJjAljb21wbGV0ZWSUjAlwYWdlX3JlYWSUjARmdWxslIwKcGFnZV90aXRsZZSMJ1BhZ2UgYXQgaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSME3BhZ2VfcHVibGlzaGVkX2RhdGWUTowNcGFnZV9sYW5ndWFnZZSMAmVulIwKc291cmNlX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjA5zb3VyY2VfdmVyc2lvbpROjAdzdXBwb3J0lIwQcGFydGx5X3N1cHBvcnRlZJSMB3NuaXBwZXSUjBNUaGUgc291cmNlIHNheXMgc28ulIwJcmF0aW9uYWxllIwTVGhlIHBhZ2Ugc3RhdGVzIGl0LpSMBXF1b3RllE6MDW1pc3NpbmdfcXVvdGWUTowOZG9pX3JlZ2lzdGVyZWSUTowIbWV0YWRhdGGUTowUbWV0YWRhdGFfZGlmZmVyZW5jZXOUXZSMCnJlZ2lzdGVyZWSUTowQdW5jaGVja2VkX3JlYXNvbpROjARoaW50lE6MB2ZhaWx1cmWUTnVoGX2UaBuPlChoaWh8aHNoamhsaH1od2h4aAlodmh5aHVoZ2h7aG9oZWhuaHFofpBoHU51YnVoGX2UaBuPlChoTGhRaEdoXmhGaEtoTmhJaFCQaB1OdWJoQimBlH2UKGgFfZQoaEZLAWhHjB1odHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRoSYwdaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaEtOaEyMIlRoZSBhZ2VuY3kgc2FpZCBzbyBpbiBhIHN0YXRlbWVudC6UaE5dlGhQTmhRaFMpgZR9lChoBX2UKGhXjAlzdXBwb3J0ZWSUaFmMB3N1cHBvcnSUaFuJdWgZfZRoG4+UKGhXaFtoWZBoHU51YmheaGApgZR9lChoBX2UKGgJjAljb21wbGV0ZWSUaGWMBGZ1bGyUaGeMJVBhZ2UgYXQgaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaGlOaGqMAmVulGhsjB1odHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRobk5ob4wJc3VwcG9ydGVklGhxjBNUaGUgc291cmNlIHNheXMgc28ulGhzjBNUaGUgcGFnZSBzdGF0ZXMgaXQulGh1Tmh2Tmh3Tmh4Tmh5XZRoe05ofE5ofU5ofk51aBl9lGgbj5QoaGlofGhzaGpobGh9aHdoeGgJaHZoeWh1aGdoe2hvaGVobmhxaH6QaB1OdWJ1aBl9lGgbj5QoaExoUWhHaF5oRmhLaE5oSWhQkGgdTnViZWgzXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjA5tb3JlX2NpdGF0aW9uc5RdlGh+TnVoGX2UjAhsYW5ndWFnZZSMAmVulHNoG4+UKGgLaDZoD2gNaKdoCWgSaD9oM2iiaBFoB2geaKRofpBoHU51Yi4=", + "citecheck__get_completed_unchecked.json": "gASVqwgAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwJQ2l0ZWNoZWNrlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMDGNpdGVjaGVja19pZJSMCDhlYjQ5MzAylIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMCXVuY2hlY2tlZJSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjBJwb2xsX2FmdGVyX3NlY29uZHOUTowGcG9saWN5lGgAjA9DaXRlY2hlY2tQb2xpY3mUk5QpgZR9lChoBX2UjA1tYXhfY2l0YXRpb25zlEsCc4wSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGJCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwQQ2l0ZWNoZWNrU3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jaXRhdGlvbnNfZm91bmSUSwKMEmNpdGF0aW9uc19zZWxlY3RlZJRLAowOY2l0YXRpb25fbGltaXSUSwKMFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUiYwPY2l0YXRpb25fY2hlY2tzlGgAjBlSZXZpZXdDaXRhdGlvbkNoZWNrQ291bnRzlJOUKYGUfZQoaAV9lCiMB2NoZWNrZWSUSwCMCXVuY2hlY2tlZJRLAowGZmFpbGVklEsAdWgZfZRoG4+UKGguaC9oMJBoHU51YowPY2l0YXRpb25faXNzdWVzlEsAdWgZfZRoG4+UKGglaCdoM2gmaChoJJBoHU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwBzaBl9lGgbj5QoaDyQaB1OdWKMCWNpdGF0aW9uc5RdlChoAIwOUmV2aWV3Q2l0YXRpb26Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMCXJlZmVyZW5jZZSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjAljaXRlZF91cmyUjB9odHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwDZG9plE6MCXN0YXRlbWVudJSMIlVuZW1wbG95bWVudCBmZWxsIHRvIDQuMSUgaW4gMjAyNC6UjAZxdW90ZXOUXZSMCHBvc2l0aW9ulE6MBnJlc3VsdJRoAIwUUmV2aWV3Q2l0YXRpb25SZXN1bHSUk5QpgZR9lChoBX2UKIwHZmluZGluZ5SMCXVuY2hlY2tlZJSMBnNvdXJjZZROjAhpc19pc3N1ZZSJdWgZfZRoG4+UKGhXaFpoWZBoHU51YowFY2hlY2uUaACME1Jldmlld0NpdGF0aW9uQ2hlY2uUk5QpgZR9lChoBX2UKGgJjAljb21wbGV0ZWSUjAlwYWdlX3JlYWSUjARmdWxslIwKcGFnZV90aXRsZZSMJ1BhZ2UgYXQgaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSME3BhZ2VfcHVibGlzaGVkX2RhdGWUTowNcGFnZV9sYW5ndWFnZZSMAmVulIwKc291cmNlX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjA5zb3VyY2VfdmVyc2lvbpROjAdzdXBwb3J0lIwJdW5jaGVja2VklIwHc25pcHBldJROjAlyYXRpb25hbGWUjBNUaGUgcGFnZSBzdGF0ZXMgaXQulIwFcXVvdGWUTowNbWlzc2luZ19xdW90ZZROjA5kb2lfcmVnaXN0ZXJlZJROjAhtZXRhZGF0YZROjBRtZXRhZGF0YV9kaWZmZXJlbmNlc5RdlIwKcmVnaXN0ZXJlZJROjBB1bmNoZWNrZWRfcmVhc29ulIwHbm9fdGV4dJSMBGhpbnSUTowHZmFpbHVyZZROdWgZfZRoG4+UKGhoaHpocWhpaGtofGh1aHZoCWh0aHdoc2hmaHlobmhkaG1ocGh9kGgdTnVidWgZfZRoG4+UKGhMaFFoR2hdaEZoS2hOaEloUJBoHU51YmhCKYGUfZQoaAV9lChoRksBaEeMHWh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGhJjB1odHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRoS05oTIwiVGhlIGFnZW5jeSBzYWlkIHNvIGluIGEgc3RhdGVtZW50LpRoTl2UaFBOaFFoUymBlH2UKGgFfZQoaFeMCXVuY2hlY2tlZJRoWU5oWol1aBl9lGgbj5QoaFdoWmhZkGgdTnViaF1oXymBlH2UKGgFfZQoaAmMCWNvbXBsZXRlZJRoZIwEZnVsbJRoZowlUGFnZSBhdCBodHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRoaE5oaYwCZW6UaGuMHWh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGhtTmhujAl1bmNoZWNrZWSUaHBOaHGME1RoZSBwYWdlIHN0YXRlcyBpdC6UaHNOaHROaHVOaHZOaHddlGh5Tmh6jAdub190ZXh0lGh8Tmh9TnVoGX2UaBuPlChoaGh6aHFoaWhraHxodWh2aAlodGh3aHNoZmh5aG5oZGhtaHBofZBoHU51YnVoGX2UaBuPlChoTGhRaEdoXWhGaEtoTmhJaFCQaB1OdWJlaDNdlIwRY2l0YXRpb25fZmFpbHVyZXOUXZSMDm1vcmVfY2l0YXRpb25zlF2UaH1OdWgZfZSMCGxhbmd1YWdllIwCZW6Uc2gbj5QoaAtoNmgPaA1opWgJaBJoP2gzaKBoEWgHaB5oomh9kGgdTnViLg==", + "citecheck__get_failed_no_citations.json": "gASVFAQAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwJQ2l0ZWNoZWNrlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMDGNpdGVjaGVja19pZJSMCDhlYjQ5MzAylIwGc3RhdHVzlIwGZmFpbGVklIwHb3V0Y29tZZSMCXVuY2hlY2tlZJSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjBJwb2xsX2FmdGVyX3NlY29uZHOUTowGcG9saWN5lGgAjA9DaXRlY2hlY2tQb2xpY3mUk5QpgZR9lChoBX2UjA1tYXhfY2l0YXRpb25zlEsUc4wSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGJCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwQQ2l0ZWNoZWNrU3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lEsUjBZjaXRhdGlvbl9saW1pdF9yZWFjaGVklE6MD2NpdGF0aW9uX2NoZWNrc5ROjA9jaXRhdGlvbl9pc3N1ZXOUSwB1aBl9lGgbj5QoaCVoJ2gpaCZoKGgkkGgdTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAHNoGX2UaBuPlChoMpBoHU51YowJY2l0YXRpb25zlF2UaCldlIwRY2l0YXRpb25fZmFpbHVyZXOUXZSMDm1vcmVfY2l0YXRpb25zlE6MB2ZhaWx1cmWUaACMDEZhaWx1cmVCbG9ja5STlCmBlH2UKGgFfZQojA5mYWlsdXJlX3JlYXNvbpSMDG5vX2NpdGF0aW9uc5SMDWZhaWx1cmVfY2xhc3OUjA1pbnZhbGlkX2lucHV0lIwJcmV0cnlhYmxllImMBGhpbnSUjE9UaGUgdGV4dCBoYXMgbm8gY2l0YXRpb24gdG8gY2hlY2s6IG5vIGxpbmssIERPSSBvciBudW1iZXJlZCByZWZlcmVuY2Ugd2l0aCBvbmUulIwIZG9jc191cmyUjClodHRwczovL2xlbnouaW8vZG9jcy9lcnJvcnMjaW52YWxpZC1pbnB1dJR1aBl9lGgbj5QoaEZoQWhIaENoRZBoHU51YnVoGX2UjAhsYW5ndWFnZZSMAmVulHNoG4+UKGgLaCxoD2gNaE1oCWgSaDVoKWg4aBFoB2geaDpoO5BoHU51Yi4=", + "citecheck__get_failed_upstream_unavailable.json": "gASVQAwAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwJQ2l0ZWNoZWNrlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMDGNpdGVjaGVja19pZJSMCDhlYjQ5MzAylIwGc3RhdHVzlIwGZmFpbGVklIwHb3V0Y29tZZSMCXVuY2hlY2tlZJSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjBJwb2xsX2FmdGVyX3NlY29uZHOUTowGcG9saWN5lGgAjA9DaXRlY2hlY2tQb2xpY3mUk5QpgZR9lChoBX2UjA1tYXhfY2l0YXRpb25zlEsUc4wSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGJCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwQQ2l0ZWNoZWNrU3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jaXRhdGlvbnNfZm91bmSUSwKMEmNpdGF0aW9uc19zZWxlY3RlZJRLAowOY2l0YXRpb25fbGltaXSUSxSMFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUiYwPY2l0YXRpb25fY2hlY2tzlGgAjBlSZXZpZXdDaXRhdGlvbkNoZWNrQ291bnRzlJOUKYGUfZQoaAV9lCiMB2NoZWNrZWSUSwCMCXVuY2hlY2tlZJRLAIwGZmFpbGVklEsCdWgZfZRoG4+UKGguaC9oMJBoHU51YowPY2l0YXRpb25faXNzdWVzlEsAdWgZfZRoG4+UKGglaCdoM2gmaChoJJBoHU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwBzaBl9lGgbj5QoaDyQaB1OdWKMCWNpdGF0aW9uc5RdlChoAIwOUmV2aWV3Q2l0YXRpb26Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMCXJlZmVyZW5jZZSMGmEgcmVwb3J0IGZyb20gdGhlIG1pbmlzdHJ5lIwJY2l0ZWRfdXJslIwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSMA2RvaZROjAlzdGF0ZW1lbnSUTowGcXVvdGVzlF2UjAhwb3NpdGlvbpROjAZyZXN1bHSUTowFY2hlY2uUaACME1Jldmlld0NpdGF0aW9uQ2hlY2uUk5QpgZR9lChoBX2UKGgJjAZmYWlsZWSUjAlwYWdlX3JlYWSUTowKcGFnZV90aXRsZZROjBNwYWdlX3B1Ymxpc2hlZF9kYXRllE6MDXBhZ2VfbGFuZ3VhZ2WUTowKc291cmNlX3VybJROjA5zb3VyY2VfdmVyc2lvbpROjAdzdXBwb3J0lE6MB3NuaXBwZXSUTowJcmF0aW9uYWxllE6MBXF1b3RllE6MDW1pc3NpbmdfcXVvdGWUTowOZG9pX3JlZ2lzdGVyZWSUTowIbWV0YWRhdGGUTowUbWV0YWRhdGFfZGlmZmVyZW5jZXOUXZSMCnJlZ2lzdGVyZWSUTowQdW5jaGVja2VkX3JlYXNvbpROjARoaW50lIw7TGVueiBjb3VsZCBub3QgcmVhY2ggdGhpcyBzb3VyY2UganVzdCBub3cuIFRyeSBhZ2FpbiBsYXRlci6UjAdmYWlsdXJllGgAjAxGYWlsdXJlQmxvY2uUk5QpgZR9lChoBX2UKIwOZmFpbHVyZV9yZWFzb26UjBR1cHN0cmVhbV91bmF2YWlsYWJsZZSMDWZhaWx1cmVfY2xhc3OUjBR1cHN0cmVhbV91bmF2YWlsYWJsZZSMCXJldHJ5YWJsZZSIaGmMO0xlbnogY291bGQgbm90IHJlYWNoIHRoaXMgc291cmNlIGp1c3Qgbm93LiBUcnkgYWdhaW4gbGF0ZXIulIwIZG9jc191cmyUjDBodHRwczovL2xlbnouaW8vZG9jcy9lcnJvcnMjdXBzdHJlYW0tdW5hdmFpbGFibGWUdWgZfZRoG4+UKGhpaHFod2hzaHWQaB1OdWJ1aBl9lGgbj5QoaFpoaGhgaFtoXGhpaGNoZGgJaGJoZWhhaFloZ2heaFhoXWhfaGuQaB1OdWJ1aBl9lGgbj5QoaExoUGhHaFFoRmhLaE1oSWhPkGgdTnViaEIpgZR9lChoBX2UKGhGSwFoR4wLYSBzdGF0ZW1lbnSUaEmMHWh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGhLTmhMTmhNXZRoT05oUE5oUWhTKYGUfZQoaAV9lChoCYwGZmFpbGVklGhYTmhZTmhaTmhbTmhcTmhdTmheTmhfTmhgTmhhTmhiTmhjTmhkTmhlXZRoZ05oaE5oaYw7TGVueiBjb3VsZCBub3QgcmVhY2ggdGhpcyBzb3VyY2UganVzdCBub3cuIFRyeSBhZ2FpbiBsYXRlci6UaGtobSmBlH2UKGgFfZQoaHGMFHVwc3RyZWFtX3VuYXZhaWxhYmxllGhzjBR1cHN0cmVhbV91bmF2YWlsYWJsZZRodYhoaYw7TGVueiBjb3VsZCBub3QgcmVhY2ggdGhpcyBzb3VyY2UganVzdCBub3cuIFRyeSBhZ2FpbiBsYXRlci6UaHeMMGh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyN1cHN0cmVhbS11bmF2YWlsYWJsZZR1aBl9lGgbj5QoaGlocWh3aHNodZBoHU51YnVoGX2UaBuPlChoWmhoaGBoW2hcaGloY2hkaAloYmhlaGFoWWhnaF5oWGhdaF9oa5BoHU51YnVoGX2UaBuPlChoTGhQaEdoUWhGaEtoTWhJaE+QaB1OdWJlaDNdlIwRY2l0YXRpb25fZmFpbHVyZXOUXZQoaACMFVJldmlld0NpdGF0aW9uRmFpbHVyZZSTlCmBlH2UKGgFfZQojA5jaXRhdGlvbl9pbmRleJRLAGhHjBphIHJlcG9ydCBmcm9tIHRoZSBtaW5pc3RyeZRoSYwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJRoS05oa2htKYGUfZQoaAV9lChocYwUdXBzdHJlYW1fdW5hdmFpbGFibGWUaHOMFHVwc3RyZWFtX3VuYXZhaWxhYmxllGh1iGhpjDtMZW56IGNvdWxkIG5vdCByZWFjaCB0aGlzIHNvdXJjZSBqdXN0IG5vdy4gVHJ5IGFnYWluIGxhdGVyLpRod4wwaHR0cHM6Ly9sZW56LmlvL2RvY3MvZXJyb3JzI3Vwc3RyZWFtLXVuYXZhaWxhYmxllHVoGX2UaBuPlChoaWhxaHdoc2h1kGgdTnVidWgZfZRoG4+UKGhHaEtooGhJaGuQaB1OdWJonCmBlH2UKGgFfZQoaKBLAWhHjAthIHN0YXRlbWVudJRoSYwdaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaEtOaGtobSmBlH2UKGgFfZQoaHGMFHVwc3RyZWFtX3VuYXZhaWxhYmxllGhzjBR1cHN0cmVhbV91bmF2YWlsYWJsZZRodYhoaYw7TGVueiBjb3VsZCBub3QgcmVhY2ggdGhpcyBzb3VyY2UganVzdCBub3cuIFRyeSBhZ2FpbiBsYXRlci6UaHeMMGh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyN1cHN0cmVhbS11bmF2YWlsYWJsZZR1aBl9lGgbj5QoaGlocWh3aHNodZBoHU51YnVoGX2UaBuPlChoR2hLaKBoSWhrkGgdTnViZYwObW9yZV9jaXRhdGlvbnOUXZRoa2htKYGUfZQoaAV9lChocYwUdXBzdHJlYW1fdW5hdmFpbGFibGWUaHOMFHVwc3RyZWFtX3VuYXZhaWxhYmxllGh1iGhpTmh3jDBodHRwczovL2xlbnouaW8vZG9jcy9lcnJvcnMjdXBzdHJlYW0tdW5hdmFpbGFibGWUdWgZfZRoG4+UKGhpaHFod2hzaHWQaB1OdWJ1aBl9lIwIbGFuZ3VhZ2WUjAJlbpRzaBuPlChoC2g2aA9oDWjJaAloEmg/aDNomWgRaAdoHmi+aGuQaB1OdWIu", + "citecheck__get_queued.json": "gASVtgUAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwJQ2l0ZWNoZWNrlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMDGNpdGVjaGVja19pZJSMCDhlYjQ5MzAylIwGc3RhdHVzlIwGcXVldWVklIwHb3V0Y29tZZROjApjcmVhdGVkX2F0lIwbMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTZalIwMY29tcGxldGVkX2F0lE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5RLCowGcG9saWN5lGgAjA9DaXRlY2hlY2tQb2xpY3mUk5QpgZR9lChoBX2UjA1tYXhfY2l0YXRpb25zlEsBc4wSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoFpCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwQQ2l0ZWNoZWNrU3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jaXRhdGlvbnNfZm91bmSUSwGMEmNpdGF0aW9uc19zZWxlY3RlZJRLAYwOY2l0YXRpb25fbGltaXSUSwGMFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUiYwPY2l0YXRpb25fY2hlY2tzlGgAjBlSZXZpZXdDaXRhdGlvbkNoZWNrQ291bnRzlJOUKYGUfZQoaAV9lCiMB2NoZWNrZWSUSwCMCXVuY2hlY2tlZJRLAIwGZmFpbGVklEsAdWgXfZRoGY+UKGgsaC1oLpBoG051YowPY2l0YXRpb25faXNzdWVzlEsAdWgXfZRoGY+UKGgjaCVoMWgkaCZoIpBoG051YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwBzaBd9lGgZj5QoaDqQaBtOdWKMCWNpdGF0aW9uc5RdlGgAjA5SZXZpZXdDaXRhdGlvbpSTlCmBlH2UKGgFfZQojAVpbmRleJRLAIwJcmVmZXJlbmNllIwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSMCWNpdGVkX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjANkb2mUTowJc3RhdGVtZW50lIwiVW5lbXBsb3ltZW50IGZlbGwgdG8gNC4xJSBpbiAyMDI0LpSMBnF1b3Rlc5RdlIwIcG9zaXRpb26UTowGcmVzdWx0lE6MBWNoZWNrlGgAjBNSZXZpZXdDaXRhdGlvbkNoZWNrlJOUKYGUfZQoaAV9lChoCYwHcGVuZGluZ5SMCXBhZ2VfcmVhZJROjApwYWdlX3RpdGxllE6ME3BhZ2VfcHVibGlzaGVkX2RhdGWUTowNcGFnZV9sYW5ndWFnZZROjApzb3VyY2VfdXJslE6MDnNvdXJjZV92ZXJzaW9ulE6MB3N1cHBvcnSUTowHc25pcHBldJROjAlyYXRpb25hbGWUTowFcXVvdGWUTowNbWlzc2luZ19xdW90ZZROjA5kb2lfcmVnaXN0ZXJlZJROjAhtZXRhZGF0YZROjBRtZXRhZGF0YV9kaWZmZXJlbmNlc5RdlIwKcmVnaXN0ZXJlZJROjBB1bmNoZWNrZWRfcmVhc29ulE6MBGhpbnSUTowHZmFpbHVyZZROdWgXfZRoGY+UKGhZaGdoX2haaFtoaGhiaGNoCWhhaGRoYGhYaGZoXWhXaFxoXmhpkGgbTnVidWgXfZRoGY+UKGhKaE9oRWhQaERoSWhMaEdoTpBoG051YmFoMV2UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwObW9yZV9jaXRhdGlvbnOUXZRoaU51aBd9lIwIbGFuZ3VhZ2WUjAJlbpRzaBmPlChoC2g0aA5oDGh0aAloEGg9aDFob2gPaAdoHGhxaGmQaBtOdWIu", + "citecheck__get_text_limit_exactly_at_limit.json": "gASVWQkAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwJQ2l0ZWNoZWNrlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMDGNpdGVjaGVja19pZJSMCDhlYjQ5MzAylIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROjAZwb2xpY3mUaACMD0NpdGVjaGVja1BvbGljeZSTlCmBlH2UKGgFfZSMDW1heF9jaXRhdGlvbnOUSwJzjBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgYkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAdzdW1tYXJ5lGgAjBBDaXRlY2hlY2tTdW1tYXJ5lJOUKYGUfZQoaAV9lCiMD2NpdGF0aW9uc19mb3VuZJRLAowSY2l0YXRpb25zX3NlbGVjdGVklEsCjA5jaXRhdGlvbl9saW1pdJRLAowWY2l0YXRpb25fbGltaXRfcmVhY2hlZJSJjA9jaXRhdGlvbl9jaGVja3OUaACMGVJldmlld0NpdGF0aW9uQ2hlY2tDb3VudHOUk5QpgZR9lChoBX2UKIwHY2hlY2tlZJRLAowJdW5jaGVja2VklEsAjAZmYWlsZWSUSwB1aBl9lGgbj5QoaC5oL2gwkGgdTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwB1aBl9lGgbj5QoaCVoJ2gzaCZoKGgkkGgdTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAnNoGX2UaBuPlChoPJBoHU51YowJY2l0YXRpb25zlF2UKGgAjA5SZXZpZXdDaXRhdGlvbpSTlCmBlH2UKGgFfZQojAVpbmRleJRLAIwJcmVmZXJlbmNllIwaYSByZXBvcnQgZnJvbSB0aGUgbWluaXN0cnmUjAljaXRlZF91cmyUjB9odHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwDZG9plE6MCXN0YXRlbWVudJSMS1VuZW1wbG95bWVudCBmZWxsIHRvIDQuMSUgaW4gMjAyNCwgYWNjb3JkaW5nIHRvIGEgcmVwb3J0IGZyb20gdGhlIG1pbmlzdHJ5LpSMBnF1b3Rlc5RdlIwIcG9zaXRpb26UaACMCFBvc2l0aW9ulJOUKYGUfZQoaAV9lCiMBXN0YXJ0lEsAjANlbmSUS26MBHRleHSUTnVoGX2UaBuPlChoVmhXaFiQaB1OdWKMBnJlc3VsdJRoAIwUUmV2aWV3Q2l0YXRpb25SZXN1bHSUk5QpgZR9lChoBX2UKIwHZmluZGluZ5SMCXN1cHBvcnRlZJSMBnNvdXJjZZSMB3N1cHBvcnSUjAhpc19pc3N1ZZSJdWgZfZRoG4+UKGhhaGVoY5BoHU51YowFY2hlY2uUaACME1Jldmlld0NpdGF0aW9uQ2hlY2uUk5QpgZR9lChoBX2UKGgJjAljb21wbGV0ZWSUjAlwYWdlX3JlYWSUjARmdWxslIwKcGFnZV90aXRsZZSMJ1BhZ2UgYXQgaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSME3BhZ2VfcHVibGlzaGVkX2RhdGWUTowNcGFnZV9sYW5ndWFnZZSMAmVulIwKc291cmNlX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjA5zb3VyY2VfdmVyc2lvbpROjAdzdXBwb3J0lIwJc3VwcG9ydGVklIwHc25pcHBldJSME1RoZSBzb3VyY2Ugc2F5cyBzby6UjAlyYXRpb25hbGWUjBNUaGUgcGFnZSBzdGF0ZXMgaXQulIwFcXVvdGWUTowNbWlzc2luZ19xdW90ZZROjA5kb2lfcmVnaXN0ZXJlZJROjAhtZXRhZGF0YZROjBRtZXRhZGF0YV9kaWZmZXJlbmNlc5RdlIwKcmVnaXN0ZXJlZJROjBB1bmNoZWNrZWRfcmVhc29ulE6MBGhpbnSUTowHZmFpbHVyZZROdWgZfZRoG4+UKGhzaIZofWh0aHZoh2iBaIJoCWiAaINof2hxaIVoeWhvaHhoe2iIkGgdTnVidWgZfZRoG4+UKGhMaFtoR2hoaEZoS2hOaEloUJBoHU51YmhCKYGUfZQoaAV9lChoRksBaEeMC2Egc3RhdGVtZW50lGhJjB1odHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRoS05oTIwiVGhlIGFnZW5jeSBzYWlkIHNvIGluIGEgc3RhdGVtZW50LpRoTl2UaFBoUimBlH2UKGgFfZQoaFZLb2hXS7JoWE51aBl9lGgbj5QoaFZoV2hYkGgdTnViaFtoXSmBlH2UKGgFfZQoaGGMCXN1cHBvcnRlZJRoY4wHc3VwcG9ydJRoZYl1aBl9lGgbj5QoaGFoZWhjkGgdTnViaGhoaimBlH2UKGgFfZQoaAmMCWNvbXBsZXRlZJRob4wEZnVsbJRocYwlUGFnZSBhdCBodHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRoc05odIwCZW6UaHaMHWh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGh4Tmh5jAlzdXBwb3J0ZWSUaHuME1RoZSBzb3VyY2Ugc2F5cyBzby6UaH2ME1RoZSBwYWdlIHN0YXRlcyBpdC6UaH9OaIBOaIFOaIJOaINdlGiFTmiGTmiHTmiITnVoGX2UaBuPlChoc2iGaH1odGh2aIdogWiCaAlogGiDaH9ocWiFaHlob2h4aHtoiJBoHU51YnVoGX2UaBuPlChoTGhbaEdoaGhGaEtoTmhJaFCQaB1OdWJlaDNdlIwRY2l0YXRpb25fZmFpbHVyZXOUXZSMDm1vcmVfY2l0YXRpb25zlF2UaIhOdWgZfZSMCGxhbmd1YWdllIwCZW6Uc2gbj5QoaAtoNmgPaA1otmgJaBJoP2gzaLFoEWgHaB5os2iIkGgdTnViLg==", + "citecheck__get_text_limit_reached.json": "gASVHggAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwJQ2l0ZWNoZWNrlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMDGNpdGVjaGVja19pZJSMCDhlYjQ5MzAylIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROjAZwb2xpY3mUaACMD0NpdGVjaGVja1BvbGljeZSTlCmBlH2UKGgFfZSMDW1heF9jaXRhdGlvbnOUSwFzjBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgYkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAdzdW1tYXJ5lGgAjBBDaXRlY2hlY2tTdW1tYXJ5lJOUKYGUfZQoaAV9lCiMD2NpdGF0aW9uc19mb3VuZJRLAowSY2l0YXRpb25zX3NlbGVjdGVklEsBjA5jaXRhdGlvbl9saW1pdJRLAYwWY2l0YXRpb25fbGltaXRfcmVhY2hlZJSIjA9jaXRhdGlvbl9jaGVja3OUaACMGVJldmlld0NpdGF0aW9uQ2hlY2tDb3VudHOUk5QpgZR9lChoBX2UKIwHY2hlY2tlZJRLAYwJdW5jaGVja2VklEsAjAZmYWlsZWSUSwB1aBl9lGgbj5QoaC5oL2gwkGgdTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwB1aBl9lGgbj5QoaCVoJ2gzaCZoKGgkkGgdTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAXNoGX2UaBuPlChoPJBoHU51YowJY2l0YXRpb25zlF2UaACMDlJldmlld0NpdGF0aW9ulJOUKYGUfZQoaAV9lCiMBWluZGV4lEsAjAlyZWZlcmVuY2WUjBphIHJlcG9ydCBmcm9tIHRoZSBtaW5pc3RyeZSMCWNpdGVkX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjANkb2mUTowJc3RhdGVtZW50lIxLVW5lbXBsb3ltZW50IGZlbGwgdG8gNC4xJSBpbiAyMDI0LCBhY2NvcmRpbmcgdG8gYSByZXBvcnQgZnJvbSB0aGUgbWluaXN0cnkulIwGcXVvdGVzlF2UjAhwb3NpdGlvbpRoAIwIUG9zaXRpb26Uk5QpgZR9lChoBX2UKIwFc3RhcnSUSwCMA2VuZJRLbowEdGV4dJROdWgZfZRoG4+UKGhWaFdoWJBoHU51YowGcmVzdWx0lGgAjBRSZXZpZXdDaXRhdGlvblJlc3VsdJSTlCmBlH2UKGgFfZQojAdmaW5kaW5nlIwJc3VwcG9ydGVklIwGc291cmNllIwHc3VwcG9ydJSMCGlzX2lzc3VllIl1aBl9lGgbj5QoaGFoZWhjkGgdTnVijAVjaGVja5RoAIwTUmV2aWV3Q2l0YXRpb25DaGVja5STlCmBlH2UKGgFfZQoaAmMCWNvbXBsZXRlZJSMCXBhZ2VfcmVhZJSMBGZ1bGyUjApwYWdlX3RpdGxllIwnUGFnZSBhdCBodHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwTcGFnZV9wdWJsaXNoZWRfZGF0ZZROjA1wYWdlX2xhbmd1YWdllIwCZW6UjApzb3VyY2VfdXJslIwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSMDnNvdXJjZV92ZXJzaW9ulE6MB3N1cHBvcnSUjAlzdXBwb3J0ZWSUjAdzbmlwcGV0lIwTVGhlIHNvdXJjZSBzYXlzIHNvLpSMCXJhdGlvbmFsZZSME1RoZSBwYWdlIHN0YXRlcyBpdC6UjAVxdW90ZZROjA1taXNzaW5nX3F1b3RllE6MDmRvaV9yZWdpc3RlcmVklE6MCG1ldGFkYXRhlE6MFG1ldGFkYXRhX2RpZmZlcmVuY2VzlF2UjApyZWdpc3RlcmVklE6MEHVuY2hlY2tlZF9yZWFzb26UTowEaGludJROjAdmYWlsdXJllE51aBl9lGgbj5QoaHNohmh9aHRodmiHaIFogmgJaIBog2h/aHFohWh5aG9oeGh7aIiQaB1OdWJ1aBl9lGgbj5QoaExoW2hHaGhoRmhLaE5oSWhQkGgdTnViYWgzXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjA5tb3JlX2NpdGF0aW9uc5RdlGgAjBJSZXZpZXdNb3JlQ2l0YXRpb26Uk5QpgZR9lChoBX2UKGhGSwFoR4wLYSBzdGF0ZW1lbnSUaEmMHWh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGhLTowIc2VudGVuY2WUjCJUaGUgYWdlbmN5IHNhaWQgc28gaW4gYSBzdGF0ZW1lbnQulGhQaFIpgZR9lChoBX2UKGhWS29oV0uyaFhOdWgZfZRoG4+UKGhWaFdoWJBoHU51YnVoGX2UaBuPlChoR2iZaEZoS2hJaFCQaB1OdWJhaIhOdWgZfZSMCGxhbmd1YWdllIwCZW6Uc2gbj5QoaAtoNmgPaA1oo2gJaBJoP2gzaI5oEWgHaB5okGiIkGgdTnViLg==", + "citecheck__idempotent_replay_202.json": "gASVuwAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwQQ2l0ZWNoZWNrU3RhcnRlZJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAxjaXRlY2hlY2tfaWSUjAg4ZWI0OTMwMpSMBnN0YXR1c5SMBnF1ZXVlZJR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgHaAmQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWIu", + "citecheck__receipt_202.json": "gASVuwAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwQQ2l0ZWNoZWNrU3RhcnRlZJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAxjaXRlY2hlY2tfaWSUjAg4ZWI0OTMwMpSMBnN0YXR1c5SMBnF1ZXVlZJR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgHaAmQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWIu", + "citecheck__receipt_202_empty_webhook_url.json": "gASVuwAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwQQ2l0ZWNoZWNrU3RhcnRlZJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAxjaXRlY2hlY2tfaWSUjAg4ZWI0OTMwMpSMBnN0YXR1c5SMBnF1ZXVlZJR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgHaAmQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWIu", + "extract__focus_ready.json": "gASVMgIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMBXJlYWR5lIwFY2xhaW2UjBdCZXRhIGZlbGwgMyUgbGFzdCB5ZWFyLpSMEWlkZW50aWZpZWRfY2xhaW1zlF2UjBBjYW5kaWRhdGVfY2xhaW1zlF2UjAZkb21haW6UjAlFY29ub21pY3OUjAxrZXlfZW50aXRpZXOUXZQoaACMD0V4dHJhY3RlZEVudGl0eZSTlCmBlH2UKGgFfZQojARuYW1llIwFQWxwaGGUjAR0eXBllIwMb3JnYW5pemF0aW9ulHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBhoGpCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmgUKYGUfZQoaAV9lChoGIwEQmV0YZRoGowMb3JnYW5pemF0aW9ulHVoHH2UaB6PlChoGGgakGggTnViZYwPcHJlc3VtZWRfaW50ZW50lIwXVmVyaWZ5IHJlcG9ydGVkIGZpZ3VyZXOUjA5vcmlnaW5hbF9pbnB1dJSMLkFscGhhIHJvc2UgNSUgaW4gMjAyNC4gQmV0YSBmZWxsIDMlIGxhc3QgeWVhci6UjAlsb2NhdGlvbnOUTnVoHH2UaB6PlChoEWgJaA1oC2gHaA9oLGgqaCiQaCBOdWIu", + "extract__idempotency_replay.json": "gASVZgIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMBXJlYWR5lIwFY2xhaW2UjBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwRaWRlbnRpZmllZF9jbGFpbXOUXZQojBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwXQmV0YSBmZWxsIDMlIGxhc3QgeWVhci6UZYwQY2FuZGlkYXRlX2NsYWltc5RdlIwGZG9tYWlulIwJRWNvbm9taWNzlIwMa2V5X2VudGl0aWVzlF2UKGgAjA9FeHRyYWN0ZWRFbnRpdHmUk5QpgZR9lChoBX2UKIwEbmFtZZSMBUFscGhhlIwEdHlwZZSMDG9yZ2FuaXphdGlvbpR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgaaByQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWJoFimBlH2UKGgFfZQoaBqMBEJldGGUaByMDG9yZ2FuaXphdGlvbpR1aB59lGggj5QoaBpoHJBoIk51YmWMD3ByZXN1bWVkX2ludGVudJSMF1ZlcmlmeSByZXBvcnRlZCBmaWd1cmVzlIwOb3JpZ2luYWxfaW5wdXSUjC5BbHBoYSByb3NlIDUlIGluIDIwMjQuIEJldGEgZmVsbCAzJSBsYXN0IHllYXIulIwJbG9jYXRpb25zlE51aB59lGggj5QoaBNoCWgPaAtoB2gRaC5oLGgqkGgiTnViLg==", + "extract__locate_all_dropped.json": "gASVGAIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMC25vdF9hX2NsYWltlIwFY2xhaW2UjACUjBFpZGVudGlmaWVkX2NsYWltc5RdlIwQY2FuZGlkYXRlX2NsYWltc5RdlIwGZG9tYWlulGgKjAxrZXlfZW50aXRpZXOUXZQoaACMD0V4dHJhY3RlZEVudGl0eZSTlCmBlH2UKGgFfZQojARuYW1llIwFQWxwaGGUjAR0eXBllIwMb3JnYW5pemF0aW9ulHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBdoGZCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmgTKYGUfZQoaAV9lChoF4wEQmV0YZRoGYwMb3JnYW5pemF0aW9ulHVoG32UaB2PlChoF2gZkGgfTnViZYwPcHJlc3VtZWRfaW50ZW50lIwXVmVyaWZ5IHJlcG9ydGVkIGZpZ3VyZXOUjA5vcmlnaW5hbF9pbnB1dJSMLkFscGhhIHJvc2UgNSUgaW4gMjAyNC4gQmV0YSBmZWxsIDMlIGxhc3QgeWVhci6UjAlsb2NhdGlvbnOUXZR1aBt9lGgdj5QoaBBoCWgNaAtoB2gPaCtoKWgnkGgfTnViLg==", + "extract__locate_failed.json": "gASVZgIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMBXJlYWR5lIwFY2xhaW2UjBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwRaWRlbnRpZmllZF9jbGFpbXOUXZQojBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwXQmV0YSBmZWxsIDMlIGxhc3QgeWVhci6UZYwQY2FuZGlkYXRlX2NsYWltc5RdlIwGZG9tYWlulIwJRWNvbm9taWNzlIwMa2V5X2VudGl0aWVzlF2UKGgAjA9FeHRyYWN0ZWRFbnRpdHmUk5QpgZR9lChoBX2UKIwEbmFtZZSMBUFscGhhlIwEdHlwZZSMDG9yZ2FuaXphdGlvbpR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgaaByQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWJoFimBlH2UKGgFfZQoaBqMBEJldGGUaByMDG9yZ2FuaXphdGlvbpR1aB59lGggj5QoaBpoHJBoIk51YmWMD3ByZXN1bWVkX2ludGVudJSMF1ZlcmlmeSByZXBvcnRlZCBmaWd1cmVzlIwOb3JpZ2luYWxfaW5wdXSUjC5BbHBoYSByb3NlIDUlIGluIDIwMjQuIEJldGEgZmVsbCAzJSBsYXN0IHllYXIulIwJbG9jYXRpb25zlE51aB59lGggj5QoaBNoCWgPaAtoB2gRaC5oLGgqkGgiTnViLg==", + "extract__locate_leading_whitespace.json": "gASV8gIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMBXJlYWR5lIwFY2xhaW2UjBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwRaWRlbnRpZmllZF9jbGFpbXOUXZSMEGNhbmRpZGF0ZV9jbGFpbXOUXZSMBmRvbWFpbpSMCUVjb25vbWljc5SMDGtleV9lbnRpdGllc5RdlChoAIwPRXh0cmFjdGVkRW50aXR5lJOUKYGUfZQoaAV9lCiMBG5hbWWUjAVBbHBoYZSMBHR5cGWUjAxvcmdhbml6YXRpb26UdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGGgakIwUX19weWRhbnRpY19wcml2YXRlX1+UTnViaBQpgZR9lChoBX2UKGgYjARCZXRhlGgajAxvcmdhbml6YXRpb26UdWgcfZRoHo+UKGgYaBqQaCBOdWJljA9wcmVzdW1lZF9pbnRlbnSUjBdWZXJpZnkgcmVwb3J0ZWQgZmlndXJlc5SMDm9yaWdpbmFsX2lucHV0lIwuQWxwaGEgcm9zZSA1JSBpbiAyMDI0LiBCZXRhIGZlbGwgMyUgbGFzdCB5ZWFyLpSMCWxvY2F0aW9uc5RdlGgAjA1DbGFpbUxvY2F0aW9ulJOUKYGUfZQoaAV9lChoCYwWQWxwaGEgcm9zZSA1JSBpbiAyMDI0LpSMCXBvc2l0aW9uc5RdlGgAjAhQb3NpdGlvbpSTlCmBlH2UKGgFfZQojAVzdGFydJRLA4wDZW5klEsZjAR0ZXh0lIwWQWxwaGEgcm9zZSA1JSBpbiAyMDI0LpR1aBx9lGgej5QoaDtoPGg9kGggTnViYXVoHH2UaB6PlChoCWg0kGggTnViYXVoHH2UaB6PlChoEWgJaA1oC2gHaA9oLGgqaCiQaCBOdWIu", + "extract__locate_some_dropped.json": "gASVsQMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMBXJlYWR5lIwFY2xhaW2UjBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwRaWRlbnRpZmllZF9jbGFpbXOUXZQojBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwXQmV0YSBmZWxsIDMlIGxhc3QgeWVhci6UZYwQY2FuZGlkYXRlX2NsYWltc5RdlIwGZG9tYWlulIwJRWNvbm9taWNzlIwMa2V5X2VudGl0aWVzlF2UKGgAjA9FeHRyYWN0ZWRFbnRpdHmUk5QpgZR9lChoBX2UKIwEbmFtZZSMBUFscGhhlIwEdHlwZZSMDG9yZ2FuaXphdGlvbpR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgaaByQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWJoFimBlH2UKGgFfZQoaBqMBEJldGGUaByMDG9yZ2FuaXphdGlvbpR1aB59lGggj5QoaBpoHJBoIk51YmWMD3ByZXN1bWVkX2ludGVudJSMF1ZlcmlmeSByZXBvcnRlZCBmaWd1cmVzlIwOb3JpZ2luYWxfaW5wdXSUjC5BbHBoYSByb3NlIDUlIGluIDIwMjQuIEJldGEgZmVsbCAzJSBsYXN0IHllYXIulIwJbG9jYXRpb25zlF2UKGgAjA1DbGFpbUxvY2F0aW9ulJOUKYGUfZQoaAV9lChoCYwWQWxwaGEgcm9zZSA1JSBpbiAyMDI0LpSMCXBvc2l0aW9uc5RdlGgAjAhQb3NpdGlvbpSTlCmBlH2UKGgFfZQojAVzdGFydJRLAIwDZW5klEsWjAR0ZXh0lIwWQWxwaGEgcm9zZSA1JSBpbiAyMDI0LpR1aB59lGggj5QoaD1oPmg/kGgiTnViYXVoHn2UaCCPlChoCWg2kGgiTnViaDEpgZR9lChoBX2UKGgJjBdCZXRhIGZlbGwgMyUgbGFzdCB5ZWFyLpRoNl2UaDkpgZR9lChoBX2UKGg9SxdoPksuaD+MF0JldGEgZmVsbCAzJSBsYXN0IHllYXIulHVoHn2UaCCPlChoPWg+aD+QaCJOdWJhdWgefZRoII+UKGgJaDaQaCJOdWJldWgefZRoII+UKGgTaAloD2gLaAdoEWguaCxoKpBoIk51Yi4=", + "extract__locate_true.json": "gASVsQMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMBXJlYWR5lIwFY2xhaW2UjBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwRaWRlbnRpZmllZF9jbGFpbXOUXZQojBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwXQmV0YSBmZWxsIDMlIGxhc3QgeWVhci6UZYwQY2FuZGlkYXRlX2NsYWltc5RdlIwGZG9tYWlulIwJRWNvbm9taWNzlIwMa2V5X2VudGl0aWVzlF2UKGgAjA9FeHRyYWN0ZWRFbnRpdHmUk5QpgZR9lChoBX2UKIwEbmFtZZSMBUFscGhhlIwEdHlwZZSMDG9yZ2FuaXphdGlvbpR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgaaByQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWJoFimBlH2UKGgFfZQoaBqMBEJldGGUaByMDG9yZ2FuaXphdGlvbpR1aB59lGggj5QoaBpoHJBoIk51YmWMD3ByZXN1bWVkX2ludGVudJSMF1ZlcmlmeSByZXBvcnRlZCBmaWd1cmVzlIwOb3JpZ2luYWxfaW5wdXSUjC5BbHBoYSByb3NlIDUlIGluIDIwMjQuIEJldGEgZmVsbCAzJSBsYXN0IHllYXIulIwJbG9jYXRpb25zlF2UKGgAjA1DbGFpbUxvY2F0aW9ulJOUKYGUfZQoaAV9lChoCYwWQWxwaGEgcm9zZSA1JSBpbiAyMDI0LpSMCXBvc2l0aW9uc5RdlGgAjAhQb3NpdGlvbpSTlCmBlH2UKGgFfZQojAVzdGFydJRLAIwDZW5klEsWjAR0ZXh0lIwWQWxwaGEgcm9zZSA1JSBpbiAyMDI0LpR1aB59lGggj5QoaD1oPmg/kGgiTnViYXVoHn2UaCCPlChoCWg2kGgiTnViaDEpgZR9lChoBX2UKGgJjBdCZXRhIGZlbGwgMyUgbGFzdCB5ZWFyLpRoNl2UaDkpgZR9lChoBX2UKGg9SxdoPksuaD+MF0JldGEgZmVsbCAzJSBsYXN0IHllYXIulHVoHn2UaCCPlChoPWg+aD+QaCJOdWJhdWgefZRoII+UKGgJaDaQaCJOdWJldWgefZRoII+UKGgTaAloD2gLaAdoEWguaCxoKpBoIk51Yi4=", + "extract__no_match_with_focus.json": "gASVZQEAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMCG5vX21hdGNolIwFY2xhaW2UjACUjBFpZGVudGlmaWVkX2NsYWltc5RdlIwQY2FuZGlkYXRlX2NsYWltc5RdlIwGZG9tYWlulGgKjAxrZXlfZW50aXRpZXOUXZSMD3ByZXN1bWVkX2ludGVudJRoCowOb3JpZ2luYWxfaW5wdXSUjC5BbHBoYSByb3NlIDUlIGluIDIwMjQuIEJldGEgZmVsbCAzJSBsYXN0IHllYXIulIwJbG9jYXRpb25zlE51jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgQaAloDWgLaAdoD2gVaBNoEpCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51Yi4=", + "extract__not_a_claim.json": "gASVTAEAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMC25vdF9hX2NsYWltlIwFY2xhaW2UjACUjBFpZGVudGlmaWVkX2NsYWltc5RdlIwQY2FuZGlkYXRlX2NsYWltc5RdlIwGZG9tYWlulGgKjAxrZXlfZW50aXRpZXOUXZSMD3ByZXN1bWVkX2ludGVudJRoCowOb3JpZ2luYWxfaW5wdXSUjBJXaGF0IGEgbG92ZWx5IGRheS6UjAlsb2NhdGlvbnOUTnWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBBoCWgNaAtoB2gPaBVoE2gSkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnViLg==", + "extract__not_a_claim_beside_claims.json": "gASVHwIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMC25vdF9hX2NsYWltlIwFY2xhaW2UjBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwRaWRlbnRpZmllZF9jbGFpbXOUXZSMEGNhbmRpZGF0ZV9jbGFpbXOUXZSMBmRvbWFpbpSMCUVjb25vbWljc5SMDGtleV9lbnRpdGllc5RdlChoAIwPRXh0cmFjdGVkRW50aXR5lJOUKYGUfZQoaAV9lCiMBG5hbWWUjAVBbHBoYZSMBHR5cGWUjAxvcmdhbml6YXRpb26UdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGGgakIwUX19weWRhbnRpY19wcml2YXRlX1+UTnViaBQpgZR9lChoBX2UKGgYjARCZXRhlGgajAxvcmdhbml6YXRpb26UdWgcfZRoHo+UKGgYaBqQaCBOdWJljA9wcmVzdW1lZF9pbnRlbnSUjBdWZXJpZnkgcmVwb3J0ZWQgZmlndXJlc5SMDm9yaWdpbmFsX2lucHV0lIwWQWxwaGEgcm9zZSA1JSBpbiAyMDI0LpSMCWxvY2F0aW9uc5ROdWgcfZRoHo+UKGgRaAloDWgLaAdoD2gsaCpoKJBoIE51Yi4=", + "extract__ready_one_claim.json": "gASVGQIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMBXJlYWR5lIwFY2xhaW2UjBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwRaWRlbnRpZmllZF9jbGFpbXOUXZSMEGNhbmRpZGF0ZV9jbGFpbXOUXZSMBmRvbWFpbpSMCUVjb25vbWljc5SMDGtleV9lbnRpdGllc5RdlChoAIwPRXh0cmFjdGVkRW50aXR5lJOUKYGUfZQoaAV9lCiMBG5hbWWUjAVBbHBoYZSMBHR5cGWUjAxvcmdhbml6YXRpb26UdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGGgakIwUX19weWRhbnRpY19wcml2YXRlX1+UTnViaBQpgZR9lChoBX2UKGgYjARCZXRhlGgajAxvcmdhbml6YXRpb26UdWgcfZRoHo+UKGgYaBqQaCBOdWJljA9wcmVzdW1lZF9pbnRlbnSUjBdWZXJpZnkgcmVwb3J0ZWQgZmlndXJlc5SMDm9yaWdpbmFsX2lucHV0lIwWQWxwaGEgcm9zZSA1JSBpbiAyMDI0LpSMCWxvY2F0aW9uc5ROdWgcfZRoHo+UKGgRaAloDWgLaAdoD2gsaCpoKJBoIE51Yi4=", + "extract__ready_several_claims.json": "gASVZgIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMBXJlYWR5lIwFY2xhaW2UjBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwRaWRlbnRpZmllZF9jbGFpbXOUXZQojBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwXQmV0YSBmZWxsIDMlIGxhc3QgeWVhci6UZYwQY2FuZGlkYXRlX2NsYWltc5RdlIwGZG9tYWlulIwJRWNvbm9taWNzlIwMa2V5X2VudGl0aWVzlF2UKGgAjA9FeHRyYWN0ZWRFbnRpdHmUk5QpgZR9lChoBX2UKIwEbmFtZZSMBUFscGhhlIwEdHlwZZSMDG9yZ2FuaXphdGlvbpR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgaaByQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWJoFimBlH2UKGgFfZQoaBqMBEJldGGUaByMDG9yZ2FuaXphdGlvbpR1aB59lGggj5QoaBpoHJBoIk51YmWMD3ByZXN1bWVkX2ludGVudJSMF1ZlcmlmeSByZXBvcnRlZCBmaWd1cmVzlIwOb3JpZ2luYWxfaW5wdXSUjC5BbHBoYSByb3NlIDUlIGluIDIwMjQuIEJldGEgZmVsbCAzJSBsYXN0IHllYXIulIwJbG9jYXRpb25zlE51aB59lGggj5QoaBNoCWgPaAtoB2gRaC5oLGgqkGgiTnViLg==", + "extract__replay_later_200.json": "gASVZgIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMBXJlYWR5lIwFY2xhaW2UjBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwRaWRlbnRpZmllZF9jbGFpbXOUXZQojBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwXQmV0YSBmZWxsIDMlIGxhc3QgeWVhci6UZYwQY2FuZGlkYXRlX2NsYWltc5RdlIwGZG9tYWlulIwJRWNvbm9taWNzlIwMa2V5X2VudGl0aWVzlF2UKGgAjA9FeHRyYWN0ZWRFbnRpdHmUk5QpgZR9lChoBX2UKIwEbmFtZZSMBUFscGhhlIwEdHlwZZSMDG9yZ2FuaXphdGlvbpR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgaaByQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWJoFimBlH2UKGgFfZQoaBqMBEJldGGUaByMDG9yZ2FuaXphdGlvbpR1aB59lGggj5QoaBpoHJBoIk51YmWMD3ByZXN1bWVkX2ludGVudJSMF1ZlcmlmeSByZXBvcnRlZCBmaWd1cmVzlIwOb3JpZ2luYWxfaW5wdXSUjC5BbHBoYSByb3NlIDUlIGluIDIwMjQuIEJldGEgZmVsbCAzJSBsYXN0IHllYXIulIwJbG9jYXRpb25zlE51aB59lGggj5QoaBNoCWgPaAtoB2gRaC5oLGgqkGgiTnViLg==", + "extract__url_input_located.json": "gASV4AIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwPRXh0cmFjdGVkQ2xhaW1zlJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMBnN0YXR1c5SMBXJlYWR5lIwFY2xhaW2UjBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwRaWRlbnRpZmllZF9jbGFpbXOUXZSMEGNhbmRpZGF0ZV9jbGFpbXOUXZSMBmRvbWFpbpSMCUVjb25vbWljc5SMDGtleV9lbnRpdGllc5RdlChoAIwPRXh0cmFjdGVkRW50aXR5lJOUKYGUfZQoaAV9lCiMBG5hbWWUjAVBbHBoYZSMBHR5cGWUjAxvcmdhbml6YXRpb26UdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGGgakIwUX19weWRhbnRpY19wcml2YXRlX1+UTnViaBQpgZR9lChoBX2UKGgYjARCZXRhlGgajAxvcmdhbml6YXRpb26UdWgcfZRoHo+UKGgYaBqQaCBOdWJljA9wcmVzdW1lZF9pbnRlbnSUjBdWZXJpZnkgcmVwb3J0ZWQgZmlndXJlc5SMDm9yaWdpbmFsX2lucHV0lIweaHR0cHM6Ly9leGFtcGxlLmNvbS9hbi1hcnRpY2xllIwJbG9jYXRpb25zlF2UaACMDUNsYWltTG9jYXRpb26Uk5QpgZR9lChoBX2UKGgJjBZBbHBoYSByb3NlIDUlIGluIDIwMjQulIwJcG9zaXRpb25zlF2UaACMCFBvc2l0aW9ulJOUKYGUfZQoaAV9lCiMBXN0YXJ0lE6MA2VuZJROjAR0ZXh0lIwWQWxwaGEgcm9zZSA1JSBpbiAyMDI0LpR1aBx9lGgej5QoaDtoPGg9kGggTnViYXVoHH2UaB6PlChoCWg0kGggTnViYXVoHH2UaB6PlChoEWgJaA1oC2gHaA9oLGgqaCiQaCBOdWIu", + "review__get_assessing.json": "gASVTgcAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJYXNzZXNzaW5nlIwHb3V0Y29tZZROjApjcmVhdGVkX2F0lIwbMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTZalIwMY29tcGxldGVkX2F0lIwbMjAyNi0xMC0wMVQxMDowNzowMC4xMjM0NTZalIwIbGFuZ3VhZ2WUjAJlbpSMBnBvbGljeZRoAIwQRXNjYWxhdGlvblBvbGljeZSTlCmBlH2UKGgFfZQojAh2ZXJkaWN0c5RdlCiMBUZhbHNllIwMTW9zdGx5IEZhbHNllIwFTWl4ZWSUZYwKY29uZmlkZW5jZZRdlIwDbG93lGGMD21heF9hc3Nlc3NtZW50c5RLFIwRbWF4X3ZlcmlmaWNhdGlvbnOUSwWMBWRlcHRolIwIc3RhbmRhcmSUjA1tYXhfY2l0YXRpb25zlEsAjA1zdWdnZXN0X2VkaXRzlIl1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgaaCRoH2gmaCdoI2gikIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAdzdW1tYXJ5lGgAjA1SZXZpZXdTdW1tYXJ5lJOUKYGUfZQoaAV9lCiMD2NsYWltc19zZWxlY3RlZJRLAowLY2xhaW1fbGltaXSUSxSME2NsYWltX2xpbWl0X3JlYWNoZWSUiYwPaW5wdXRfdHJ1bmNhdGVklImMC2Fzc2Vzc21lbnRzlGgAjBZSZXZpZXdBc3Nlc3NtZW50Q291bnRzlJOUKYGUfZQoaAV9lCiMCWNvbXBsZXRlZJRLAIwGZmFpbGVklEsAdWgofZRoKo+UKGg9aD6QaCxOdWKMDXZlcmlmaWNhdGlvbnOUTowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lE6MFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUTowPY2l0YXRpb25fY2hlY2tzlE6MD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoKH2UaCqPlChoM2g3aDZoRGhBaEloRmhCaDRoRWhIaEdoQ2g1kGgsTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAnNoKH2UaCqPlChoUpBoLE51YowScG9sbF9hZnRlcl9zZWNvbmRzlEsKaEJdlIwIZmFpbHVyZXOUXZRoSF2UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUXZSMFG1vcmVfY2xhaW1fbG9jYXRpb25zlF2UjA5tb3JlX2NpdGF0aW9uc5RdlIwHZmFpbHVyZZROjAZjbGFpbXOUXZQoaACMC1Jldmlld0NsYWltlJOUKYGUfZQoaAV9lCiMBWluZGV4lEsAjAVjbGFpbZSMKFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UjAlwb3NpdGlvbnOUTowGcmVzdWx0lE6MCmFzc2Vzc21lbnSUaACMEFJldmlld0Fzc2Vzc21lbnSUk5QpgZR9lChoBX2UKGgLjAdydW5uaW5nlIwHdmVyZGljdJROaB9OjAlyYXRpb25hbGWUTowHZGlzc2VudJROjBB2ZXJpZmljYXRpb25fdXJslE6MCmVycm9yX2NvZGWUTowRaWRlbnRpZmllZF9jbGFpbXOUXZSMBGhpbnSUTowRc3VnZ2VzdGVkX3Jld3JpdGWUTmhiTnVoKH2UaCqPlChofWh4aHloH2gLaHZoe2h3aHpofmhikGgsTnVijAplc2NhbGF0aW9ulE6MDHZlcmlmaWNhdGlvbpROjA9zdWdnZXN0ZWRfZWRpdHOUTnVoKH2UaCqPlChoa2hvaIFoamiCaINobmhtkGgsTnViaGYpgZR9lChoBX2UKGhqSwFoa4wiV2F0ZXIgYm9pbHMgYXQgMTAwIEMgYXQgc2VhIGxldmVsLpRobU5obk5ob2hxKYGUfZQoaAV9lChoC4wHcnVubmluZ5Rodk5oH05od05oeE5oeU5oek5oe12UaH1OaH5OaGJOdWgofZRoKo+UKGh9aHhoeWgfaAtodmh7aHdoemh+aGKQaCxOdWJogU5ogk5og051aCh9lGgqj5QoaGtob2iBaGpogmiDaG5obZBoLE51YmWMCWNpdGF0aW9uc5RdlHVoKH2UaCqPlChoXGhXaBBoC2gUaFpoVWgtaGBoTGgOaEhoY2gNaF5oEmgJaJNoQmgHaGKQaCxOdWIu", + "review__get_assessment_rows_full_fields.json": "gASV+QwAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMCmluY29tcGxldGWUjApjcmVhdGVkX2F0lIwbMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTZalIwMY29tcGxldGVkX2F0lIwbMjAyNi0xMC0wMVQxMDowNzowMC4xMjM0NTZalIwIbGFuZ3VhZ2WUjAJlbpSMBnBvbGljeZRoAIwQRXNjYWxhdGlvblBvbGljeZSTlCmBlH2UKGgFfZQojAh2ZXJkaWN0c5RdlCiMBUZhbHNllIwMTW9zdGx5IEZhbHNllIwFTWl4ZWSUZYwKY29uZmlkZW5jZZRdlIwDbG93lGGMD21heF9hc3Nlc3NtZW50c5RLFIwRbWF4X3ZlcmlmaWNhdGlvbnOUSwCMBWRlcHRolIwIc3RhbmRhcmSUjA1tYXhfY2l0YXRpb25zlEsAjA1zdWdnZXN0X2VkaXRzlIl1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgbaCVoIGgnaChoJGgjkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAdzdW1tYXJ5lGgAjA1SZXZpZXdTdW1tYXJ5lJOUKYGUfZQoaAV9lCiMD2NsYWltc19zZWxlY3RlZJRLAowLY2xhaW1fbGltaXSUSxSME2NsYWltX2xpbWl0X3JlYWNoZWSUiYwPaW5wdXRfdHJ1bmNhdGVklImMC2Fzc2Vzc21lbnRzlGgAjBZSZXZpZXdBc3Nlc3NtZW50Q291bnRzlJOUKYGUfZQoaAV9lCiMCWNvbXBsZXRlZJRLAYwGZmFpbGVklEsBdWgpfZRoK4+UKGg+aD+QaC1OdWKMDXZlcmlmaWNhdGlvbnOUaACMGFJldmlld1ZlcmlmaWNhdGlvbkNvdW50c5STlCmBlH2UKGgFfZQojAdwbGFubmVklEsAaD5LAGg/SwB1aCl9lGgrj5QoaD5oP2hIkGgtTnVijAZpc3N1ZXOUSwGMD2NpdGF0aW9uc19mb3VuZJROjBJjaXRhdGlvbnNfc2VsZWN0ZWSUTowOY2l0YXRpb25fbGltaXSUTowWY2l0YXRpb25fbGltaXRfcmVhY2hlZJROjA9jaXRhdGlvbl9jaGVja3OUTowPY2l0YXRpb25faXNzdWVzlEsAjBFjaXRhdGlvbnNfc2tpcHBlZJROdWgpfZRoK4+UKGg0aDhoN2hNaEJoUmhPaEtoNWhOaFFoUGhMaDaQaC1OdWKMB2NyZWRpdHOUaACMDVJldmlld0NyZWRpdHOUk5QpgZR9lChoBX2UjAdjaGFyZ2VklEsCc2gpfZRoK4+UKGhbkGgtTnVijBJwb2xsX2FmdGVyX3NlY29uZHOUTmhLXZRoAIwLUmV2aWV3SXNzdWWUk5QpgZR9lChoBX2UKIwLY2xhaW1faW5kZXiUSwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMDnZlcmlmaWVkX2NsYWltlE6MB3ZlcmRpY3SUjAVGYWxzZZRoIIwEaGlnaJSMBnNvdXJjZZSMCmFzc2Vzc21lbnSUjA92ZXJpZmljYXRpb25faWSUTowTdmVyaWZpY2F0aW9uX3N0YXR1c5ROjBB2ZXJpZmljYXRpb25fdXJslE6MA3VybJROjAplc2NhbGF0aW9ulGgAjApFc2NhbGF0aW9ulJOUKYGUfZQoaAV9lCiMDW1hdGNoZWRfcnVsZXOUXZSMB3ZlcmRpY3SUYYwLZGlzcG9zaXRpb26UjANjYXCUdWgpfZRoK4+UKGh7aHiQaC1OdWKMC2tleV9maW5kaW5nlE6MCXJhdGlvbmFsZZSMI1R3byByZXZpZXdlcnMgZm91bmQgdGhlIGRhdGUgd3JvbmculIwRc3VnZ2VzdGVkX3Jld3JpdGWUjDBUaGUgRVUgQUkgQWN0IGVudGVyZWQgaW50byBmb3JjZSBpbiBBdWd1c3QgMjAyNC6UjAdmYWlsdXJllE6MD3N1Z2dlc3RlZF9lZGl0c5ROdWgpfZRoK4+UKGhmaG5ocGggaGlob2hyaIBohWhxaGxoaGhlaH9ogmiEkGgtTnViYYwIZmFpbHVyZXOUXZRoAIwNUmV2aWV3RmFpbHVyZZSTlCmBlH2UKGgFfZQoaGVLAWhmjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UjAVzdGFnZZSMCmFzc2Vzc21lbnSUaIRoAIwMRmFpbHVyZUJsb2NrlJOUKYGUfZQoaAV9lCiMDmZhaWx1cmVfcmVhc29ulIwHdGltZW91dJSMDWZhaWx1cmVfY2xhc3OUjBR1cHN0cmVhbV91bmF2YWlsYWJsZZSMCXJldHJ5YWJsZZSIjARoaW50lIw5VGhlIGNoZWNrIHJhbiBvdXQgb2YgdGltZS4gUmV0cnkgaXQ7IG5vdGhpbmcgd2FzIGNoYXJnZWQulIwIZG9jc191cmyUTnVoKX2UaCuPlChonGiXaJ5omWibkGgtTnVidWgpfZRoK4+UKGhmaGVokGiEkGgtTnViYWhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UaIROjAZjbGFpbXOUXZQoaACMC1Jldmlld0NsYWltlJOUKYGUfZQoaAV9lCiMBWluZGV4lEsAaGaMKFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UjAlwb3NpdGlvbnOUTowGcmVzdWx0lGgAjAxSZXZpZXdSZXN1bHSUk5QpgZR9lChoBX2UKGhpjAVGYWxzZZRoIIwEaGlnaJRobIwKYXNzZXNzbWVudJSMCGlzX2lzc3VllIh1aCl9lGgrj5QoaCBoaWhsaL+QaC1OdWKMCmFzc2Vzc21lbnSUaACMEFJldmlld0Fzc2Vzc21lbnSUk5QpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaGmMBUZhbHNllGggjARoaWdolGiAjCNUd28gcmV2aWV3ZXJzIGZvdW5kIHRoZSBkYXRlIHdyb25nLpSMB2Rpc3NlbnSUjDpPbmUgcmV2aWV3ZXIgcmVhZCB0aGUgY2xhaW0gYXMgYWJvdXQgdGhlIGVudHJ5IGludG8gZm9yY2UulGhwTowKZXJyb3JfY29kZZROjBFpZGVudGlmaWVkX2NsYWltc5RdlCiMIlRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gMjAyNC6UjBhJdCB0b29rIGVmZmVjdCBpbiBNYXJjaC6UZWicjCRUaGlzIHRleHQgaG9sZHMgbW9yZSB0aGFuIG9uZSBjbGFpbS6UaIKMMFRoZSBFVSBBSSBBY3QgZW50ZXJlZCBpbnRvIGZvcmNlIGluIEF1Z3VzdCAyMDI0LpRohE51aCl9lGgrj5QoaJxozGhwaCBoC2hpaM9ogGjOaIJohJBoLU51YmhyaHQpgZR9lChoBX2UKGh4XZSMB3ZlcmRpY3SUYWh7jANjYXCUdWgpfZRoK4+UKGh7aHiQaC1OdWKMDHZlcmlmaWNhdGlvbpROaIVOdWgpfZRoK4+UKGhmaMJocmizaN9ohWi2aLWQaC1OdWJorymBlH2UKGgFfZQoaLNLAWhmjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UaLVOaLZOaMJoxCmBlH2UKGgFfZQoaAuMBmZhaWxlZJRoaU5oIE5ogE5ozE5ocE5ozowHdGltZW91dJRoz12UaJxOaIJOaIRokymBlH2UKGgFfZQoaJeMB3RpbWVvdXSUaJmMFHVwc3RyZWFtX3VuYXZhaWxhYmxllGibiGicjDlUaGUgY2hlY2sgcmFuIG91dCBvZiB0aW1lLiBSZXRyeSBpdDsgbm90aGluZyB3YXMgY2hhcmdlZC6UaJ5OdWgpfZRoK4+UKGicaJdonmiZaJuQaC1OdWJ1aCl9lGgrj5QoaJxozGhwaCBoC2hpaM9ogGjOaIJohJBoLU51YmhyTmjfTmiFTnVoKX2UaCuPlChoZmjCaHJos2jfaIVotmi1kGgtTnViZYwJY2l0YXRpb25zlF2UdWgpfZRoK4+UKGimaIhoEWgLaBVopGheaC5oqmhVaA9oUWisaA1oqGgTaAlo+GhLaAdohJBoLU51Yi4=", + "review__get_citations_clean.json": "gASV2w0AAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLFIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwGMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwGMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUSwKMEmNpdGF0aW9uc19zZWxlY3RlZJRLAowOY2l0YXRpb25fbGltaXSUSxSMFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUiYwPY2l0YXRpb25fY2hlY2tzlGgAjBlSZXZpZXdDaXRhdGlvbkNoZWNrQ291bnRzlJOUKYGUfZQoaAV9lCiMB2NoZWNrZWSUSwKMCXVuY2hlY2tlZJRLAGg/SwB1aCl9lGgrj5QoaFZoV2g/kGgtTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aE1oQmhbaE9oS2g1aE5oWmhQaExoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwNzaCl9lGgrj5QoaGSQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaEtdlIwIZmFpbHVyZXOUXZRoWl2UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUXZSMFG1vcmVfY2xhaW1fbG9jYXRpb25zlF2UjA5tb3JlX2NpdGF0aW9uc5RdlIwHZmFpbHVyZZROjAZjbGFpbXOUXZRoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCXBvc2l0aW9uc5ROjAZyZXN1bHSUaACMDFJldmlld1Jlc3VsdJSTlCmBlH2UKGgFfZQojAd2ZXJkaWN0lIwEVHJ1ZZRoIIwEaGlnaJSMBnNvdXJjZZSMCmFzc2Vzc21lbnSUjAhpc19pc3N1ZZSJdWgpfZRoK4+UKGggaIZoiWiLkGgtTnVijAphc3Nlc3NtZW50lGgAjBBSZXZpZXdBc3Nlc3NtZW50lJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGiGjARUcnVllGggjARoaWdolIwJcmF0aW9uYWxllE6MB2Rpc3NlbnSUTowQdmVyaWZpY2F0aW9uX3VybJROjAplcnJvcl9jb2RllE6MEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE6MEXN1Z2dlc3RlZF9yZXdyaXRllE5odE51aCl9lGgrj5QoaJ1omGiZaCBoC2iGaJtol2iaaJ5odJBoLU51YowKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAtkaXNwb3NpdGlvbpSMDG5vdF9zZWxlY3RlZJR1aCl9lGgrj5QoaKlop5BoLU51YowMdmVyaWZpY2F0aW9ulE6MD3N1Z2dlc3RlZF9lZGl0c5ROdWgpfZRoK4+UKGh9aI5ooWh8aK1ormiAaH+QaC1OdWJhjAljaXRhdGlvbnOUXZQoaACMDlJldmlld0NpdGF0aW9ulJOUKYGUfZQoaAV9lChofEsAjAlyZWZlcmVuY2WUjBphIHJlcG9ydCBmcm9tIHRoZSBtaW5pc3RyeZSMCWNpdGVkX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjANkb2mUTowJc3RhdGVtZW50lIxLVW5lbXBsb3ltZW50IGZlbGwgdG8gNC4xJSBpbiAyMDI0LCBhY2NvcmRpbmcgdG8gYSByZXBvcnQgZnJvbSB0aGUgbWluaXN0cnkulIwGcXVvdGVzlF2UjAhwb3NpdGlvbpRoAIwIUG9zaXRpb26Uk5QpgZR9lChoBX2UKIwFc3RhcnSUSwCMA2VuZJRLbowEdGV4dJROdWgpfZRoK4+UKGjHaMhoyZBoLU51YmiAaACMFFJldmlld0NpdGF0aW9uUmVzdWx0lJOUKYGUfZQoaAV9lCiMB2ZpbmRpbmeUjAlzdXBwb3J0ZWSUaImMB3N1cHBvcnSUaIuJdWgpfZRoK4+UKGjRaItoiZBoLU51YowFY2hlY2uUaACME1Jldmlld0NpdGF0aW9uQ2hlY2uUk5QpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUjAlwYWdlX3JlYWSUjARmdWxslIwKcGFnZV90aXRsZZSMJ1BhZ2UgYXQgaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSME3BhZ2VfcHVibGlzaGVkX2RhdGWUTowNcGFnZV9sYW5ndWFnZZSMAmVulIwKc291cmNlX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjA5zb3VyY2VfdmVyc2lvbpROjAdzdXBwb3J0lIwJc3VwcG9ydGVklIwHc25pcHBldJSME1RoZSBzb3VyY2Ugc2F5cyBzby6UaJeME1RoZSBwYWdlIHN0YXRlcyBpdC6UjAVxdW90ZZROjA1taXNzaW5nX3F1b3RllE6MDmRvaV9yZWdpc3RlcmVklE6MCG1ldGFkYXRhlE6MFG1ldGFkYXRhX2RpZmZlcmVuY2VzlF2UjApyZWdpc3RlcmVklE6MEHVuY2hlY2tlZF9yZWFzb26UTmidTmh0TnVoKX2UaCuPlCho4WjzaJdo4mjkaJ1o7mjvaAto7WjwaOxo32jyaOdo3WjmaOlodJBoLU51YnVoKX2UaCuPlChovWiAaLho1mh8aLxov2i6aMGQaC1OdWJotCmBlH2UKGgFfZQoaHxLAWi4jAthIHN0YXRlbWVudJRouowdaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaLxOaL2MIlRoZSBhZ2VuY3kgc2FpZCBzbyBpbiBhIHN0YXRlbWVudC6UaL9dlGjBaMMpgZR9lChoBX2UKGjHS29oyEuyaMlOdWgpfZRoK4+UKGjHaMhoyZBoLU51YmiAaM0pgZR9lChoBX2UKGjRjAlzdXBwb3J0ZWSUaImMB3N1cHBvcnSUaIuJdWgpfZRoK4+UKGjRaItoiZBoLU51YmjWaNgpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaN2MBGZ1bGyUaN+MJVBhZ2UgYXQgaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaOFOaOKMAmVulGjkjB1odHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRo5k5o54wJc3VwcG9ydGVklGjpjBNUaGUgc291cmNlIHNheXMgc28ulGiXjBNUaGUgcGFnZSBzdGF0ZXMgaXQulGjsTmjtTmjuTmjvTmjwXZRo8k5o805onU5odE51aCl9lGgrj5QoaOFo82iXaOJo5GidaO5o72gLaO1o8GjsaN9o8mjnaN1o5mjpaHSQaC1OdWJ1aCl9lGgrj5QoaL1ogGi4aNZofGi8aL9oumjBkGgtTnViZXVoKX2UaCuPlChobmhpaBFoC2gVaGxoZ2guaHJoXmgPaFpodWgNaHBoE2gJaLFoS2gHaHSQaC1OdWIu", + "review__get_citations_failed_and_unchecked.json": "gASVUA8AAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMCmluY29tcGxldGWUjApjcmVhdGVkX2F0lIwbMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTZalIwMY29tcGxldGVkX2F0lIwbMjAyNi0xMC0wMVQxMDowNzowMC4xMjM0NTZalIwIbGFuZ3VhZ2WUjAJlbpSMBnBvbGljeZRoAIwQRXNjYWxhdGlvblBvbGljeZSTlCmBlH2UKGgFfZQojAh2ZXJkaWN0c5RdlCiMBUZhbHNllIwMTW9zdGx5IEZhbHNllIwFTWl4ZWSUZYwKY29uZmlkZW5jZZRdlIwDbG93lGGMD21heF9hc3Nlc3NtZW50c5RLFIwRbWF4X3ZlcmlmaWNhdGlvbnOUSwWMBWRlcHRolIwIc3RhbmRhcmSUjA1tYXhfY2l0YXRpb25zlEsUjA1zdWdnZXN0X2VkaXRzlIl1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgbaCVoIGgnaChoJGgjkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAdzdW1tYXJ5lGgAjA1SZXZpZXdTdW1tYXJ5lJOUKYGUfZQoaAV9lCiMD2NsYWltc19zZWxlY3RlZJRLAYwLY2xhaW1fbGltaXSUSxSME2NsYWltX2xpbWl0X3JlYWNoZWSUiYwPaW5wdXRfdHJ1bmNhdGVklImMC2Fzc2Vzc21lbnRzlGgAjBZSZXZpZXdBc3Nlc3NtZW50Q291bnRzlJOUKYGUfZQoaAV9lCiMCWNvbXBsZXRlZJRLAYwGZmFpbGVklEsAdWgpfZRoK4+UKGg+aD+QaC1OdWKMDXZlcmlmaWNhdGlvbnOUaACMGFJldmlld1ZlcmlmaWNhdGlvbkNvdW50c5STlCmBlH2UKGgFfZQojAdwbGFubmVklEsAaD5LAGg/SwB1aCl9lGgrj5QoaD5oP2hIkGgtTnVijAZpc3N1ZXOUSwCMD2NpdGF0aW9uc19mb3VuZJRLAowSY2l0YXRpb25zX3NlbGVjdGVklEsCjA5jaXRhdGlvbl9saW1pdJRLFIwWY2l0YXRpb25fbGltaXRfcmVhY2hlZJSJjA9jaXRhdGlvbl9jaGVja3OUaACMGVJldmlld0NpdGF0aW9uQ2hlY2tDb3VudHOUk5QpgZR9lChoBX2UKIwHY2hlY2tlZJRLAIwJdW5jaGVja2VklEsBaD9LAXVoKX2UaCuPlChoVmhXaD+QaC1OdWKMD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoKX2UaCuPlChoNGg4aDdoTWhCaFtoT2hLaDVoTmhaaFBoTGg2kGgtTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAXNoKX2UaCuPlChoZJBoLU51YowScG9sbF9hZnRlcl9zZWNvbmRzlE5oS12UjAhmYWlsdXJlc5RdlGhaXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UaACMFVJldmlld0NpdGF0aW9uRmFpbHVyZZSTlCmBlH2UKGgFfZQojA5jaXRhdGlvbl9pbmRleJRLAIwJcmVmZXJlbmNllIwaYSByZXBvcnQgZnJvbSB0aGUgbWluaXN0cnmUjAljaXRlZF91cmyUjB9odHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwDZG9plE6MB2ZhaWx1cmWUaACMDEZhaWx1cmVCbG9ja5STlCmBlH2UKGgFfZQojA5mYWlsdXJlX3JlYXNvbpSMCGludGVybmFslIwNZmFpbHVyZV9jbGFzc5SMCGludGVybmFslIwJcmV0cnlhYmxllImMBGhpbnSUjC5UaGUgY2hlY2sgZmFpbGVkIG9uIG91ciBzaWRlLiBUcnkgYWdhaW4gbGF0ZXIulIwIZG9jc191cmyUjCRodHRwczovL2xlbnouaW8vZG9jcy9lcnJvcnMjaW50ZXJuYWyUdWgpfZRoK4+UKGiEaH9ohmiBaIOQaC1OdWJ1aCl9lGgrj5QoaHRoeGhzaHZoeZBoLU51YmGMC21vcmVfY2xhaW1zlF2UjBRtb3JlX2NsYWltX2xvY2F0aW9uc5RdlIwObW9yZV9jaXRhdGlvbnOUXZRoeU6MBmNsYWltc5RdlGgAjAtSZXZpZXdDbGFpbZSTlCmBlH2UKGgFfZQojAVpbmRleJRLAIwFY2xhaW2UjChUaGUgRVUgQUkgQWN0IHRvb2sgZWZmZWN0IGluIE1hcmNoIDIwMjQulIwJcG9zaXRpb25zlE6MBnJlc3VsdJRoAIwMUmV2aWV3UmVzdWx0lJOUKYGUfZQoaAV9lCiMB3ZlcmRpY3SUjARUcnVllGggjARoaWdolIwGc291cmNllIwKYXNzZXNzbWVudJSMCGlzX2lzc3VllIl1aCl9lGgrj5QoaCBoo2imaKiQaC1OdWKMCmFzc2Vzc21lbnSUaACMEFJldmlld0Fzc2Vzc21lbnSUk5QpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaKOMBFRydWWUaCCMBGhpZ2iUjAlyYXRpb25hbGWUTowHZGlzc2VudJROjBB2ZXJpZmljYXRpb25fdXJslE6MCmVycm9yX2NvZGWUTowRaWRlbnRpZmllZF9jbGFpbXOUXZRohE6MEXN1Z2dlc3RlZF9yZXdyaXRllE5oeU51aCl9lGgrj5QoaIRotWi2aCBoC2ijaLhotGi3aLpoeZBoLU51YowKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAtkaXNwb3NpdGlvbpSMDG5vdF9zZWxlY3RlZJR1aCl9lGgrj5QoaMVow5BoLU51YowMdmVyaWZpY2F0aW9ulE6MD3N1Z2dlc3RlZF9lZGl0c5ROdWgpfZRoK4+UKGiaaKtovWiZaMloymidaJyQaC1OdWJhjAljaXRhdGlvbnOUXZQoaACMDlJldmlld0NpdGF0aW9ulJOUKYGUfZQoaAV9lChomUsAaHSMGmEgcmVwb3J0IGZyb20gdGhlIG1pbmlzdHJ5lGh2jB9odHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lGh4TowJc3RhdGVtZW50lIxLVW5lbXBsb3ltZW50IGZlbGwgdG8gNC4xJSBpbiAyMDI0LCBhY2NvcmRpbmcgdG8gYSByZXBvcnQgZnJvbSB0aGUgbWluaXN0cnkulIwGcXVvdGVzlF2UjAhwb3NpdGlvbpRoAIwIUG9zaXRpb26Uk5QpgZR9lChoBX2UKIwFc3RhcnSUSwCMA2VuZJRLbowEdGV4dJROdWgpfZRoK4+UKGjgaOFo4pBoLU51YmidTowFY2hlY2uUaACME1Jldmlld0NpdGF0aW9uQ2hlY2uUk5QpgZR9lChoBX2UKGgLjAZmYWlsZWSUjAlwYWdlX3JlYWSUTowKcGFnZV90aXRsZZROjBNwYWdlX3B1Ymxpc2hlZF9kYXRllE6MDXBhZ2VfbGFuZ3VhZ2WUTowKc291cmNlX3VybJROjA5zb3VyY2VfdmVyc2lvbpROjAdzdXBwb3J0lE6MB3NuaXBwZXSUTmi0TowFcXVvdGWUTowNbWlzc2luZ19xdW90ZZROjA5kb2lfcmVnaXN0ZXJlZJROjAhtZXRhZGF0YZROjBRtZXRhZGF0YV9kaWZmZXJlbmNlc5RdlIwKcmVnaXN0ZXJlZJROjBB1bmNoZWNrZWRfcmVhc29ulE5ohIwuVGhlIGNoZWNrIGZhaWxlZCBvbiBvdXIgc2lkZS4gVHJ5IGFnYWluIGxhdGVyLpRoeWh7KYGUfZQoaAV9lChof4wIaW50ZXJuYWyUaIGMCGludGVybmFslGiDiWiEjC5UaGUgY2hlY2sgZmFpbGVkIG9uIG91ciBzaWRlLiBUcnkgYWdhaW4gbGF0ZXIulGiGjCRodHRwczovL2xlbnouaW8vZG9jcy9lcnJvcnMjaW50ZXJuYWyUdWgpfZRoK4+UKGiEaH9ohmiBaIOQaC1OdWJ1aCl9lGgrj5QoaO5o+2i0aO9o8GiEaPZo92gLaPVo+Gj0aO1o+mjyaOxo8WjzaHmQaC1OdWJ1aCl9lGgrj5QoaNZonWh0aOVomWh4aNhodmjakGgtTnViaNApgZR9lChoBX2UKGiZSwFodIwLYSBzdGF0ZW1lbnSUaHaMHWh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGh4TmjWjCJUaGUgYWdlbmN5IHNhaWQgc28gaW4gYSBzdGF0ZW1lbnQulGjYXZRo2mjcKYGUfZQoaAV9lCho4EtvaOFLsmjiTnVoKX2UaCuPlCho4GjhaOKQaC1OdWJonWgAjBRSZXZpZXdDaXRhdGlvblJlc3VsdJSTlCmBlH2UKGgFfZQojAdmaW5kaW5nlIwJdW5jaGVja2VklGimTmioiXVoKX2UaCuPlChqGwEAAGioaKaQaC1OdWJo5WjnKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGjsjARmdWxslGjtjCVQYWdlIGF0IGh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGjuTmjvjAJlbpRo8IwdaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaPFOaPKMCXVuY2hlY2tlZJRo805otIwTVGhlIHBhZ2Ugc3RhdGVzIGl0LpRo9E5o9U5o9k5o905o+F2UaPpOaPuMB25vX3RleHSUaIROaHlOdWgpfZRoK4+UKGjuaPtotGjvaPBohGj2aPdoC2j1aPho9GjtaPpo8mjsaPFo82h5kGgtTnVidWgpfZRoK4+UKGjWaJ1odGjlaJloeGjYaHZo2pBoLU51YmV1aCl9lGgrj5QoaIxoaWgRaAtoFWhsaGdoLmiQaF5oD2haaJJoDWiOaBNoCWjNaEtoB2h5kGgtTnViLg==", + "review__get_citations_issue_full.json": "gASV2w8AAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMDGlzc3Vlc19mb3VuZJSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjAhsYW5ndWFnZZSMAmVulIwGcG9saWN5lGgAjBBFc2NhbGF0aW9uUG9saWN5lJOUKYGUfZQoaAV9lCiMCHZlcmRpY3RzlF2UKIwFRmFsc2WUjAxNb3N0bHkgRmFsc2WUjAVNaXhlZJRljApjb25maWRlbmNllF2UjANsb3eUYYwPbWF4X2Fzc2Vzc21lbnRzlEsUjBFtYXhfdmVyaWZpY2F0aW9uc5RLBYwFZGVwdGiUjAhzdGFuZGFyZJSMDW1heF9jaXRhdGlvbnOUSxSMDXN1Z2dlc3RfZWRpdHOUiXWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBtoJWggaCdoKGgkaCOQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMB3N1bW1hcnmUaACMDVJldmlld1N1bW1hcnmUk5QpgZR9lChoBX2UKIwPY2xhaW1zX3NlbGVjdGVklEsBjAtjbGFpbV9saW1pdJRLFIwTY2xhaW1fbGltaXRfcmVhY2hlZJSJjA9pbnB1dF90cnVuY2F0ZWSUiYwLYXNzZXNzbWVudHOUaACMFlJldmlld0Fzc2Vzc21lbnRDb3VudHOUk5QpgZR9lChoBX2UKIwJY29tcGxldGVklEsBjAZmYWlsZWSUSwB1aCl9lGgrj5QoaD5oP5BoLU51YowNdmVyaWZpY2F0aW9uc5RoAIwYUmV2aWV3VmVyaWZpY2F0aW9uQ291bnRzlJOUKYGUfZQoaAV9lCiMB3BsYW5uZWSUSwBoPksAaD9LAHVoKX2UaCuPlChoPmg/aEiQaC1OdWKMBmlzc3Vlc5RLAIwPY2l0YXRpb25zX2ZvdW5klEsCjBJjaXRhdGlvbnNfc2VsZWN0ZWSUSwKMDmNpdGF0aW9uX2xpbWl0lEsUjBZjaXRhdGlvbl9saW1pdF9yZWFjaGVklImMD2NpdGF0aW9uX2NoZWNrc5RoAIwZUmV2aWV3Q2l0YXRpb25DaGVja0NvdW50c5STlCmBlH2UKGgFfZQojAdjaGVja2VklEsCjAl1bmNoZWNrZWSUSwBoP0sAdWgpfZRoK4+UKGhWaFdoP5BoLU51YowPY2l0YXRpb25faXNzdWVzlEsBjBFjaXRhdGlvbnNfc2tpcHBlZJROdWgpfZRoK4+UKGg0aDhoN2hNaEJoW2hPaEtoNWhOaFpoUGhMaDaQaC1OdWKMB2NyZWRpdHOUaACMDVJldmlld0NyZWRpdHOUk5QpgZR9lChoBX2UjAdjaGFyZ2VklEsDc2gpfZRoK4+UKGhkkGgtTnVijBJwb2xsX2FmdGVyX3NlY29uZHOUTmhLXZSMCGZhaWx1cmVzlF2UaFpdlGgAjBNSZXZpZXdDaXRhdGlvbklzc3VllJOUKYGUfZQoaAV9lCiMDmNpdGF0aW9uX2luZGV4lEsAjAlyZWZlcmVuY2WUjBphIHJlcG9ydCBmcm9tIHRoZSBtaW5pc3RyeZSMCWNpdGVkX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjANkb2mUTowJc3RhdGVtZW50lIxLVW5lbXBsb3ltZW50IGZlbGwgdG8gNC4xJSBpbiAyMDI0LCBhY2NvcmRpbmcgdG8gYSByZXBvcnQgZnJvbSB0aGUgbWluaXN0cnkulIwGcXVvdGVzlF2UjAhwb3NpdGlvbpRoAIwIUG9zaXRpb26Uk5QpgZR9lChoBX2UKIwFc3RhcnSUSwCMA2VuZJRLbowEdGV4dJROdWgpfZRoK4+UKGiBaIJog5BoLU51YowHZmluZGluZ5SMDGNvbnRyYWRpY3RlZJSMBnNvdXJjZZSMB3N1cHBvcnSUjAdzbmlwcGV0lIwTVGhlIHNvdXJjZSBzYXlzIHNvLpSMCXJhdGlvbmFsZZSME1RoZSBwYWdlIHN0YXRlcyBpdC6UjA1taXNzaW5nX3F1b3RllE6MFG1ldGFkYXRhX2RpZmZlcmVuY2VzlF2UjApwYWdlX3RpdGxllIwnUGFnZSBhdCBodHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwHZmFpbHVyZZROdWgpfZRoK4+UKGh3aI5ocmiPaJFodmhxaIxoeWiIaIZodGiKaJNoe5BoLU51YmGMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UaJNOjAZjbGFpbXOUXZRoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCXBvc2l0aW9uc5ROjAZyZXN1bHSUaACMDFJldmlld1Jlc3VsdJSTlCmBlH2UKGgFfZQojAd2ZXJkaWN0lIwEVHJ1ZZRoIIwEaGlnaJRoiIwKYXNzZXNzbWVudJSMCGlzX2lzc3VllIl1aCl9lGgrj5QoaCBor2iIaLOQaC1OdWKMCmFzc2Vzc21lbnSUaACMEFJldmlld0Fzc2Vzc21lbnSUk5QpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaK+MBFRydWWUaCCMBGhpZ2iUaIxOjAdkaXNzZW50lE6MEHZlcmlmaWNhdGlvbl91cmyUTowKZXJyb3JfY29kZZROjBFpZGVudGlmaWVkX2NsYWltc5RdlIwEaGludJROjBFzdWdnZXN0ZWRfcmV3cml0ZZROaJNOdWgpfZRoK4+UKGjEaL9owGggaAtor2jCaIxowWjFaJOQaC1OdWKMCmVzY2FsYXRpb26UaACMCkVzY2FsYXRpb26Uk5QpgZR9lChoBX2UKIwNbWF0Y2hlZF9ydWxlc5RdlIwLZGlzcG9zaXRpb26UjAxub3Rfc2VsZWN0ZWSUdWgpfZRoK4+UKGjQaM6QaC1OdWKMDHZlcmlmaWNhdGlvbpROjA9zdWdnZXN0ZWRfZWRpdHOUTnVoKX2UaCuPlChopmi2aMhopWjUaNVoqWiokGgtTnViYYwJY2l0YXRpb25zlF2UKGgAjA5SZXZpZXdDaXRhdGlvbpSTlCmBlH2UKGgFfZQoaKVLAGhyjBphIHJlcG9ydCBmcm9tIHRoZSBtaW5pc3RyeZRodIwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJRodk5od4xLVW5lbXBsb3ltZW50IGZlbGwgdG8gNC4xJSBpbiAyMDI0LCBhY2NvcmRpbmcgdG8gYSByZXBvcnQgZnJvbSB0aGUgbWluaXN0cnkulGh5XZRoe2h9KYGUfZQoaAV9lChogUsAaIJLbmiDTnVoKX2UaCuPlChogWiCaIOQaC1OdWJoqWgAjBRSZXZpZXdDaXRhdGlvblJlc3VsdJSTlCmBlH2UKGgFfZQoaIaMDGNvbnRyYWRpY3RlZJRoiIwHc3VwcG9ydJRos4h1aCl9lGgrj5QoaIZos2iIkGgtTnVijAVjaGVja5RoAIwTUmV2aWV3Q2l0YXRpb25DaGVja5STlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJSMCXBhZ2VfcmVhZJSMBGZ1bGyUaJGMJ1BhZ2UgYXQgaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSME3BhZ2VfcHVibGlzaGVkX2RhdGWUTowNcGFnZV9sYW5ndWFnZZSMAmVulIwKc291cmNlX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjA5zb3VyY2VfdmVyc2lvbpROjAdzdXBwb3J0lIwMY29udHJhZGljdGVklGiKjBNUaGUgc291cmNlIHNheXMgc28ulGiMjBNUaGUgcGFnZSBzdGF0ZXMgaXQulIwFcXVvdGWUTmiOTowOZG9pX3JlZ2lzdGVyZWSUTowIbWV0YWRhdGGUTmiPXZSMCnJlZ2lzdGVyZWSUTowQdW5jaGVja2VkX3JlYXNvbpROaMROaJNOdWgpfZRoK4+UKGj7agoBAABojGj8aP5oxGoGAQAAagcBAABoC2iOaI9qBQEAAGiRagkBAABqAQEAAGj4agABAABoimiTkGgtTnVidWgpfZRoK4+UKGh3aKlocmjxaKVodmh5aHRoe5BoLU51YmjbKYGUfZQoaAV9lChopUsBaHKMC2Egc3RhdGVtZW50lGh0jB1odHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRodk5od4wiVGhlIGFnZW5jeSBzYWlkIHNvIGluIGEgc3RhdGVtZW50LpRoeV2UaHtofSmBlH2UKGgFfZQoaIFLb2iCS7Jog051aCl9lGgrj5QoaIFogmiDkGgtTnViaKlo6SmBlH2UKGgFfZQoaIaMCXN1cHBvcnRlZJRoiIwHc3VwcG9ydJRos4l1aCl9lGgrj5QoaIZos2iIkGgtTnViaPFo8ymBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJRo+IwEZnVsbJRokYwlUGFnZSBhdCBodHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRo+05o/IwCZW6UaP6MHWh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGoAAQAATmoBAQAAjAlzdXBwb3J0ZWSUaIqME1RoZSBzb3VyY2Ugc2F5cyBzby6UaIyME1RoZSBwYWdlIHN0YXRlcyBpdC6UagUBAABOaI5OagYBAABOagcBAABOaI9dlGoJAQAATmoKAQAATmjETmiTTnVoKX2UaCuPlCho+2oKAQAAaIxo/Gj+aMRqBgEAAGoHAQAAaAtojmiPagUBAABokWoJAQAAagEBAABo+GoAAQAAaIpok5BoLU51YnVoKX2UaCuPlChod2ipaHJo8WilaHZoeWh0aHuQaC1OdWJldWgpfZRoK4+UKGiYaGloEWgLaBVolmhnaC5onGheaA9oWmieaA1ommgTaAlo2GhLaAdok5BoLU51Yi4=", + "review__get_citations_issue_issues_view.json": "gASV9AcAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjAZpc3N1ZXOUjAZzdGF0dXOUjAljb21wbGV0ZWSUjAdvdXRjb21llIwMaXNzdWVzX2ZvdW5klIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLFIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwGMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwGMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUSwKMEmNpdGF0aW9uc19zZWxlY3RlZJRLAowOY2l0YXRpb25fbGltaXSUSxSMFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUiYwPY2l0YXRpb25fY2hlY2tzlGgAjBlSZXZpZXdDaXRhdGlvbkNoZWNrQ291bnRzlJOUKYGUfZQoaAV9lCiMB2NoZWNrZWSUSwKMCXVuY2hlY2tlZJRLAGg/SwB1aCl9lGgrj5QoaFZoV2g/kGgtTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwGMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aE1oQmhbaE9oS2g1aE5oWmhQaExoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwNzaCl9lGgrj5QoaGSQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaEtdlIwIZmFpbHVyZXOUXZRoWl2UaACME1Jldmlld0NpdGF0aW9uSXNzdWWUk5QpgZR9lChoBX2UKIwOY2l0YXRpb25faW5kZXiUSwCMCXJlZmVyZW5jZZSMGmEgcmVwb3J0IGZyb20gdGhlIG1pbmlzdHJ5lIwJY2l0ZWRfdXJslIwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSMA2RvaZROjAlzdGF0ZW1lbnSUjEtVbmVtcGxveW1lbnQgZmVsbCB0byA0LjElIGluIDIwMjQsIGFjY29yZGluZyB0byBhIHJlcG9ydCBmcm9tIHRoZSBtaW5pc3RyeS6UjAZxdW90ZXOUXZSMCHBvc2l0aW9ulGgAjAhQb3NpdGlvbpSTlCmBlH2UKGgFfZQojAVzdGFydJRLAIwDZW5klEtujAR0ZXh0lE51aCl9lGgrj5QoaIFogmiDkGgtTnVijAdmaW5kaW5nlIwMY29udHJhZGljdGVklIwGc291cmNllIwHc3VwcG9ydJSMB3NuaXBwZXSUjBNUaGUgc291cmNlIHNheXMgc28ulIwJcmF0aW9uYWxllIwTVGhlIHBhZ2Ugc3RhdGVzIGl0LpSMDW1pc3NpbmdfcXVvdGWUTowUbWV0YWRhdGFfZGlmZmVyZW5jZXOUXZSMCnBhZ2VfdGl0bGWUjCdQYWdlIGF0IGh0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjAdmYWlsdXJllE51aCl9lGgrj5QoaHdojmhyaI9okWh2aHFojGh5aIhohmh0aIpok2h7kGgtTnViYYwRY2l0YXRpb25fZmFpbHVyZXOUXZSMC21vcmVfY2xhaW1zlF2UjBRtb3JlX2NsYWltX2xvY2F0aW9uc5RdlIwObW9yZV9jaXRhdGlvbnOUXZRok06MBmNsYWltc5RdlIwJY2l0YXRpb25zlF2UdWgpfZRoK4+UKGiYaGloEWgLaBVolmhnaC5onGheaA9oWmgNaJpoE2gJaEtoB2iTkGgtTnViLg==", + "review__get_citations_limit_exactly_at_limit.json": "gASV2w0AAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAowNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwGMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwGMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUSwKMEmNpdGF0aW9uc19zZWxlY3RlZJRLAowOY2l0YXRpb25fbGltaXSUSwKMFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUiYwPY2l0YXRpb25fY2hlY2tzlGgAjBlSZXZpZXdDaXRhdGlvbkNoZWNrQ291bnRzlJOUKYGUfZQoaAV9lCiMB2NoZWNrZWSUSwKMCXVuY2hlY2tlZJRLAGg/SwB1aCl9lGgrj5QoaFZoV2g/kGgtTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aE1oQmhbaE9oS2g1aE5oWmhQaExoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwNzaCl9lGgrj5QoaGSQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaEtdlIwIZmFpbHVyZXOUXZRoWl2UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUXZSMFG1vcmVfY2xhaW1fbG9jYXRpb25zlF2UjA5tb3JlX2NpdGF0aW9uc5RdlIwHZmFpbHVyZZROjAZjbGFpbXOUXZRoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCXBvc2l0aW9uc5ROjAZyZXN1bHSUaACMDFJldmlld1Jlc3VsdJSTlCmBlH2UKGgFfZQojAd2ZXJkaWN0lIwEVHJ1ZZRoIIwEaGlnaJSMBnNvdXJjZZSMCmFzc2Vzc21lbnSUjAhpc19pc3N1ZZSJdWgpfZRoK4+UKGggaIZoiWiLkGgtTnVijAphc3Nlc3NtZW50lGgAjBBSZXZpZXdBc3Nlc3NtZW50lJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGiGjARUcnVllGggjARoaWdolIwJcmF0aW9uYWxllE6MB2Rpc3NlbnSUTowQdmVyaWZpY2F0aW9uX3VybJROjAplcnJvcl9jb2RllE6MEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE6MEXN1Z2dlc3RlZF9yZXdyaXRllE5odE51aCl9lGgrj5QoaJ1omGiZaCBoC2iGaJtol2iaaJ5odJBoLU51YowKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAtkaXNwb3NpdGlvbpSMDG5vdF9zZWxlY3RlZJR1aCl9lGgrj5QoaKlop5BoLU51YowMdmVyaWZpY2F0aW9ulE6MD3N1Z2dlc3RlZF9lZGl0c5ROdWgpfZRoK4+UKGh9aI5ooWh8aK1ormiAaH+QaC1OdWJhjAljaXRhdGlvbnOUXZQoaACMDlJldmlld0NpdGF0aW9ulJOUKYGUfZQoaAV9lChofEsAjAlyZWZlcmVuY2WUjBphIHJlcG9ydCBmcm9tIHRoZSBtaW5pc3RyeZSMCWNpdGVkX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjANkb2mUTowJc3RhdGVtZW50lIxLVW5lbXBsb3ltZW50IGZlbGwgdG8gNC4xJSBpbiAyMDI0LCBhY2NvcmRpbmcgdG8gYSByZXBvcnQgZnJvbSB0aGUgbWluaXN0cnkulIwGcXVvdGVzlF2UjAhwb3NpdGlvbpRoAIwIUG9zaXRpb26Uk5QpgZR9lChoBX2UKIwFc3RhcnSUSwCMA2VuZJRLbowEdGV4dJROdWgpfZRoK4+UKGjHaMhoyZBoLU51YmiAaACMFFJldmlld0NpdGF0aW9uUmVzdWx0lJOUKYGUfZQoaAV9lCiMB2ZpbmRpbmeUjAlzdXBwb3J0ZWSUaImMB3N1cHBvcnSUaIuJdWgpfZRoK4+UKGjRaItoiZBoLU51YowFY2hlY2uUaACME1Jldmlld0NpdGF0aW9uQ2hlY2uUk5QpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUjAlwYWdlX3JlYWSUjARmdWxslIwKcGFnZV90aXRsZZSMJ1BhZ2UgYXQgaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSME3BhZ2VfcHVibGlzaGVkX2RhdGWUTowNcGFnZV9sYW5ndWFnZZSMAmVulIwKc291cmNlX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjA5zb3VyY2VfdmVyc2lvbpROjAdzdXBwb3J0lIwJc3VwcG9ydGVklIwHc25pcHBldJSME1RoZSBzb3VyY2Ugc2F5cyBzby6UaJeME1RoZSBwYWdlIHN0YXRlcyBpdC6UjAVxdW90ZZROjA1taXNzaW5nX3F1b3RllE6MDmRvaV9yZWdpc3RlcmVklE6MCG1ldGFkYXRhlE6MFG1ldGFkYXRhX2RpZmZlcmVuY2VzlF2UjApyZWdpc3RlcmVklE6MEHVuY2hlY2tlZF9yZWFzb26UTmidTmh0TnVoKX2UaCuPlCho4WjzaJdo4mjkaJ1o7mjvaAto7WjwaOxo32jyaOdo3WjmaOlodJBoLU51YnVoKX2UaCuPlChovWiAaLho1mh8aLxov2i6aMGQaC1OdWJotCmBlH2UKGgFfZQoaHxLAWi4jAthIHN0YXRlbWVudJRouowdaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaLxOaL2MIlRoZSBhZ2VuY3kgc2FpZCBzbyBpbiBhIHN0YXRlbWVudC6UaL9dlGjBaMMpgZR9lChoBX2UKGjHS29oyEuyaMlOdWgpfZRoK4+UKGjHaMhoyZBoLU51YmiAaM0pgZR9lChoBX2UKGjRjAlzdXBwb3J0ZWSUaImMB3N1cHBvcnSUaIuJdWgpfZRoK4+UKGjRaItoiZBoLU51YmjWaNgpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaN2MBGZ1bGyUaN+MJVBhZ2UgYXQgaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaOFOaOKMAmVulGjkjB1odHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRo5k5o54wJc3VwcG9ydGVklGjpjBNUaGUgc291cmNlIHNheXMgc28ulGiXjBNUaGUgcGFnZSBzdGF0ZXMgaXQulGjsTmjtTmjuTmjvTmjwXZRo8k5o805onU5odE51aCl9lGgrj5QoaOFo82iXaOJo5GidaO5o72gLaO1o8GjsaN9o8mjnaN1o5mjpaHSQaC1OdWJ1aCl9lGgrj5QoaL1ogGi4aNZofGi8aL9oumjBkGgtTnViZXVoKX2UaCuPlChobmhpaBFoC2gVaGxoZ2guaHJoXmgPaFpodWgNaHBoE2gJaLFoS2gHaHSQaC1OdWIu", + "review__get_citations_limit_reached.json": "gASVqQwAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAYwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwGMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwGMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUSwKMEmNpdGF0aW9uc19zZWxlY3RlZJRLAYwOY2l0YXRpb25fbGltaXSUSwGMFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUiIwPY2l0YXRpb25fY2hlY2tzlGgAjBlSZXZpZXdDaXRhdGlvbkNoZWNrQ291bnRzlJOUKYGUfZQoaAV9lCiMB2NoZWNrZWSUSwGMCXVuY2hlY2tlZJRLAGg/SwB1aCl9lGgrj5QoaFZoV2g/kGgtTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aE1oQmhbaE9oS2g1aE5oWmhQaExoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwJzaCl9lGgrj5QoaGSQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaEtdlIwIZmFpbHVyZXOUXZRoWl2UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUXZSMFG1vcmVfY2xhaW1fbG9jYXRpb25zlF2UjA5tb3JlX2NpdGF0aW9uc5RdlGgAjBJSZXZpZXdNb3JlQ2l0YXRpb26Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwGMCXJlZmVyZW5jZZSMC2Egc3RhdGVtZW50lIwJY2l0ZWRfdXJslIwdaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUjANkb2mUTowIc2VudGVuY2WUjCJUaGUgYWdlbmN5IHNhaWQgc28gaW4gYSBzdGF0ZW1lbnQulIwIcG9zaXRpb26UaACMCFBvc2l0aW9ulJOUKYGUfZQoaAV9lCiMBXN0YXJ0lEtvjANlbmSUS7KMBHRleHSUTnVoKX2UaCuPlChoh2iIaImQaC1OdWJ1aCl9lGgrj5QoaHpof2h5aH5ofGiBkGgtTnViYYwHZmFpbHVyZZROjAZjbGFpbXOUXZRoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKGh5SwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCXBvc2l0aW9uc5ROjAZyZXN1bHSUaACMDFJldmlld1Jlc3VsdJSTlCmBlH2UKGgFfZQojAd2ZXJkaWN0lIwEVHJ1ZZRoIIwEaGlnaJSMBnNvdXJjZZSMCmFzc2Vzc21lbnSUjAhpc19pc3N1ZZSJdWgpfZRoK4+UKGggaJ9oomikkGgtTnVijAphc3Nlc3NtZW50lGgAjBBSZXZpZXdBc3Nlc3NtZW50lJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGifjARUcnVllGggjARoaWdolIwJcmF0aW9uYWxllE6MB2Rpc3NlbnSUTowQdmVyaWZpY2F0aW9uX3VybJROjAplcnJvcl9jb2RllE6MEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE6MEXN1Z2dlc3RlZF9yZXdyaXRllE5ojk51aCl9lGgrj5QoaLZosWiyaCBoC2ifaLRosGizaLdojpBoLU51YowKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAtkaXNwb3NpdGlvbpSMDG5vdF9zZWxlY3RlZJR1aCl9lGgrj5QoaMJowJBoLU51YowMdmVyaWZpY2F0aW9ulE6MD3N1Z2dlc3RlZF9lZGl0c5ROdWgpfZRoK4+UKGiWaKdoumh5aMZox2iZaJiQaC1OdWJhjAljaXRhdGlvbnOUXZRoAIwOUmV2aWV3Q2l0YXRpb26Uk5QpgZR9lChoBX2UKGh5SwBoeowaYSByZXBvcnQgZnJvbSB0aGUgbWluaXN0cnmUaHyMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUaH5OjAlzdGF0ZW1lbnSUjEtVbmVtcGxveW1lbnQgZmVsbCB0byA0LjElIGluIDIwMjQsIGFjY29yZGluZyB0byBhIHJlcG9ydCBmcm9tIHRoZSBtaW5pc3RyeS6UjAZxdW90ZXOUXZRogWiDKYGUfZQoaAV9lChoh0sAaIhLbmiJTnVoKX2UaCuPlChoh2iIaImQaC1OdWJomWgAjBRSZXZpZXdDaXRhdGlvblJlc3VsdJSTlCmBlH2UKGgFfZQojAdmaW5kaW5nlIwJc3VwcG9ydGVklGiijAdzdXBwb3J0lGikiXVoKX2UaCuPlCho4WikaKKQaC1OdWKMBWNoZWNrlGgAjBNSZXZpZXdDaXRhdGlvbkNoZWNrlJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklIwJcGFnZV9yZWFklIwEZnVsbJSMCnBhZ2VfdGl0bGWUjCdQYWdlIGF0IGh0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjBNwYWdlX3B1Ymxpc2hlZF9kYXRllE6MDXBhZ2VfbGFuZ3VhZ2WUjAJlbpSMCnNvdXJjZV91cmyUjB9odHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwOc291cmNlX3ZlcnNpb26UTowHc3VwcG9ydJSMCXN1cHBvcnRlZJSMB3NuaXBwZXSUjBNUaGUgc291cmNlIHNheXMgc28ulGiwjBNUaGUgcGFnZSBzdGF0ZXMgaXQulIwFcXVvdGWUTowNbWlzc2luZ19xdW90ZZROjA5kb2lfcmVnaXN0ZXJlZJROjAhtZXRhZGF0YZROjBRtZXRhZGF0YV9kaWZmZXJlbmNlc5RdlIwKcmVnaXN0ZXJlZJROjBB1bmNoZWNrZWRfcmVhc29ulE5otk5ojk51aCl9lGgrj5QoaPFqAwEAAGiwaPJo9Gi2aP5o/2gLaP1qAAEAAGj8aO9qAgEAAGj3aO1o9mj5aI6QaC1OdWJ1aCl9lGgrj5QoaNNomWh6aOZoeWh+aNVofGiBkGgtTnViYXVoKX2UaCuPlChobmhpaBFoC2gVaGxoZ2guaHJoXmgPaFpoj2gNaHBoE2gJaMpoS2gHaI6QaC1OdWIu", + "review__get_citations_no_claim_but_citations.json": "gASVkAsAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLFIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwCMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwCMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUSwKMEmNpdGF0aW9uc19zZWxlY3RlZJRLAowOY2l0YXRpb25fbGltaXSUSxSMFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUiYwPY2l0YXRpb25fY2hlY2tzlGgAjBlSZXZpZXdDaXRhdGlvbkNoZWNrQ291bnRzlJOUKYGUfZQoaAV9lCiMB2NoZWNrZWSUSwKMCXVuY2hlY2tlZJRLAGg/SwB1aCl9lGgrj5QoaFZoV2g/kGgtTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aE1oQmhbaE9oS2g1aE5oWmhQaExoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwJzaCl9lGgrj5QoaGSQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaEtdlIwIZmFpbHVyZXOUXZRoWl2UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUXZSMFG1vcmVfY2xhaW1fbG9jYXRpb25zlF2UjA5tb3JlX2NpdGF0aW9uc5RdlIwHZmFpbHVyZZROjAZjbGFpbXOUXZSMCWNpdGF0aW9uc5RdlChoAIwOUmV2aWV3Q2l0YXRpb26Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMCXJlZmVyZW5jZZSMGmEgcmVwb3J0IGZyb20gdGhlIG1pbmlzdHJ5lIwJY2l0ZWRfdXJslIwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSMA2RvaZROjAlzdGF0ZW1lbnSUjEtVbmVtcGxveW1lbnQgZmVsbCB0byA0LjElIGluIDIwMjQsIGFjY29yZGluZyB0byBhIHJlcG9ydCBmcm9tIHRoZSBtaW5pc3RyeS6UjAZxdW90ZXOUXZSMCHBvc2l0aW9ulGgAjAhQb3NpdGlvbpSTlCmBlH2UKGgFfZQojAVzdGFydJRLAIwDZW5klEtujAR0ZXh0lE51aCl9lGgrj5QoaI5oj2iQkGgtTnVijAZyZXN1bHSUaACMFFJldmlld0NpdGF0aW9uUmVzdWx0lJOUKYGUfZQoaAV9lCiMB2ZpbmRpbmeUjAlzdXBwb3J0ZWSUjAZzb3VyY2WUjAdzdXBwb3J0lIwIaXNfaXNzdWWUiXVoKX2UaCuPlChomWidaJuQaC1OdWKMBWNoZWNrlGgAjBNSZXZpZXdDaXRhdGlvbkNoZWNrlJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklIwJcGFnZV9yZWFklIwEZnVsbJSMCnBhZ2VfdGl0bGWUjCdQYWdlIGF0IGh0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjBNwYWdlX3B1Ymxpc2hlZF9kYXRllE6MDXBhZ2VfbGFuZ3VhZ2WUjAJlbpSMCnNvdXJjZV91cmyUjB9odHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwOc291cmNlX3ZlcnNpb26UTowHc3VwcG9ydJSMCXN1cHBvcnRlZJSMB3NuaXBwZXSUjBNUaGUgc291cmNlIHNheXMgc28ulIwJcmF0aW9uYWxllIwTVGhlIHBhZ2Ugc3RhdGVzIGl0LpSMBXF1b3RllE6MDW1pc3NpbmdfcXVvdGWUTowOZG9pX3JlZ2lzdGVyZWSUTowIbWV0YWRhdGGUTowUbWV0YWRhdGFfZGlmZmVyZW5jZXOUXZSMCnJlZ2lzdGVyZWSUTowQdW5jaGVja2VkX3JlYXNvbpROjARoaW50lE5odE51aCl9lGgrj5QoaKtovmi1aKxormi/aLloumgLaLhou2i3aKlovWixaKdosGizaHSQaC1OdWJ1aCl9lGgrj5QoaIRok2h/aKBofmiDaIZogWiIkGgtTnViaHopgZR9lChoBX2UKGh+SwFof4wLYSBzdGF0ZW1lbnSUaIGMHWh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGiDTmiEjCJUaGUgYWdlbmN5IHNhaWQgc28gaW4gYSBzdGF0ZW1lbnQulGiGXZRoiGiKKYGUfZQoaAV9lChojktvaI9LsmiQTnVoKX2UaCuPlChojmiPaJCQaC1OdWJok2iVKYGUfZQoaAV9lChomYwJc3VwcG9ydGVklGibjAdzdXBwb3J0lGidiXVoKX2UaCuPlChomWidaJuQaC1OdWJooGiiKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGinjARmdWxslGipjCVQYWdlIGF0IGh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGirTmisjAJlbpRorowdaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaLBOaLGMCXN1cHBvcnRlZJRos4wTVGhlIHNvdXJjZSBzYXlzIHNvLpRotYwTVGhlIHBhZ2Ugc3RhdGVzIGl0LpRot05ouE5ouU5ouk5ou12UaL1OaL5OaL9OaHROdWgpfZRoK4+UKGiraL5otWisaK5ov2i5aLpoC2i4aLtot2ipaL1osWinaLBos2h0kGgtTnVidWgpfZRoK4+UKGiEaJNof2igaH5og2iGaIFoiJBoLU51YmV1aCl9lGgrj5QoaG5oaWgRaAtoFWhsaGdoLmhyaF5oD2haaHVoDWhwaBNoCWh3aEtoB2h0kGgtTnViLg==", + "review__get_citations_no_claim_no_citation.json": "gASV+AUAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwGZmFpbGVklIwHb3V0Y29tZZSMCXVuY2hlY2tlZJSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjAhsYW5ndWFnZZSMAmVulIwGcG9saWN5lGgAjBBFc2NhbGF0aW9uUG9saWN5lJOUKYGUfZQoaAV9lCiMCHZlcmRpY3RzlF2UKIwFRmFsc2WUjAxNb3N0bHkgRmFsc2WUjAVNaXhlZJRljApjb25maWRlbmNllF2UjANsb3eUYYwPbWF4X2Fzc2Vzc21lbnRzlEsUjBFtYXhfdmVyaWZpY2F0aW9uc5RLBYwFZGVwdGiUjAhzdGFuZGFyZJSMDW1heF9jaXRhdGlvbnOUSxSMDXN1Z2dlc3RfZWRpdHOUiXWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBtoJWggaCdoKGgkaCOQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMB3N1bW1hcnmUaACMDVJldmlld1N1bW1hcnmUk5QpgZR9lChoBX2UKIwPY2xhaW1zX3NlbGVjdGVklE6MC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklE6MD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5ROjA12ZXJpZmljYXRpb25zlE6MBmlzc3Vlc5RLAIwPY2l0YXRpb25zX2ZvdW5klE6MEmNpdGF0aW9uc19zZWxlY3RlZJROjA5jaXRhdGlvbl9saW1pdJRLFIwWY2l0YXRpb25fbGltaXRfcmVhY2hlZJROjA9jaXRhdGlvbl9jaGVja3OUTowPY2l0YXRpb25faXNzdWVzlEsAjBFjaXRhdGlvbnNfc2tpcHBlZJROdWgpfZRoK4+UKGg0aDhoN2g8aDloQWg+aDpoNWg9aEBoP2g7aDaQaC1OdWKMB2NyZWRpdHOUaACMDVJldmlld0NyZWRpdHOUk5QpgZR9lChoBX2UjAdjaGFyZ2VklEsAc2gpfZRoK4+UKGhKkGgtTnVijBJwb2xsX2FmdGVyX3NlY29uZHOUTmg6XZSMCGZhaWx1cmVzlF2UaEBdlIwRY2l0YXRpb25fZmFpbHVyZXOUXZSMC21vcmVfY2xhaW1zlE6MFG1vcmVfY2xhaW1fbG9jYXRpb25zlE6MDm1vcmVfY2l0YXRpb25zlE6MB2ZhaWx1cmWUaACMDEZhaWx1cmVCbG9ja5STlCmBlH2UKGgFfZQojA5mYWlsdXJlX3JlYXNvbpSMCG5vX2NsYWltlIwNZmFpbHVyZV9jbGFzc5SMDWludmFsaWRfaW5wdXSUjAlyZXRyeWFibGWUiYwEaGludJSMo05vIGZhY3R1YWwgc3RhdGVtZW50IHRoYXQgY2FuIGJlIGNoZWNrZWQgYWdhaW5zdCBldmlkZW5jZSB3YXMgZm91bmQgaW4gdGhlIGlucHV0LiBTZW5kIG9uZSBmYWN0dWFsIGNsYWltLCBvciBydW4gdGhlIHRleHQgdGhyb3VnaCAvZXh0cmFjdCB0byBlbnVtZXJhdGUgaXRzIGNsYWltcy6UjAhkb2NzX3VybJSMKWh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyNpbnZhbGlkLWlucHV0lHVoKX2UaCuPlChoYmhdaGRoX2hhkGgtTnVijAZjbGFpbXOUXZSMCWNpdGF0aW9uc5RdlHVoKX2UaCuPlChoVGhPaBFoC2gVaFJoTWguaFZoRGgPaEBoaGgNaFVoE2gJaGpoOmgHaFeQaC1OdWIu", + "review__get_citations_not_asked.json": "gASVtAcAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwGMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwGMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lE6MFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUTowPY2l0YXRpb25fY2hlY2tzlE6MD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoKX2UaCuPlChoNGg4aDdoTWhCaFJoT2hLaDVoTmhRaFBoTGg2kGgtTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAXNoKX2UaCuPlChoW5BoLU51YowScG9sbF9hZnRlcl9zZWNvbmRzlE5oS12UjAhmYWlsdXJlc5RdlGhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UjAdmYWlsdXJllE6MBmNsYWltc5RdlGgAjAtSZXZpZXdDbGFpbZSTlCmBlH2UKGgFfZQojAVpbmRleJRLAIwFY2xhaW2UjChUaGUgRVUgQUkgQWN0IHRvb2sgZWZmZWN0IGluIE1hcmNoIDIwMjQulIwJcG9zaXRpb25zlE6MBnJlc3VsdJRoAIwMUmV2aWV3UmVzdWx0lJOUKYGUfZQoaAV9lCiMB3ZlcmRpY3SUjARUcnVllGggjARoaWdolIwGc291cmNllIwKYXNzZXNzbWVudJSMCGlzX2lzc3VllIl1aCl9lGgrj5QoaCBofWiAaIKQaC1OdWKMCmFzc2Vzc21lbnSUaACMEFJldmlld0Fzc2Vzc21lbnSUk5QpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaH2MBFRydWWUaCCMBGhpZ2iUjAlyYXRpb25hbGWUTowHZGlzc2VudJROjBB2ZXJpZmljYXRpb25fdXJslE6MCmVycm9yX2NvZGWUTowRaWRlbnRpZmllZF9jbGFpbXOUXZSMBGhpbnSUTowRc3VnZ2VzdGVkX3Jld3JpdGWUTmhrTnVoKX2UaCuPlCholGiPaJBoIGgLaH1okmiOaJFolWhrkGgtTnVijAplc2NhbGF0aW9ulGgAjApFc2NhbGF0aW9ulJOUKYGUfZQoaAV9lCiMDW1hdGNoZWRfcnVsZXOUXZSMC2Rpc3Bvc2l0aW9ulIwMbm90X3NlbGVjdGVklHVoKX2UaCuPlChooGiekGgtTnVijAx2ZXJpZmljYXRpb26UTowPc3VnZ2VzdGVkX2VkaXRzlE51aCl9lGgrj5QoaHRohWiYaHNopGilaHdodpBoLU51YmGMCWNpdGF0aW9uc5RdlHVoKX2UaCuPlChoZWhgaBFoC2gVaGNoXmguaGloVWgPaFFobGgNaGdoE2gJaKhoS2gHaGuQaC1OdWIu", + "review__get_citations_only.json": "gASVMAwAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSwCMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLFIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwCMC2NsYWltX2xpbWl0lEsAjBNjbGFpbV9saW1pdF9yZWFjaGVklIiMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwCMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUSwKMEmNpdGF0aW9uc19zZWxlY3RlZJRLAowOY2l0YXRpb25fbGltaXSUSxSMFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUiYwPY2l0YXRpb25fY2hlY2tzlGgAjBlSZXZpZXdDaXRhdGlvbkNoZWNrQ291bnRzlJOUKYGUfZQoaAV9lCiMB2NoZWNrZWSUSwKMCXVuY2hlY2tlZJRLAGg/SwB1aCl9lGgrj5QoaFZoV2g/kGgtTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aE1oQmhbaE9oS2g1aE5oWmhQaExoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwJzaCl9lGgrj5QoaGSQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaEtdlIwIZmFpbHVyZXOUXZRoWl2UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUXZSMKFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UYYwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZRoAIwNQ2xhaW1Mb2NhdGlvbpSTlCmBlH2UKGgFfZQojAVjbGFpbZSMKFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UjAlwb3NpdGlvbnOUTnVoKX2UaCuPlChoeGh6kGgtTnViYYwObW9yZV9jaXRhdGlvbnOUXZSMB2ZhaWx1cmWUTowGY2xhaW1zlF2UjAljaXRhdGlvbnOUXZQoaACMDlJldmlld0NpdGF0aW9ulJOUKYGUfZQoaAV9lCiMBWluZGV4lEsAjAlyZWZlcmVuY2WUjBphIHJlcG9ydCBmcm9tIHRoZSBtaW5pc3RyeZSMCWNpdGVkX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjANkb2mUTowJc3RhdGVtZW50lIxLVW5lbXBsb3ltZW50IGZlbGwgdG8gNC4xJSBpbiAyMDI0LCBhY2NvcmRpbmcgdG8gYSByZXBvcnQgZnJvbSB0aGUgbWluaXN0cnkulIwGcXVvdGVzlF2UjAhwb3NpdGlvbpRoAIwIUG9zaXRpb26Uk5QpgZR9lChoBX2UKIwFc3RhcnSUSwCMA2VuZJRLbowEdGV4dJROdWgpfZRoK4+UKGiZaJpom5BoLU51YowGcmVzdWx0lGgAjBRSZXZpZXdDaXRhdGlvblJlc3VsdJSTlCmBlH2UKGgFfZQojAdmaW5kaW5nlIwJc3VwcG9ydGVklIwGc291cmNllIwHc3VwcG9ydJSMCGlzX2lzc3VllIl1aCl9lGgrj5QoaKRoqGimkGgtTnVijAVjaGVja5RoAIwTUmV2aWV3Q2l0YXRpb25DaGVja5STlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJSMCXBhZ2VfcmVhZJSMBGZ1bGyUjApwYWdlX3RpdGxllIwnUGFnZSBhdCBodHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwTcGFnZV9wdWJsaXNoZWRfZGF0ZZROjA1wYWdlX2xhbmd1YWdllIwCZW6UjApzb3VyY2VfdXJslIwfaHR0cHM6Ly9leGFtcGxlLmdvdi9yZXBvcnQtMjAyNJSMDnNvdXJjZV92ZXJzaW9ulE6MB3N1cHBvcnSUjAlzdXBwb3J0ZWSUjAdzbmlwcGV0lIwTVGhlIHNvdXJjZSBzYXlzIHNvLpSMCXJhdGlvbmFsZZSME1RoZSBwYWdlIHN0YXRlcyBpdC6UjAVxdW90ZZROjA1taXNzaW5nX3F1b3RllE6MDmRvaV9yZWdpc3RlcmVklE6MCG1ldGFkYXRhlE6MFG1ldGFkYXRhX2RpZmZlcmVuY2VzlF2UjApyZWdpc3RlcmVklE6MEHVuY2hlY2tlZF9yZWFzb26UTowEaGludJROaH9OdWgpfZRoK4+UKGi2aMlowGi3aLloymjEaMVoC2jDaMZowmi0aMhovGiyaLtovmh/kGgtTnVidWgpfZRoK4+UKGiPaJ5oimiraIlojmiRaIxok5BoLU51YmiFKYGUfZQoaAV9lChoiUsBaIqMC2Egc3RhdGVtZW50lGiMjB1odHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRojk5oj4wiVGhlIGFnZW5jeSBzYWlkIHNvIGluIGEgc3RhdGVtZW50LpRokV2UaJNolSmBlH2UKGgFfZQoaJlLb2iaS7Jom051aCl9lGgrj5QoaJlommibkGgtTnViaJ5ooCmBlH2UKGgFfZQoaKSMCXN1cHBvcnRlZJRopowHc3VwcG9ydJRoqIl1aCl9lGgrj5QoaKRoqGimkGgtTnViaKtorSmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJRosowEZnVsbJRotIwlUGFnZSBhdCBodHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRotk5ot4wCZW6UaLmMHWh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGi7Tmi8jAlzdXBwb3J0ZWSUaL6ME1RoZSBzb3VyY2Ugc2F5cyBzby6UaMCME1RoZSBwYWdlIHN0YXRlcyBpdC6UaMJOaMNOaMROaMVOaMZdlGjITmjJTmjKTmh/TnVoKX2UaCuPlChotmjJaMBot2i5aMpoxGjFaAtow2jGaMJotGjIaLxosmi7aL5of5BoLU51YnVoKX2UaCuPlChoj2ieaIpoq2iJaI5okWiMaJOQaC1OdWJldWgpfZRoK4+UKGhuaGloEWgLaBVobGhnaC5ofWheaA9oWmiAaA1ocWgTaAlogmhLaAdof5BoLU51Yi4=", + "review__get_citations_partly_supported.json": "gASV6Q0AAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLFIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwGMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwGMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUSwKMEmNpdGF0aW9uc19zZWxlY3RlZJRLAowOY2l0YXRpb25fbGltaXSUSxSMFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUiYwPY2l0YXRpb25fY2hlY2tzlGgAjBlSZXZpZXdDaXRhdGlvbkNoZWNrQ291bnRzlJOUKYGUfZQoaAV9lCiMB2NoZWNrZWSUSwKMCXVuY2hlY2tlZJRLAGg/SwB1aCl9lGgrj5QoaFZoV2g/kGgtTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aE1oQmhbaE9oS2g1aE5oWmhQaExoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwNzaCl9lGgrj5QoaGSQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaEtdlIwIZmFpbHVyZXOUXZRoWl2UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUXZSMFG1vcmVfY2xhaW1fbG9jYXRpb25zlF2UjA5tb3JlX2NpdGF0aW9uc5RdlIwHZmFpbHVyZZROjAZjbGFpbXOUXZRoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCXBvc2l0aW9uc5ROjAZyZXN1bHSUaACMDFJldmlld1Jlc3VsdJSTlCmBlH2UKGgFfZQojAd2ZXJkaWN0lIwEVHJ1ZZRoIIwEaGlnaJSMBnNvdXJjZZSMCmFzc2Vzc21lbnSUjAhpc19pc3N1ZZSJdWgpfZRoK4+UKGggaIZoiWiLkGgtTnVijAphc3Nlc3NtZW50lGgAjBBSZXZpZXdBc3Nlc3NtZW50lJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGiGjARUcnVllGggjARoaWdolIwJcmF0aW9uYWxllE6MB2Rpc3NlbnSUTowQdmVyaWZpY2F0aW9uX3VybJROjAplcnJvcl9jb2RllE6MEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE6MEXN1Z2dlc3RlZF9yZXdyaXRllE5odE51aCl9lGgrj5QoaJ1omGiZaCBoC2iGaJtol2iaaJ5odJBoLU51YowKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAtkaXNwb3NpdGlvbpSMDG5vdF9zZWxlY3RlZJR1aCl9lGgrj5QoaKlop5BoLU51YowMdmVyaWZpY2F0aW9ulE6MD3N1Z2dlc3RlZF9lZGl0c5ROdWgpfZRoK4+UKGh9aI5ooWh8aK1ormiAaH+QaC1OdWJhjAljaXRhdGlvbnOUXZQoaACMDlJldmlld0NpdGF0aW9ulJOUKYGUfZQoaAV9lChofEsAjAlyZWZlcmVuY2WUjBphIHJlcG9ydCBmcm9tIHRoZSBtaW5pc3RyeZSMCWNpdGVkX3VybJSMH2h0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjANkb2mUTowJc3RhdGVtZW50lIxLVW5lbXBsb3ltZW50IGZlbGwgdG8gNC4xJSBpbiAyMDI0LCBhY2NvcmRpbmcgdG8gYSByZXBvcnQgZnJvbSB0aGUgbWluaXN0cnkulIwGcXVvdGVzlF2UjAhwb3NpdGlvbpRoAIwIUG9zaXRpb26Uk5QpgZR9lChoBX2UKIwFc3RhcnSUSwCMA2VuZJRLbowEdGV4dJROdWgpfZRoK4+UKGjHaMhoyZBoLU51YmiAaACMFFJldmlld0NpdGF0aW9uUmVzdWx0lJOUKYGUfZQoaAV9lCiMB2ZpbmRpbmeUjBBwYXJ0bHlfc3VwcG9ydGVklGiJjAdzdXBwb3J0lGiLiXVoKX2UaCuPlCho0WiLaImQaC1OdWKMBWNoZWNrlGgAjBNSZXZpZXdDaXRhdGlvbkNoZWNrlJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklIwJcGFnZV9yZWFklIwEZnVsbJSMCnBhZ2VfdGl0bGWUjCdQYWdlIGF0IGh0dHBzOi8vZXhhbXBsZS5nb3YvcmVwb3J0LTIwMjSUjBNwYWdlX3B1Ymxpc2hlZF9kYXRllE6MDXBhZ2VfbGFuZ3VhZ2WUjAJlbpSMCnNvdXJjZV91cmyUjB9odHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwOc291cmNlX3ZlcnNpb26UTowHc3VwcG9ydJSMEHBhcnRseV9zdXBwb3J0ZWSUjAdzbmlwcGV0lIwTVGhlIHNvdXJjZSBzYXlzIHNvLpRol4wTVGhlIHBhZ2Ugc3RhdGVzIGl0LpSMBXF1b3RllE6MDW1pc3NpbmdfcXVvdGWUTowOZG9pX3JlZ2lzdGVyZWSUTowIbWV0YWRhdGGUTowUbWV0YWRhdGFfZGlmZmVyZW5jZXOUXZSMCnJlZ2lzdGVyZWSUTowQdW5jaGVja2VkX3JlYXNvbpROaJ1OaHROdWgpfZRoK4+UKGjhaPNol2jiaORonWjuaO9oC2jtaPBo7GjfaPJo52jdaOZo6Wh0kGgtTnVidWgpfZRoK4+UKGi9aIBouGjWaHxovGi/aLpowZBoLU51Ymi0KYGUfZQoaAV9lChofEsBaLiMC2Egc3RhdGVtZW50lGi6jB1odHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRovE5ovYwiVGhlIGFnZW5jeSBzYWlkIHNvIGluIGEgc3RhdGVtZW50LpRov12UaMFowymBlH2UKGgFfZQoaMdLb2jIS7JoyU51aCl9lGgrj5QoaMdoyGjJkGgtTnViaIBozSmBlH2UKGgFfZQoaNGMCXN1cHBvcnRlZJRoiYwHc3VwcG9ydJRoi4l1aCl9lGgrj5QoaNFoi2iJkGgtTnViaNZo2CmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJRo3YwEZnVsbJRo34wlUGFnZSBhdCBodHRwczovL2V4YW1wbGUub3JnL3N0YXRlbWVudJRo4U5o4owCZW6UaOSMHWh0dHBzOi8vZXhhbXBsZS5vcmcvc3RhdGVtZW50lGjmTmjnjAlzdXBwb3J0ZWSUaOmME1RoZSBzb3VyY2Ugc2F5cyBzby6UaJeME1RoZSBwYWdlIHN0YXRlcyBpdC6UaOxOaO1OaO5OaO9OaPBdlGjyTmjzTmidTmh0TnVoKX2UaCuPlCho4WjzaJdo4mjkaJ1o7mjvaAto7WjwaOxo32jyaOdo3WjmaOlodJBoLU51YnVoKX2UaCuPlChovWiAaLho1mh8aLxov2i6aMGQaC1OdWJldWgpfZRoK4+UKGhuaGloEWgLaBVobGhnaC5ocmheaA9oWmh1aA1ocGgTaAlosWhLaAdodJBoLU51Yi4=", + "review__get_citations_running.json": "gASVIAsAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJdmVyaWZ5aW5nlIwHb3V0Y29tZZROjApjcmVhdGVkX2F0lIwbMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTZalIwMY29tcGxldGVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLFIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGWgjaB5oJWgmaCJoIZCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwGMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwGMBmZhaWxlZJRLAHVoJ32UaCmPlChoPGg9kGgrTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg8SwBoPUsAdWgnfZRoKY+UKGg8aD1oRpBoK051YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUSwKMEmNpdGF0aW9uc19zZWxlY3RlZJRLAowOY2l0YXRpb25fbGltaXSUSxSMFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUiYwPY2l0YXRpb25fY2hlY2tzlGgAjBlSZXZpZXdDaXRhdGlvbkNoZWNrQ291bnRzlJOUKYGUfZQoaAV9lCiMB2NoZWNrZWSUSwCMCXVuY2hlY2tlZJRLAGg9SwB1aCd9lGgpj5QoaFRoVWg9kGgrTnVijA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCd9lGgpj5QoaDJoNmg1aEtoQGhZaE1oSWgzaExoWGhOaEpoNJBoK051YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwFzaCd9lGgpj5QoaGKQaCtOdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5RLD2hJXZSMCGZhaWx1cmVzlF2UaFhdlIwRY2l0YXRpb25fZmFpbHVyZXOUXZSMC21vcmVfY2xhaW1zlF2UjBRtb3JlX2NsYWltX2xvY2F0aW9uc5RdlIwObW9yZV9jaXRhdGlvbnOUXZSMB2ZhaWx1cmWUTowGY2xhaW1zlF2UaACMC1Jldmlld0NsYWltlJOUKYGUfZQoaAV9lCiMBWluZGV4lEsAjAVjbGFpbZSMKFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UjAlwb3NpdGlvbnOUTowGcmVzdWx0lGgAjAxSZXZpZXdSZXN1bHSUk5QpgZR9lChoBX2UKIwHdmVyZGljdJSMBFRydWWUaB6MBGhpZ2iUjAZzb3VyY2WUjAphc3Nlc3NtZW50lIwIaXNfaXNzdWWUiXVoJ32UaCmPlChoHmiEaIdoiZBoK051YowKYXNzZXNzbWVudJRoAIwQUmV2aWV3QXNzZXNzbWVudJSTlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJRohIwEVHJ1ZZRoHowEaGlnaJSMCXJhdGlvbmFsZZROjAdkaXNzZW50lE6MEHZlcmlmaWNhdGlvbl91cmyUTowKZXJyb3JfY29kZZROjBFpZGVudGlmaWVkX2NsYWltc5RdlIwEaGludJROjBFzdWdnZXN0ZWRfcmV3cml0ZZROaHJOdWgnfZRoKY+UKGibaJZol2geaAtohGiZaJVomGicaHKQaCtOdWKMCmVzY2FsYXRpb26UaACMCkVzY2FsYXRpb26Uk5QpgZR9lChoBX2UKIwNbWF0Y2hlZF9ydWxlc5RdlIwLZGlzcG9zaXRpb26UjAxub3Rfc2VsZWN0ZWSUdWgnfZRoKY+UKGinaKWQaCtOdWKMDHZlcmlmaWNhdGlvbpROjA9zdWdnZXN0ZWRfZWRpdHOUTnVoJ32UaCmPlChoe2iMaJ9oemiraKxofmh9kGgrTnViYYwJY2l0YXRpb25zlF2UKGgAjA5SZXZpZXdDaXRhdGlvbpSTlCmBlH2UKGgFfZQoaHpLAIwJcmVmZXJlbmNllIwaYSByZXBvcnQgZnJvbSB0aGUgbWluaXN0cnmUjAljaXRlZF91cmyUjB9odHRwczovL2V4YW1wbGUuZ292L3JlcG9ydC0yMDI0lIwDZG9plE6MCXN0YXRlbWVudJROjAZxdW90ZXOUXZSMCHBvc2l0aW9ulE5ofk6MBWNoZWNrlGgAjBNSZXZpZXdDaXRhdGlvbkNoZWNrlJOUKYGUfZQoaAV9lChoC4wHcGVuZGluZ5SMCXBhZ2VfcmVhZJROjApwYWdlX3RpdGxllE6ME3BhZ2VfcHVibGlzaGVkX2RhdGWUTowNcGFnZV9sYW5ndWFnZZROjApzb3VyY2VfdXJslE6MDnNvdXJjZV92ZXJzaW9ulE6MB3N1cHBvcnSUTowHc25pcHBldJROaJVOjAVxdW90ZZROjA1taXNzaW5nX3F1b3RllE6MDmRvaV9yZWdpc3RlcmVklE6MCG1ldGFkYXRhlE6MFG1ldGFkYXRhX2RpZmZlcmVuY2VzlF2UjApyZWdpc3RlcmVklE6MEHVuY2hlY2tlZF9yZWFzb26UTmibTmhyTnVoJ32UaCmPlChoyGjVaJVoyWjKaJto0GjRaAtoz2jSaM5ox2jUaMxoxmjLaM1ocpBoK051YnVoJ32UaCmPlChou2h+aLZov2h6aLpovGi4aL6QaCtOdWJosimBlH2UKGgFfZQoaHpLAWi2jAthIHN0YXRlbWVudJRouIwdaHR0cHM6Ly9leGFtcGxlLm9yZy9zdGF0ZW1lbnSUaLpOaLtOaLxdlGi+Tmh+Tmi/aMEpgZR9lChoBX2UKGgLjAdwZW5kaW5nlGjGTmjHTmjITmjJTmjKTmjLTmjMTmjNTmiVTmjOTmjPTmjQTmjRTmjSXZRo1E5o1U5om05ock51aCd9lGgpj5QoaMho1WiVaMloymibaNBo0WgLaM9o0mjOaMdo1GjMaMZoy2jNaHKQaCtOdWJ1aCd9lGgpj5QoaLtofmi2aL9oemi6aLxouGi+kGgrTnViZXVoJ32UaCmPlChobGhnaBBoC2gTaGpoZWgsaHBoXGgOaFhoc2gNaG5oEWgJaK9oSWgHaHKQaCtOdWIu", + "review__get_citations_skipped_switched_off.json": "gASVwwcAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLFIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwGMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwGMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lEsUjBZjaXRhdGlvbl9saW1pdF9yZWFjaGVklE6MD2NpdGF0aW9uX2NoZWNrc5ROjA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklIwMc3dpdGNoZWRfb2ZmlHVoKX2UaCuPlChoNGg4aDdoTWhCaFJoT2hLaDVoTmhRaFBoTGg2kGgtTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAXNoKX2UaCuPlChoXJBoLU51YowScG9sbF9hZnRlcl9zZWNvbmRzlE5oS12UjAhmYWlsdXJlc5RdlGhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UjAdmYWlsdXJllE6MBmNsYWltc5RdlGgAjAtSZXZpZXdDbGFpbZSTlCmBlH2UKGgFfZQojAVpbmRleJRLAIwFY2xhaW2UjChUaGUgRVUgQUkgQWN0IHRvb2sgZWZmZWN0IGluIE1hcmNoIDIwMjQulIwJcG9zaXRpb25zlE6MBnJlc3VsdJRoAIwMUmV2aWV3UmVzdWx0lJOUKYGUfZQoaAV9lCiMB3ZlcmRpY3SUjARUcnVllGggjARoaWdolIwGc291cmNllIwKYXNzZXNzbWVudJSMCGlzX2lzc3VllIl1aCl9lGgrj5QoaCBofmiBaIOQaC1OdWKMCmFzc2Vzc21lbnSUaACMEFJldmlld0Fzc2Vzc21lbnSUk5QpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaH6MBFRydWWUaCCMBGhpZ2iUjAlyYXRpb25hbGWUTowHZGlzc2VudJROjBB2ZXJpZmljYXRpb25fdXJslE6MCmVycm9yX2NvZGWUTowRaWRlbnRpZmllZF9jbGFpbXOUXZSMBGhpbnSUTowRc3VnZ2VzdGVkX3Jld3JpdGWUTmhsTnVoKX2UaCuPlCholWiQaJFoIGgLaH5ok2iPaJJolmhskGgtTnVijAplc2NhbGF0aW9ulGgAjApFc2NhbGF0aW9ulJOUKYGUfZQoaAV9lCiMDW1hdGNoZWRfcnVsZXOUXZSMC2Rpc3Bvc2l0aW9ulIwMbm90X3NlbGVjdGVklHVoKX2UaCuPlChooWifkGgtTnVijAx2ZXJpZmljYXRpb26UTowPc3VnZ2VzdGVkX2VkaXRzlE51aCl9lGgrj5QoaHVohmiZaHRopWimaHhod5BoLU51YmGMCWNpdGF0aW9uc5RdlHVoKX2UaCuPlChoZmhhaBFoC2gVaGRoX2guaGpoVmgPaFFobWgNaGhoE2gJaKloS2gHaGyQaC1OdWIu", + "review__get_citations_skipped_url_input.json": "gASVeAUAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwGZmFpbGVklIwHb3V0Y29tZZSMCXVuY2hlY2tlZJSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjAhsYW5ndWFnZZSMAmVulIwGcG9saWN5lGgAjBBFc2NhbGF0aW9uUG9saWN5lJOUKYGUfZQoaAV9lCiMCHZlcmRpY3RzlF2UKIwFRmFsc2WUjAxNb3N0bHkgRmFsc2WUjAVNaXhlZJRljApjb25maWRlbmNllF2UjANsb3eUYYwPbWF4X2Fzc2Vzc21lbnRzlEsUjBFtYXhfdmVyaWZpY2F0aW9uc5RLBYwFZGVwdGiUjAhzdGFuZGFyZJSMDW1heF9jaXRhdGlvbnOUSxSMDXN1Z2dlc3RfZWRpdHOUiXWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBtoJWggaCdoKGgkaCOQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMB3N1bW1hcnmUaACMDVJldmlld1N1bW1hcnmUk5QpgZR9lChoBX2UKIwPY2xhaW1zX3NlbGVjdGVklE6MC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklE6MD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5ROjA12ZXJpZmljYXRpb25zlE6MBmlzc3Vlc5RLAIwPY2l0YXRpb25zX2ZvdW5klE6MEmNpdGF0aW9uc19zZWxlY3RlZJROjA5jaXRhdGlvbl9saW1pdJRLFIwWY2l0YXRpb25fbGltaXRfcmVhY2hlZJROjA9jaXRhdGlvbl9jaGVja3OUTowPY2l0YXRpb25faXNzdWVzlEsAjBFjaXRhdGlvbnNfc2tpcHBlZJSMCXVybF9pbnB1dJR1aCl9lGgrj5QoaDRoOGg3aDxoOWhBaD5oOmg1aD1oQGg/aDtoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwBzaCl9lGgrj5QoaEuQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaDpdlIwIZmFpbHVyZXOUXZRoQF2UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUTowUbW9yZV9jbGFpbV9sb2NhdGlvbnOUTowObW9yZV9jaXRhdGlvbnOUTowHZmFpbHVyZZRoAIwMRmFpbHVyZUJsb2NrlJOUKYGUfZQoaAV9lCiMDmZhaWx1cmVfcmVhc29ulIwUdXBzdHJlYW1fdW5hdmFpbGFibGWUjA1mYWlsdXJlX2NsYXNzlIwUdXBzdHJlYW1fdW5hdmFpbGFibGWUjAlyZXRyeWFibGWUiIwEaGludJROjAhkb2NzX3VybJSMMGh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyN1cHN0cmVhbS11bmF2YWlsYWJsZZR1aCl9lGgrj5QoaGNoXmhkaGBoYpBoLU51YowGY2xhaW1zlF2UjAljaXRhdGlvbnOUXZR1aCl9lGgrj5QoaFVoUGgRaAtoFWhTaE5oLmhXaEVoD2hAaGhoDWhWaBNoCWhqaDpoB2hYkGgtTnViLg==", + "review__get_claim_limit_not_reached.json": "gASVBwkAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSwOMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwKMC2NsYWltX2xpbWl0lEsDjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwKMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lE6MFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUTowPY2l0YXRpb25fY2hlY2tzlE6MD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoKX2UaCuPlChoNGg4aDdoTWhCaFJoT2hLaDVoTmhRaFBoTGg2kGgtTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAnNoKX2UaCuPlChoW5BoLU51YowScG9sbF9hZnRlcl9zZWNvbmRzlE5oS12UjAhmYWlsdXJlc5RdlGhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UjAdmYWlsdXJllE6MBmNsYWltc5RdlChoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCXBvc2l0aW9uc5ROjAZyZXN1bHSUaACMDFJldmlld1Jlc3VsdJSTlCmBlH2UKGgFfZQojAd2ZXJkaWN0lIwEVHJ1ZZRoIIwEaGlnaJSMBnNvdXJjZZSMCmFzc2Vzc21lbnSUjAhpc19pc3N1ZZSJdWgpfZRoK4+UKGggaH1ogGiCkGgtTnVijAphc3Nlc3NtZW50lGgAjBBSZXZpZXdBc3Nlc3NtZW50lJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGh9jARUcnVllGggjARoaWdolIwJcmF0aW9uYWxllE6MB2Rpc3NlbnSUTowQdmVyaWZpY2F0aW9uX3VybJROjAplcnJvcl9jb2RllE6MEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE6MEXN1Z2dlc3RlZF9yZXdyaXRllE5oa051aCl9lGgrj5QoaJRoj2iQaCBoC2h9aJJojmiRaJVoa5BoLU51YowKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAtkaXNwb3NpdGlvbpSMDG5vdF9zZWxlY3RlZJR1aCl9lGgrj5QoaKBonpBoLU51YowMdmVyaWZpY2F0aW9ulE6MD3N1Z2dlc3RlZF9lZGl0c5ROdWgpfZRoK4+UKGh0aIVomGhzaKRopWh3aHaQaC1OdWJobymBlH2UKGgFfZQoaHNLAWh0jCJXYXRlciBib2lscyBhdCAxMDAgQyBhdCBzZWEgbGV2ZWwulGh2Tmh3aHkpgZR9lChoBX2UKGh9jARUcnVllGggjARoaWdolGiAjAphc3Nlc3NtZW50lGiCiXVoKX2UaCuPlChoIGh9aIBogpBoLU51YmiFaIcpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaH2MBFRydWWUaCCMBGhpZ2iUaI5OaI9OaJBOaJFOaJJdlGiUTmiVTmhrTnVoKX2UaCuPlCholGiPaJBoIGgLaH1okmiOaJFolWhrkGgtTnViaJhomimBlH2UKGgFfZQoaJ5dlGigjAxub3Rfc2VsZWN0ZWSUdWgpfZRoK4+UKGigaJ6QaC1OdWJopE5opU51aCl9lGgrj5QoaHRohWiYaHNopGilaHdodpBoLU51YmWMCWNpdGF0aW9uc5RdlHVoKX2UaCuPlChoZWhgaBFoC2gVaGNoXmguaGloVWgPaFFobGgNaGdoE2gJaMZoS2gHaGuQaC1OdWIu", + "review__get_claim_limit_reached_exact.json": "gASVBwkAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSwKMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwKMC2NsYWltX2xpbWl0lEsCjBNjbGFpbV9saW1pdF9yZWFjaGVklIiMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwKMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lE6MFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUTowPY2l0YXRpb25fY2hlY2tzlE6MD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoKX2UaCuPlChoNGg4aDdoTWhCaFJoT2hLaDVoTmhRaFBoTGg2kGgtTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAnNoKX2UaCuPlChoW5BoLU51YowScG9sbF9hZnRlcl9zZWNvbmRzlE5oS12UjAhmYWlsdXJlc5RdlGhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UjAdmYWlsdXJllE6MBmNsYWltc5RdlChoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCXBvc2l0aW9uc5ROjAZyZXN1bHSUaACMDFJldmlld1Jlc3VsdJSTlCmBlH2UKGgFfZQojAd2ZXJkaWN0lIwEVHJ1ZZRoIIwEaGlnaJSMBnNvdXJjZZSMCmFzc2Vzc21lbnSUjAhpc19pc3N1ZZSJdWgpfZRoK4+UKGggaH1ogGiCkGgtTnVijAphc3Nlc3NtZW50lGgAjBBSZXZpZXdBc3Nlc3NtZW50lJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGh9jARUcnVllGggjARoaWdolIwJcmF0aW9uYWxllE6MB2Rpc3NlbnSUTowQdmVyaWZpY2F0aW9uX3VybJROjAplcnJvcl9jb2RllE6MEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE6MEXN1Z2dlc3RlZF9yZXdyaXRllE5oa051aCl9lGgrj5QoaJRoj2iQaCBoC2h9aJJojmiRaJVoa5BoLU51YowKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAtkaXNwb3NpdGlvbpSMDG5vdF9zZWxlY3RlZJR1aCl9lGgrj5QoaKBonpBoLU51YowMdmVyaWZpY2F0aW9ulE6MD3N1Z2dlc3RlZF9lZGl0c5ROdWgpfZRoK4+UKGh0aIVomGhzaKRopWh3aHaQaC1OdWJobymBlH2UKGgFfZQoaHNLAWh0jCJXYXRlciBib2lscyBhdCAxMDAgQyBhdCBzZWEgbGV2ZWwulGh2Tmh3aHkpgZR9lChoBX2UKGh9jARUcnVllGggjARoaWdolGiAjAphc3Nlc3NtZW50lGiCiXVoKX2UaCuPlChoIGh9aIBogpBoLU51YmiFaIcpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaH2MBFRydWWUaCCMBGhpZ2iUaI5OaI9OaJBOaJFOaJJdlGiUTmiVTmhrTnVoKX2UaCuPlCholGiPaJBoIGgLaH1okmiOaJFolWhrkGgtTnViaJhomimBlH2UKGgFfZQoaJ5dlGigjAxub3Rfc2VsZWN0ZWSUdWgpfZRoK4+UKGigaJ6QaC1OdWJopE5opU51aCl9lGgrj5QoaHRohWiYaHNopGilaHdodpBoLU51YmWMCWNpdGF0aW9uc5RdlHVoKX2UaCuPlChoZWhgaBFoC2gVaGNoXmguaGloVWgPaFFobGgNaGdoE2gJaMZoS2gHaGuQaC1OdWIu", + "review__get_completed_assess_only.json": "gASVTAoAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMDGlzc3Vlc19mb3VuZJSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjAhsYW5ndWFnZZSMAmVulIwGcG9saWN5lGgAjBBFc2NhbGF0aW9uUG9saWN5lJOUKYGUfZQoaAV9lCiMCHZlcmRpY3RzlF2UKIwFRmFsc2WUjAxNb3N0bHkgRmFsc2WUjAVNaXhlZJRljApjb25maWRlbmNllF2UjANsb3eUYYwPbWF4X2Fzc2Vzc21lbnRzlEsUjBFtYXhfdmVyaWZpY2F0aW9uc5RLAIwFZGVwdGiUjAhzdGFuZGFyZJSMDW1heF9jaXRhdGlvbnOUSwCMDXN1Z2dlc3RfZWRpdHOUiXWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBtoJWggaCdoKGgkaCOQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMB3N1bW1hcnmUaACMDVJldmlld1N1bW1hcnmUk5QpgZR9lChoBX2UKIwPY2xhaW1zX3NlbGVjdGVklEsCjAtjbGFpbV9saW1pdJRLFIwTY2xhaW1fbGltaXRfcmVhY2hlZJSJjA9pbnB1dF90cnVuY2F0ZWSUiYwLYXNzZXNzbWVudHOUaACMFlJldmlld0Fzc2Vzc21lbnRDb3VudHOUk5QpgZR9lChoBX2UKIwJY29tcGxldGVklEsCjAZmYWlsZWSUSwB1aCl9lGgrj5QoaD5oP5BoLU51YowNdmVyaWZpY2F0aW9uc5RoAIwYUmV2aWV3VmVyaWZpY2F0aW9uQ291bnRzlJOUKYGUfZQoaAV9lCiMB3BsYW5uZWSUSwBoPksAaD9LAHVoKX2UaCuPlChoPmg/aEiQaC1OdWKMBmlzc3Vlc5RLAYwPY2l0YXRpb25zX2ZvdW5klE6MEmNpdGF0aW9uc19zZWxlY3RlZJROjA5jaXRhdGlvbl9saW1pdJROjBZjaXRhdGlvbl9saW1pdF9yZWFjaGVklE6MD2NpdGF0aW9uX2NoZWNrc5ROjA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aE1oQmhSaE9oS2g1aE5oUWhQaExoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwJzaCl9lGgrj5QoaFuQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaEtdlGgAjAtSZXZpZXdJc3N1ZZSTlCmBlH2UKGgFfZQojAtjbGFpbV9pbmRleJRLAYwFY2xhaW2UjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UjA52ZXJpZmllZF9jbGFpbZROjAd2ZXJkaWN0lIwFRmFsc2WUaCCMBGhpZ2iUjAZzb3VyY2WUjAphc3Nlc3NtZW50lIwPdmVyaWZpY2F0aW9uX2lklE6ME3ZlcmlmaWNhdGlvbl9zdGF0dXOUTowQdmVyaWZpY2F0aW9uX3VybJROjAN1cmyUTowKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAd2ZXJkaWN0lGGMC2Rpc3Bvc2l0aW9ulIwDY2FwlHVoKX2UaCuPlChoe2h4kGgtTnVijAtrZXlfZmluZGluZ5ROjAlyYXRpb25hbGWUTowRc3VnZ2VzdGVkX3Jld3JpdGWUTowHZmFpbHVyZZROjA9zdWdnZXN0ZWRfZWRpdHOUTnVoKX2UaCuPlChoZmhuaHBoIGhpaG9ocmiAaINocWhsaGhoZWh/aIFogpBoLU51YmGMCGZhaWx1cmVzlF2UaFFdlIwRY2l0YXRpb25fZmFpbHVyZXOUXZSMC21vcmVfY2xhaW1zlF2UjBRtb3JlX2NsYWltX2xvY2F0aW9uc5RdlIwObW9yZV9jaXRhdGlvbnOUXZRogk6MBmNsYWltc5RdlChoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwBoZowoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCXBvc2l0aW9uc5ROjAZyZXN1bHSUaACMDFJldmlld1Jlc3VsdJSTlCmBlH2UKGgFfZQoaGmMBFRydWWUaCCMBGhpZ2iUaGyMCmFzc2Vzc21lbnSUjAhpc19pc3N1ZZSJdWgpfZRoK4+UKGggaGlobGikkGgtTnVijAphc3Nlc3NtZW50lGgAjBBSZXZpZXdBc3Nlc3NtZW50lJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGhpjARUcnVllGggjARoaWdolGiATowHZGlzc2VudJROaHBOjAplcnJvcl9jb2RllE6MEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE5ogU5ogk51aCl9lGgrj5QoaLRosGhwaCBoC2hpaLJogGixaIFogpBoLU51YmhyaHQpgZR9lChoBX2UKGh4XZRoe4wMbm90X3NlbGVjdGVklHVoKX2UaCuPlChoe2h4kGgtTnVijAx2ZXJpZmljYXRpb26UTmiDTnVoKX2UaCuPlChoZminaHJomGi+aINom2iakGgtTnViaJQpgZR9lChoBX2UKGiYSwFoZoweVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulGiaTmibaJ0pgZR9lChoBX2UKGhpjAVGYWxzZZRoIIwEaGlnaJRobIwKYXNzZXNzbWVudJRopIh1aCl9lGgrj5QoaCBoaWhsaKSQaC1OdWJop2ipKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGhpjAVGYWxzZZRoIIwEaGlnaJRogE5osE5ocE5osU5osl2UaLROaIFOaIJOdWgpfZRoK4+UKGi0aLBocGggaAtoaWiyaIBosWiBaIKQaC1OdWJocmh0KYGUfZQoaAV9lChoeF2UjAd2ZXJkaWN0lGFoe4wDY2FwlHVoKX2UaCuPlChoe2h4kGgtTnViaL5OaINOdWgpfZRoK4+UKGhmaKdocmiYaL5og2ibaJqQaC1OdWJljAljaXRhdGlvbnOUXZR1aCl9lGgrj5QoaItohmgRaAtoFWiJaF5oLmiPaFVoD2hRaJFoDWiNaBNoCWjgaEtoB2iCkGgtTnViLg==", + "review__get_completed_clean.json": "gASVBAkAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwKMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwKMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lE6MFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUTowPY2l0YXRpb25fY2hlY2tzlE6MD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoKX2UaCuPlChoNGg4aDdoTWhCaFJoT2hLaDVoTmhRaFBoTGg2kGgtTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAnNoKX2UaCuPlChoW5BoLU51YowScG9sbF9hZnRlcl9zZWNvbmRzlE5oS12UjAhmYWlsdXJlc5RdlGhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UjAdmYWlsdXJllE6MBmNsYWltc5RdlChoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCXBvc2l0aW9uc5ROjAZyZXN1bHSUaACMDFJldmlld1Jlc3VsdJSTlCmBlH2UKGgFfZQojAd2ZXJkaWN0lIwEVHJ1ZZRoIIwEaGlnaJSMBnNvdXJjZZSMCmFzc2Vzc21lbnSUjAhpc19pc3N1ZZSJdWgpfZRoK4+UKGggaH1ogGiCkGgtTnVijAphc3Nlc3NtZW50lGgAjBBSZXZpZXdBc3Nlc3NtZW50lJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGh9jARUcnVllGggjARoaWdolIwJcmF0aW9uYWxllE6MB2Rpc3NlbnSUTowQdmVyaWZpY2F0aW9uX3VybJROjAplcnJvcl9jb2RllE6MEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE6MEXN1Z2dlc3RlZF9yZXdyaXRllE5oa051aCl9lGgrj5QoaJRoj2iQaCBoC2h9aJJojmiRaJVoa5BoLU51YowKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAtkaXNwb3NpdGlvbpSMDG5vdF9zZWxlY3RlZJR1aCl9lGgrj5QoaKBonpBoLU51YowMdmVyaWZpY2F0aW9ulE6MD3N1Z2dlc3RlZF9lZGl0c5ROdWgpfZRoK4+UKGh0aIVomGhzaKRopWh3aHaQaC1OdWJobymBlH2UKGgFfZQoaHNLAWh0jB9QYXJpcyBpcyB0aGUgY2FwaXRhbCBvZiBGcmFuY2UulGh2Tmh3aHkpgZR9lChoBX2UKGh9jARUcnVllGggjARoaWdolGiAjAphc3Nlc3NtZW50lGiCiXVoKX2UaCuPlChoIGh9aIBogpBoLU51YmiFaIcpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaH2MBFRydWWUaCCMBGhpZ2iUaI5OaI9OaJBOaJFOaJJdlGiUTmiVTmhrTnVoKX2UaCuPlCholGiPaJBoIGgLaH1okmiOaJFolWhrkGgtTnViaJhomimBlH2UKGgFfZQoaJ5dlGigjAxub3Rfc2VsZWN0ZWSUdWgpfZRoK4+UKGigaJ6QaC1OdWJopE5opU51aCl9lGgrj5QoaHRohWiYaHNopGilaHdodpBoLU51YmWMCWNpdGF0aW9uc5RdlHVoKX2UaCuPlChoZWhgaBFoC2gVaGNoXmguaGloVWgPaFFobGgNaGdoE2gJaMZoS2gHaGuQaC1OdWIu", + "review__get_completed_issues_all_verified.json": "gASVIhMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMDGlzc3Vlc19mb3VuZJSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjAhsYW5ndWFnZZSMAmVulIwGcG9saWN5lGgAjBBFc2NhbGF0aW9uUG9saWN5lJOUKYGUfZQoaAV9lCiMCHZlcmRpY3RzlF2UKIwFRmFsc2WUjAxNb3N0bHkgRmFsc2WUjAVNaXhlZJRljApjb25maWRlbmNllF2UjANsb3eUYYwPbWF4X2Fzc2Vzc21lbnRzlEsUjBFtYXhfdmVyaWZpY2F0aW9uc5RLBYwFZGVwdGiUjAhzdGFuZGFyZJSMDW1heF9jaXRhdGlvbnOUSwCMDXN1Z2dlc3RfZWRpdHOUiXWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBtoJWggaCdoKGgkaCOQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMB3N1bW1hcnmUaACMDVJldmlld1N1bW1hcnmUk5QpgZR9lChoBX2UKIwPY2xhaW1zX3NlbGVjdGVklEsDjAtjbGFpbV9saW1pdJRLFIwTY2xhaW1fbGltaXRfcmVhY2hlZJSJjA9pbnB1dF90cnVuY2F0ZWSUiYwLYXNzZXNzbWVudHOUaACMFlJldmlld0Fzc2Vzc21lbnRDb3VudHOUk5QpgZR9lChoBX2UKIwJY29tcGxldGVklEsDjAZmYWlsZWSUSwB1aCl9lGgrj5QoaD5oP5BoLU51YowNdmVyaWZpY2F0aW9uc5RoAIwYUmV2aWV3VmVyaWZpY2F0aW9uQ291bnRzlJOUKYGUfZQoaAV9lCiMB3BsYW5uZWSUSwJoPksCaD9LAHVoKX2UaCuPlChoPmg/aEiQaC1OdWKMBmlzc3Vlc5RLAowPY2l0YXRpb25zX2ZvdW5klE6MEmNpdGF0aW9uc19zZWxlY3RlZJROjA5jaXRhdGlvbl9saW1pdJROjBZjaXRhdGlvbl9saW1pdF9yZWFjaGVklE6MD2NpdGF0aW9uX2NoZWNrc5ROjA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aE1oQmhSaE9oS2g1aE5oUWhQaExoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSxdzaCl9lGgrj5QoaFuQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaEtdlChoAIwLUmV2aWV3SXNzdWWUk5QpgZR9lChoBX2UKIwLY2xhaW1faW5kZXiUSwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMDnZlcmlmaWVkX2NsYWltlE6MB3ZlcmRpY3SUjAVGYWxzZZRoIIwEaGlnaJSMBnNvdXJjZZSMDHZlcmlmaWNhdGlvbpSMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwTdmVyaWZpY2F0aW9uX3N0YXR1c5SMCWNvbXBsZXRlZJSMEHZlcmlmaWNhdGlvbl91cmyUjC1odHRwczovL2xlbnouaW8vYXBpL3YxL3ZlcmlmaWNhdGlvbnMvNjhjYTRhYWaUjAN1cmyUjC1odHRwczovL2xlbnouaW8vYy90aGUtZWFydGgtaXMtcm91bmQtNjhjYTRhYWaUjAplc2NhbGF0aW9ulGgAjApFc2NhbGF0aW9ulJOUKYGUfZQoaAV9lCiMDW1hdGNoZWRfcnVsZXOUXZSMB3ZlcmRpY3SUYYwLZGlzcG9zaXRpb26UjAdwbGFubmVklHVoKX2UaCuPlChof2h8kGgtTnVijAtrZXlfZmluZGluZ5SMNEZpbmRpbmcgZm9yIFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UjAlyYXRpb25hbGWUTowRc3VnZ2VzdGVkX3Jld3JpdGWUjC9GaXhlZDogVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMB2ZhaWx1cmWUTowPc3VnZ2VzdGVkX2VkaXRzlE51aCl9lGgrj5QoaGZobmhyaCBoaWhwaHZohWiJaHRobGhoaGVog2iGaIiQaC1OdWJoYSmBlH2UKGgFfZQoaGVLAWhmjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UaGhOaGmMBUZhbHNllGggjARoaWdolGhsjAx2ZXJpZmljYXRpb26UaG6MCDRkNDRkZmFmlGhwjAljb21wbGV0ZWSUaHKMLWh0dHBzOi8vbGVuei5pby9hcGkvdjEvdmVyaWZpY2F0aW9ucy80ZDQ0ZGZhZpRodIwtaHR0cHM6Ly9sZW56LmlvL2MvdGhlLWVhcnRoLWlzLXJvdW5kLTRkNDRkZmFmlGh2aHgpgZR9lChoBX2UKGh8XZSMB3ZlcmRpY3SUYWh/jAdwbGFubmVklHVoKX2UaCuPlChof2h8kGgtTnViaIOMKkZpbmRpbmcgZm9yIFRoZSBFaWZmZWwgVG93ZXIgaXMgaW4gQmVybGluLpRohU5ohowlRml4ZWQ6IFRoZSBFaWZmZWwgVG93ZXIgaXMgaW4gQmVybGluLpRoiE5oiU51aCl9lGgrj5QoaGZobmhyaCBoaWhwaHZohWiJaHRobGhoaGVog2iGaIiQaC1OdWJljAhmYWlsdXJlc5RdlGhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UaIhOjAZjbGFpbXOUXZQoaACMC1Jldmlld0NsYWltlJOUKYGUfZQoaAV9lCiMBWluZGV4lEsAaGaMKFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UjAlwb3NpdGlvbnOUTowGcmVzdWx0lGgAjAxSZXZpZXdSZXN1bHSUk5QpgZR9lChoBX2UKGhpjAVGYWxzZZRoIIwEaGlnaJRobIwMdmVyaWZpY2F0aW9ulIwIaXNfaXNzdWWUiHVoKX2UaCuPlChoIGhpaGxowZBoLU51YowKYXNzZXNzbWVudJRoAIwQUmV2aWV3QXNzZXNzbWVudJSTlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJRoaYwMTW9zdGx5IEZhbHNllGggjAZtZWRpdW2UaIVOjAdkaXNzZW50lE5ock6MCmVycm9yX2NvZGWUTowRaWRlbnRpZmllZF9jbGFpbXOUXZSMBGhpbnSUTmiGTmiITnVoKX2UaCuPlCho0WjNaHJoIGgLaGloz2iFaM5ohmiIkGgtTnViaHZoeCmBlH2UKGgFfZQoaHxdlIwHdmVyZGljdJRhaH+MB3BsYW5uZWSUdWgpfZRoK4+UKGh/aHyQaC1OdWKMDHZlcmlmaWNhdGlvbpRoAIwSUmV2aWV3VmVyaWZpY2F0aW9ulJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklIwOY29udGVudF9zdGF0dXOUjAlhdmFpbGFibGWUaG6MCDY4Y2E0YWFmlIwHdGFza19pZJSMIDdjZmYxOGRhMmQ5NzlkNjM3MGU1NGExNjBiZTEyMWFklGhmjChUaGUgRVUgQUkgQWN0IHRvb2sgZWZmZWN0IGluIE1hcmNoIDIwMjQulGgTjAJlbpSMCnZpc2liaWxpdHmUjAdwcml2YXRllGgljAhzdGFuZGFyZJSMBmRvbWFpbpSMAJSMCGVudGl0aWVzlF2UaGmMBUZhbHNllGggjARoaWdolIwKbGVuel9zY29yZZRLAmiDjDRGaW5kaW5nIGZvciBUaGUgRVUgQUkgQWN0IHRvb2sgZWZmZWN0IGluIE1hcmNoIDIwMjQulIwRZXhlY3V0aXZlX3N1bW1hcnmUjDRTdW1tYXJ5IGZvciBUaGUgRVUgQUkgQWN0IHRvb2sgZWZmZWN0IGluIE1hcmNoIDIwMjQulGiGjC9GaXhlZDogVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCHdhcm5pbmdzlF2UjAJ3MZRhaA+MIDIwMjYtMTAtMDFUMDk6MTQ6MDAuMTIzNDU2KzAwOjAwlIwLbW9kaWZpZWRfYXSUTmhyjC1odHRwczovL2xlbnouaW8vYXBpL3YxL3ZlcmlmaWNhdGlvbnMvNjhjYTRhYWaUaHSMLWh0dHBzOi8vbGVuei5pby9jL3RoZS1lYXJ0aC1pcy1yb3VuZC02OGNhNGFhZpRoiE51aCl9lGgrj5QoaG5ocmjvaCBo/Gj1aHRo6mgLaO1og2hmaCVoD2hpaIZo+GjmaBNo82jjaIiQaC1OdWJoiU51aCl9lGgrj5QoaGZoxGh2aLVo3GiJaLhot5BoLU51YmixKYGUfZQoaAV9lChotUsBaGaMHlRoZSBFaWZmZWwgVG93ZXIgaXMgaW4gQmVybGluLpRot05ouGi6KYGUfZQoaAV9lChoaYwFRmFsc2WUaCCMBGhpZ2iUaGyMDHZlcmlmaWNhdGlvbpRowYh1aCl9lGgrj5QoaCBoaWhsaMGQaC1OdWJoxGjGKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGhpjAVGYWxzZZRoIIwEaGlnaJRohU5ozU5ock5ozk5oz12UaNFOaIZOaIhOdWgpfZRoK4+UKGjRaM1ocmggaAtoaWjPaIVozmiGaIiQaC1OdWJodmh4KYGUfZQoaAV9lChofF2UjAd2ZXJkaWN0lGFof4wHcGxhbm5lZJR1aCl9lGgrj5QoaH9ofJBoLU51YmjcaN4pgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaOOMCWF2YWlsYWJsZZRobowINGQ0NGRmYWaUaOaMIDBiOTJiNDQzZWI2OWI5YzcxNDM0ZmRjNjRmMmNhOGJllGhmjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UaBOMAmVulGjqjAdwcml2YXRllGgljAhzdGFuZGFyZJRo7WjuaO9dlGhpjAVGYWxzZZRoIIwEaGlnaJRo80sCaIOMKkZpbmRpbmcgZm9yIFRoZSBFaWZmZWwgVG93ZXIgaXMgaW4gQmVybGluLpRo9YwqU3VtbWFyeSBmb3IgVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulGiGjCVGaXhlZDogVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulGj4XZSMAncxlGFoD4wgMjAyNi0xMC0wMVQwOToxNDowMC4xMjM0NTYrMDA6MDCUaPxOaHKMLWh0dHBzOi8vbGVuei5pby9hcGkvdjEvdmVyaWZpY2F0aW9ucy80ZDQ0ZGZhZpRodIwtaHR0cHM6Ly9sZW56LmlvL2MvdGhlLWVhcnRoLWlzLXJvdW5kLTRkNDRkZmFmlGiITnVoKX2UaCuPlChobmhyaO9oIGj8aPVodGjqaAto7WiDaGZoJWgPaGlohmj4aOZoE2jzaONoiJBoLU51YmiJTnVoKX2UaCuPlChoZmjEaHZotWjcaIlouGi3kGgtTnViaLEpgZR9lChoBX2UKGi1SwJoZowfUGFyaXMgaXMgdGhlIGNhcGl0YWwgb2YgRnJhbmNlLpRot05ouGi6KYGUfZQoaAV9lChoaYwEVHJ1ZZRoIIwEaGlnaJRobIwKYXNzZXNzbWVudJRowYl1aCl9lGgrj5QoaCBoaWhsaMGQaC1OdWJoxGjGKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGhpjARUcnVllGggjARoaWdolGiFTmjNTmhyTmjOTmjPXZRo0U5ohk5oiE51aCl9lGgrj5QoaNFozWhyaCBoC2hpaM9ohWjOaIZoiJBoLU51Ymh2aHgpgZR9lChoBX2UKGh8XZRof4wMbm90X3NlbGVjdGVklHVoKX2UaCuPlChof2h8kGgtTnViaNxOaIlOdWgpfZRoK4+UKGhmaMRodmi1aNxoiWi4aLeQaC1OdWJljAljaXRhdGlvbnOUXZR1aCl9lGgrj5QoaKhoo2gRaAtoFWimaF5oLmisaFVoD2hRaK5oDWiqaBNoCWpYAQAAaEtoB2iIkGgtTnViLg==", + "review__get_completed_issues_full.json": "gASVyhUAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMCmluY29tcGxldGWUjApjcmVhdGVkX2F0lIwbMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTZalIwMY29tcGxldGVkX2F0lIwbMjAyNi0xMC0wMVQxMDowNzowMC4xMjM0NTZalIwIbGFuZ3VhZ2WUjAJlbpSMBnBvbGljeZRoAIwQRXNjYWxhdGlvblBvbGljeZSTlCmBlH2UKGgFfZQojAh2ZXJkaWN0c5RdlCiMBUZhbHNllIwMTW9zdGx5IEZhbHNllIwFTWl4ZWSUZYwKY29uZmlkZW5jZZRdlIwDbG93lGGMD21heF9hc3Nlc3NtZW50c5RLFIwRbWF4X3ZlcmlmaWNhdGlvbnOUSwWMBWRlcHRolIwIc3RhbmRhcmSUjA1tYXhfY2l0YXRpb25zlEsAjA1zdWdnZXN0X2VkaXRzlIl1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgbaCVoIGgnaChoJGgjkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAdzdW1tYXJ5lGgAjA1SZXZpZXdTdW1tYXJ5lJOUKYGUfZQoaAV9lCiMD2NsYWltc19zZWxlY3RlZJRLBIwLY2xhaW1fbGltaXSUSxSME2NsYWltX2xpbWl0X3JlYWNoZWSUiYwPaW5wdXRfdHJ1bmNhdGVklImMC2Fzc2Vzc21lbnRzlGgAjBZSZXZpZXdBc3Nlc3NtZW50Q291bnRzlJOUKYGUfZQoaAV9lCiMCWNvbXBsZXRlZJRLA4wGZmFpbGVklEsBdWgpfZRoK4+UKGg+aD+QaC1OdWKMDXZlcmlmaWNhdGlvbnOUaACMGFJldmlld1ZlcmlmaWNhdGlvbkNvdW50c5STlCmBlH2UKGgFfZQojAdwbGFubmVklEsCaD5LAWg/SwF1aCl9lGgrj5QoaD5oP2hIkGgtTnVijAZpc3N1ZXOUSwKMD2NpdGF0aW9uc19mb3VuZJROjBJjaXRhdGlvbnNfc2VsZWN0ZWSUTowOY2l0YXRpb25fbGltaXSUTowWY2l0YXRpb25fbGltaXRfcmVhY2hlZJROjA9jaXRhdGlvbl9jaGVja3OUTowPY2l0YXRpb25faXNzdWVzlEsAjBFjaXRhdGlvbnNfc2tpcHBlZJROdWgpfZRoK4+UKGg0aDhoN2hNaEJoUmhPaEtoNWhOaFFoUGhMaDaQaC1OdWKMB2NyZWRpdHOUaACMDVJldmlld0NyZWRpdHOUk5QpgZR9lChoBX2UjAdjaGFyZ2VklEsNc2gpfZRoK4+UKGhbkGgtTnVijBJwb2xsX2FmdGVyX3NlY29uZHOUTmhLXZQoaACMC1Jldmlld0lzc3VllJOUKYGUfZQoaAV9lCiMC2NsYWltX2luZGV4lEsAjAVjbGFpbZSMKFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UjA52ZXJpZmllZF9jbGFpbZROjAd2ZXJkaWN0lIwFRmFsc2WUaCCMBGhpZ2iUjAZzb3VyY2WUjAx2ZXJpZmljYXRpb26UjA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSME3ZlcmlmaWNhdGlvbl9zdGF0dXOUjAljb21wbGV0ZWSUjBB2ZXJpZmljYXRpb25fdXJslIwtaHR0cHM6Ly9sZW56LmlvL2FwaS92MS92ZXJpZmljYXRpb25zLzY4Y2E0YWFmlIwDdXJslIwtaHR0cHM6Ly9sZW56LmlvL2MvdGhlLWVhcnRoLWlzLXJvdW5kLTY4Y2E0YWFmlIwKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAd2ZXJkaWN0lGGMC2Rpc3Bvc2l0aW9ulIwHcGxhbm5lZJR1aCl9lGgrj5QoaH9ofJBoLU51YowLa2V5X2ZpbmRpbmeUjDRGaW5kaW5nIGZvciBUaGUgRVUgQUkgQWN0IHRvb2sgZWZmZWN0IGluIE1hcmNoIDIwMjQulIwJcmF0aW9uYWxllE6MEXN1Z2dlc3RlZF9yZXdyaXRllIwvRml4ZWQ6IFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UjAdmYWlsdXJllE6MD3N1Z2dlc3RlZF9lZGl0c5ROdWgpfZRoK4+UKGhmaG5ocmggaGlocGh2aIVoiWh0aGxoaGhlaINohmiIkGgtTnViaGEpgZR9lChoBX2UKGhlSwJoZoweVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulGhoTmhpjAVGYWxzZZRoIIwEaGlnaJRobIwKYXNzZXNzbWVudJRobk5ocIwGZmFpbGVklGhyTmh0Tmh2aHgpgZR9lChoBX2UKGh8XZSMB3ZlcmRpY3SUYWh/jAdwbGFubmVklHVoKX2UaCuPlChof2h8kGgtTnViaINOaIVOaIZOaIhoAIwMRmFpbHVyZUJsb2NrlJOUKYGUfZQoaAV9lCiMDmZhaWx1cmVfcmVhc29ulIwOcmVzZWFyY2hfZW1wdHmUjA1mYWlsdXJlX2NsYXNzlIwVaW5zdWZmaWNpZW50X2V2aWRlbmNllIwJcmV0cnlhYmxllImMBGhpbnSUTowIZG9jc191cmyUjDFodHRwczovL2xlbnouaW8vZG9jcy9lcnJvcnMjaW5zdWZmaWNpZW50LWV2aWRlbmNllHVoKX2UaCuPlChopmihaKdoo2ilkGgtTnViaIlOdWgpfZRoK4+UKGhmaG5ocmggaGlocGh2aIVoiWh0aGxoaGhlaINohmiIkGgtTnViZYwIZmFpbHVyZXOUXZRoAIwNUmV2aWV3RmFpbHVyZZSTlCmBlH2UKGgFfZQoaGVLAWhmjCJXYXRlciBib2lscyBhdCAxMDAgQyBhdCBzZWEgbGV2ZWwulIwFc3RhZ2WUjAphc3Nlc3NtZW50lGiIaJ0pgZR9lChoBX2UKGihjBR1cHN0cmVhbV91bmF2YWlsYWJsZZRoo4wUdXBzdHJlYW1fdW5hdmFpbGFibGWUaKWIaKaMTkEgbW9kZWwgcHJvdmlkZXIgd2FzIHVuYXZhaWxhYmxlIGZvciB0aGlzIGl0ZW0uIFJldHJ5IGl0OyBub3RoaW5nIHdhcyBjaGFyZ2VkLpRop4wwaHR0cHM6Ly9sZW56LmlvL2RvY3MvZXJyb3JzI3Vwc3RyZWFtLXVuYXZhaWxhYmxllHVoKX2UaCuPlChopmihaKdoo2ilkGgtTnVidWgpfZRoK4+UKGhmaGVotWiIkGgtTnViYWhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UaIhOjAZjbGFpbXOUXZQoaACMC1Jldmlld0NsYWltlJOUKYGUfZQoaAV9lCiMBWluZGV4lEsAaGaMKFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UjAlwb3NpdGlvbnOUTowGcmVzdWx0lGgAjAxSZXZpZXdSZXN1bHSUk5QpgZR9lChoBX2UKGhpjAVGYWxzZZRoIIwEaGlnaJRobIwMdmVyaWZpY2F0aW9ulIwIaXNfaXNzdWWUiHVoKX2UaCuPlChoIGhpaGxo3pBoLU51YowKYXNzZXNzbWVudJRoAIwQUmV2aWV3QXNzZXNzbWVudJSTlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJRoaYwMTW9zdGx5IEZhbHNllGggjAZtZWRpdW2UaIVOjAdkaXNzZW50lE5ock6MCmVycm9yX2NvZGWUTowRaWRlbnRpZmllZF9jbGFpbXOUXZRopk5ohk5oiE51aCl9lGgrj5QoaKZo6mhyaCBoC2hpaOxohWjraIZoiJBoLU51Ymh2aHgpgZR9lChoBX2UKGh8XZSMB3ZlcmRpY3SUYWh/jAdwbGFubmVklHVoKX2UaCuPlChof2h8kGgtTnVijAx2ZXJpZmljYXRpb26UaACMElJldmlld1ZlcmlmaWNhdGlvbpSTlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJSMDmNvbnRlbnRfc3RhdHVzlIwJYXZhaWxhYmxllGhujAg2OGNhNGFhZpSMB3Rhc2tfaWSUjCA3Y2ZmMThkYTJkOTc5ZDYzNzBlNTRhMTYwYmUxMjFhZJRoZowoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpRoE4wCZW6UjAp2aXNpYmlsaXR5lIwHcHJpdmF0ZZRoJYwIc3RhbmRhcmSUjAZkb21haW6UjACUjAhlbnRpdGllc5RdlGhpjAVGYWxzZZRoIIwEaGlnaJSMCmxlbnpfc2NvcmWUSwJog4w0RmluZGluZyBmb3IgVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMEWV4ZWN1dGl2ZV9zdW1tYXJ5lIw0U3VtbWFyeSBmb3IgVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpRohowvRml4ZWQ6IFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UjAh3YXJuaW5nc5RdlIwCdzGUYWgPjCAyMDI2LTEwLTAxVDA5OjE0OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE5ocowtaHR0cHM6Ly9sZW56LmlvL2FwaS92MS92ZXJpZmljYXRpb25zLzY4Y2E0YWFmlGh0jC1odHRwczovL2xlbnouaW8vYy90aGUtZWFydGgtaXMtcm91bmQtNjhjYTRhYWaUaIhOdWgpfZRoK4+UKGhuaHJqCwEAAGggahgBAABqEQEAAGh0agYBAABoC2oJAQAAaINoZmglaA9oaWiGahQBAABqAgEAAGgTag8BAABo/2iIkGgtTnViaIlOdWgpfZRoK4+UKGhmaOFodmjSaPhoiWjVaNSQaC1OdWJozimBlH2UKGgFfZQoaNJLAWhmjCJXYXRlciBib2lscyBhdCAxMDAgQyBhdCBzZWEgbGV2ZWwulGjUTmjVTmjhaOMpgZR9lChoBX2UKGgLjAZmYWlsZWSUaGlOaCBOaIVOaOpOaHJOaOuMFHVwc3RyZWFtX3VuYXZhaWxhYmxllGjsXZRopk5ohk5oiGidKYGUfZQoaAV9lChooYwUdXBzdHJlYW1fdW5hdmFpbGFibGWUaKOMFHVwc3RyZWFtX3VuYXZhaWxhYmxllGiliGimjE5BIG1vZGVsIHByb3ZpZGVyIHdhcyB1bmF2YWlsYWJsZSBmb3IgdGhpcyBpdGVtLiBSZXRyeSBpdDsgbm90aGluZyB3YXMgY2hhcmdlZC6UaKeMMGh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyN1cHN0cmVhbS11bmF2YWlsYWJsZZR1aCl9lGgrj5QoaKZooWinaKNopZBoLU51YnVoKX2UaCuPlChopmjqaHJoIGgLaGlo7GiFaOtohmiIkGgtTnViaHZOaPhOaIlOdWgpfZRoK4+UKGhmaOFodmjSaPhoiWjVaNSQaC1OdWJozimBlH2UKGgFfZQoaNJLAmhmjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UaNROaNVo1ymBlH2UKGgFfZQoaGmMBUZhbHNllGggjARoaWdolGhsjAphc3Nlc3NtZW50lGjeiHVoKX2UaCuPlChoIGhpaGxo3pBoLU51YmjhaOMpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaGmMBUZhbHNllGggjARoaWdolGiFTmjqTmhyTmjrTmjsXZRopk5ohk5oiE51aCl9lGgrj5QoaKZo6mhyaCBoC2hpaOxohWjraIZoiJBoLU51Ymh2aHgpgZR9lChoBX2UKGh8XZSMB3ZlcmRpY3SUYWh/jAdwbGFubmVklHVoKX2UaCuPlChof2h8kGgtTnViaPho+imBlH2UKGgFfZQoaAuMBmZhaWxlZJRo/4wJYXZhaWxhYmxllGhuTmoCAQAAjCAwYjkyYjQ0M2ViNjliOWM3MTQzNGZkYzY0ZjJjYThiZZRoZk5oE05qBgEAAE5oJU5qCQEAAE5qCwEAAF2UaGlOaCBOag8BAABOaINOahEBAABOaIZOahQBAABdlGgPTmoYAQAATmhyTmh0TmiIaJ0pgZR9lChoBX2UKGihjA5yZXNlYXJjaF9lbXB0eZRoo4wVaW5zdWZmaWNpZW50X2V2aWRlbmNllGiliWimTminjDFodHRwczovL2xlbnouaW8vZG9jcy9lcnJvcnMjaW5zdWZmaWNpZW50LWV2aWRlbmNllHVoKX2UaCuPlChopmihaKdoo2ilkGgtTnVidWgpfZRoK4+UKGhuaHJqCwEAAGggahgBAABqEQEAAGh0agYBAABoC2oJAQAAaINoZmglaA9oaWiGahQBAABqAgEAAGgTag8BAABo/2iIkGgtTnViaIlOdWgpfZRoK4+UKGhmaOFodmjSaPhoiWjVaNSQaC1OdWJozimBlH2UKGgFfZQoaNJLA2hmjB9QYXJpcyBpcyB0aGUgY2FwaXRhbCBvZiBGcmFuY2UulGjUTmjVaNcpgZR9lChoBX2UKGhpjARUcnVllGggjARoaWdolGhsjAphc3Nlc3NtZW50lGjeiXVoKX2UaCuPlChoIGhpaGxo3pBoLU51YmjhaOMpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaGmMBFRydWWUaCCMBGhpZ2iUaIVOaOpOaHJOaOtOaOxdlGimTmiGTmiITnVoKX2UaCuPlChopmjqaHJoIGgLaGlo7GiFaOtohmiIkGgtTnViaHZoeCmBlH2UKGgFfZQoaHxdlGh/jAxub3Rfc2VsZWN0ZWSUdWgpfZRoK4+UKGh/aHyQaC1OdWJo+E5oiU51aCl9lGgrj5QoaGZo4Wh2aNJo+GiJaNVo1JBoLU51YmWMCWNpdGF0aW9uc5RdlHVoKX2UaCuPlChoxWitaBFoC2gVaMNoXmguaMloVWgPaFFoy2gNaMdoE2gJaoUBAABoS2gHaIiQaC1OdWIu", + "review__get_completed_issues_view_issues.json": "gASVDAsAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjAZpc3N1ZXOUjAZzdGF0dXOUjAljb21wbGV0ZWSUjAdvdXRjb21llIwKaW5jb21wbGV0ZZSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjAhsYW5ndWFnZZSMAmVulIwGcG9saWN5lGgAjBBFc2NhbGF0aW9uUG9saWN5lJOUKYGUfZQoaAV9lCiMCHZlcmRpY3RzlF2UKIwFRmFsc2WUjAxNb3N0bHkgRmFsc2WUjAVNaXhlZJRljApjb25maWRlbmNllF2UjANsb3eUYYwPbWF4X2Fzc2Vzc21lbnRzlEsUjBFtYXhfdmVyaWZpY2F0aW9uc5RLBYwFZGVwdGiUjAhzdGFuZGFyZJSMDW1heF9jaXRhdGlvbnOUSwCMDXN1Z2dlc3RfZWRpdHOUiXWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBtoJWggaCdoKGgkaCOQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMB3N1bW1hcnmUaACMDVJldmlld1N1bW1hcnmUk5QpgZR9lChoBX2UKIwPY2xhaW1zX3NlbGVjdGVklEsEjAtjbGFpbV9saW1pdJRLFIwTY2xhaW1fbGltaXRfcmVhY2hlZJSJjA9pbnB1dF90cnVuY2F0ZWSUiYwLYXNzZXNzbWVudHOUaACMFlJldmlld0Fzc2Vzc21lbnRDb3VudHOUk5QpgZR9lChoBX2UKIwJY29tcGxldGVklEsDjAZmYWlsZWSUSwF1aCl9lGgrj5QoaD5oP5BoLU51YowNdmVyaWZpY2F0aW9uc5RoAIwYUmV2aWV3VmVyaWZpY2F0aW9uQ291bnRzlJOUKYGUfZQoaAV9lCiMB3BsYW5uZWSUSwJoPksBaD9LAXVoKX2UaCuPlChoPmg/aEiQaC1OdWKMBmlzc3Vlc5RLAowPY2l0YXRpb25zX2ZvdW5klE6MEmNpdGF0aW9uc19zZWxlY3RlZJROjA5jaXRhdGlvbl9saW1pdJROjBZjaXRhdGlvbl9saW1pdF9yZWFjaGVklE6MD2NpdGF0aW9uX2NoZWNrc5ROjA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aE1oQmhSaE9oS2g1aE5oUWhQaExoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSw1zaCl9lGgrj5QoaFuQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaEtdlChoAIwLUmV2aWV3SXNzdWWUk5QpgZR9lChoBX2UKIwLY2xhaW1faW5kZXiUSwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMDnZlcmlmaWVkX2NsYWltlE6MB3ZlcmRpY3SUjAVGYWxzZZRoIIwEaGlnaJSMBnNvdXJjZZSMDHZlcmlmaWNhdGlvbpSMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwTdmVyaWZpY2F0aW9uX3N0YXR1c5SMCWNvbXBsZXRlZJSMEHZlcmlmaWNhdGlvbl91cmyUjC1odHRwczovL2xlbnouaW8vYXBpL3YxL3ZlcmlmaWNhdGlvbnMvNjhjYTRhYWaUjAN1cmyUjC1odHRwczovL2xlbnouaW8vYy90aGUtZWFydGgtaXMtcm91bmQtNjhjYTRhYWaUjAplc2NhbGF0aW9ulGgAjApFc2NhbGF0aW9ulJOUKYGUfZQoaAV9lCiMDW1hdGNoZWRfcnVsZXOUXZSMB3ZlcmRpY3SUYYwLZGlzcG9zaXRpb26UjAdwbGFubmVklHVoKX2UaCuPlChof2h8kGgtTnVijAtrZXlfZmluZGluZ5SMNEZpbmRpbmcgZm9yIFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UjAlyYXRpb25hbGWUTowRc3VnZ2VzdGVkX3Jld3JpdGWUjC9GaXhlZDogVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMB2ZhaWx1cmWUTowPc3VnZ2VzdGVkX2VkaXRzlE51aCl9lGgrj5QoaGZobmhyaCBoaWhwaHZohWiJaHRobGhoaGVog2iGaIiQaC1OdWJoYSmBlH2UKGgFfZQoaGVLAmhmjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UaGhOaGmMBUZhbHNllGggjARoaWdolGhsjAphc3Nlc3NtZW50lGhuTmhwjAZmYWlsZWSUaHJOaHROaHZoeCmBlH2UKGgFfZQoaHxdlIwHdmVyZGljdJRhaH+MB3BsYW5uZWSUdWgpfZRoK4+UKGh/aHyQaC1OdWJog05ohU5ohk5oiGgAjAxGYWlsdXJlQmxvY2uUk5QpgZR9lChoBX2UKIwOZmFpbHVyZV9yZWFzb26UjA5yZXNlYXJjaF9lbXB0eZSMDWZhaWx1cmVfY2xhc3OUjBVpbnN1ZmZpY2llbnRfZXZpZGVuY2WUjAlyZXRyeWFibGWUiYwEaGludJROjAhkb2NzX3VybJSMMWh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyNpbnN1ZmZpY2llbnQtZXZpZGVuY2WUdWgpfZRoK4+UKGimaKFop2ijaKWQaC1OdWJoiU51aCl9lGgrj5QoaGZobmhyaCBoaWhwaHZohWiJaHRobGhoaGVog2iGaIiQaC1OdWJljAhmYWlsdXJlc5RdlGgAjA1SZXZpZXdGYWlsdXJllJOUKYGUfZQoaAV9lChoZUsBaGaMIldhdGVyIGJvaWxzIGF0IDEwMCBDIGF0IHNlYSBsZXZlbC6UjAVzdGFnZZSMCmFzc2Vzc21lbnSUaIhonSmBlH2UKGgFfZQoaKGMFHVwc3RyZWFtX3VuYXZhaWxhYmxllGijjBR1cHN0cmVhbV91bmF2YWlsYWJsZZRopYhopoxOQSBtb2RlbCBwcm92aWRlciB3YXMgdW5hdmFpbGFibGUgZm9yIHRoaXMgaXRlbS4gUmV0cnkgaXQ7IG5vdGhpbmcgd2FzIGNoYXJnZWQulGinjDBodHRwczovL2xlbnouaW8vZG9jcy9lcnJvcnMjdXBzdHJlYW0tdW5hdmFpbGFibGWUdWgpfZRoK4+UKGimaKFop2ijaKWQaC1OdWJ1aCl9lGgrj5QoaGZoZWi1aIiQaC1OdWJhaFFdlIwRY2l0YXRpb25fZmFpbHVyZXOUXZSMC21vcmVfY2xhaW1zlF2UjBRtb3JlX2NsYWltX2xvY2F0aW9uc5RdlIwObW9yZV9jaXRhdGlvbnOUXZRoiE6MBmNsYWltc5RdlIwJY2l0YXRpb25zlF2UdWgpfZRoK4+UKGjFaK1oEWgLaBVow2heaC5oyWhVaA9oUWgNaMdoE2gJaEtoB2iIkGgtTnViLg==", + "review__get_completed_positions.json": "gASV0QkAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwKMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwKMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lE6MFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUTowPY2l0YXRpb25fY2hlY2tzlE6MD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoKX2UaCuPlChoNGg4aDdoTWhCaFJoT2hLaDVoTmhRaFBoTGg2kGgtTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAnNoKX2UaCuPlChoW5BoLU51YowScG9sbF9hZnRlcl9zZWNvbmRzlE5oS12UjAhmYWlsdXJlc5RdlGhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UjAdmYWlsdXJllE6MBmNsYWltc5RdlChoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCXBvc2l0aW9uc5RdlGgAjAhQb3NpdGlvbpSTlCmBlH2UKGgFfZQojAVzdGFydJRLAIwDZW5klEsojAR0ZXh0lIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpR1aCl9lGgrj5QoaH1ofmh/kGgtTnViYYwGcmVzdWx0lGgAjAxSZXZpZXdSZXN1bHSUk5QpgZR9lChoBX2UKIwHdmVyZGljdJSMBFRydWWUaCCMBGhpZ2iUjAZzb3VyY2WUjAphc3Nlc3NtZW50lIwIaXNfaXNzdWWUiXVoKX2UaCuPlChoIGiJaIxojpBoLU51YowKYXNzZXNzbWVudJRoAIwQUmV2aWV3QXNzZXNzbWVudJSTlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJRoiYwEVHJ1ZZRoIIwEaGlnaJSMCXJhdGlvbmFsZZROjAdkaXNzZW50lE6MEHZlcmlmaWNhdGlvbl91cmyUTowKZXJyb3JfY29kZZROjBFpZGVudGlmaWVkX2NsYWltc5RdlIwEaGludJROjBFzdWdnZXN0ZWRfcmV3cml0ZZROaGtOdWgpfZRoK4+UKGigaJtonGggaAtoiWieaJponWihaGuQaC1OdWKMCmVzY2FsYXRpb26UaACMCkVzY2FsYXRpb26Uk5QpgZR9lChoBX2UKIwNbWF0Y2hlZF9ydWxlc5RdlIwLZGlzcG9zaXRpb26UjAxub3Rfc2VsZWN0ZWSUdWgpfZRoK4+UKGisaKqQaC1OdWKMDHZlcmlmaWNhdGlvbpROjA9zdWdnZXN0ZWRfZWRpdHOUTnVoKX2UaCuPlChodGiRaKRoc2iwaLFog2h2kGgtTnViaG8pgZR9lChoBX2UKGhzSwFodIwiV2F0ZXIgYm9pbHMgYXQgMTAwIEMgYXQgc2VhIGxldmVsLpRodl2UaHkpgZR9lChoBX2UKGh9SzdofktZaH+MIldhdGVyIGJvaWxzIGF0IDEwMCBDIGF0IHNlYSBsZXZlbC6UdWgpfZRoK4+UKGh9aH5of5BoLU51YmFog2iFKYGUfZQoaAV9lChoiYwEVHJ1ZZRoIIwEaGlnaJRojIwKYXNzZXNzbWVudJRojol1aCl9lGgrj5QoaCBoiWiMaI6QaC1OdWJokWiTKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGiJjARUcnVllGggjARoaWdolGiaTmibTmicTmidTmieXZRooE5ooU5oa051aCl9lGgrj5QoaKBom2icaCBoC2iJaJ5ommidaKFoa5BoLU51YmikaKYpgZR9lChoBX2UKGiqXZRorIwMbm90X3NlbGVjdGVklHVoKX2UaCuPlChorGiqkGgtTnViaLBOaLFOdWgpfZRoK4+UKGh0aJFopGhzaLBosWiDaHaQaC1OdWJljAljaXRhdGlvbnOUXZR1aCl9lGgrj5QoaGVoYGgRaAtoFWhjaF5oLmhpaFVoD2hRaGxoDWhnaBNoCWjZaEtoB2hrkGgtTnViLg==", + "review__get_completed_recovered_claim.json": "gASVuQcAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwGMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwGMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lE6MFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUTowPY2l0YXRpb25fY2hlY2tzlE6MD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoKX2UaCuPlChoNGg4aDdoTWhCaFJoT2hLaDVoTmhRaFBoTGg2kGgtTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAXNoKX2UaCuPlChoW5BoLU51YowScG9sbF9hZnRlcl9zZWNvbmRzlE5oS12UjAhmYWlsdXJlc5RdlGhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UjAdmYWlsdXJllE6MBmNsYWltc5RdlGgAjAtSZXZpZXdDbGFpbZSTlCmBlH2UKGgFfZQojAVpbmRleJRLAIwFY2xhaW2UjCxPcmJpdCBNb3RvcnMgc3RvY2sgaW5jcmVhc2VkIGJ5IDQwJSBpbiAyMDIyLpSMCXBvc2l0aW9uc5RdlIwGcmVzdWx0lGgAjAxSZXZpZXdSZXN1bHSUk5QpgZR9lChoBX2UKIwHdmVyZGljdJSMBFRydWWUaCCMBGhpZ2iUjAZzb3VyY2WUjAphc3Nlc3NtZW50lIwIaXNfaXNzdWWUiXVoKX2UaCuPlChoIGh+aIFog5BoLU51YowKYXNzZXNzbWVudJRoAIwQUmV2aWV3QXNzZXNzbWVudJSTlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJRofowEVHJ1ZZRoIIwEaGlnaJSMCXJhdGlvbmFsZZROjAdkaXNzZW50lE6MEHZlcmlmaWNhdGlvbl91cmyUTowKZXJyb3JfY29kZZROjBFpZGVudGlmaWVkX2NsYWltc5RdlIwEaGludJROjBFzdWdnZXN0ZWRfcmV3cml0ZZROaGtOdWgpfZRoK4+UKGiVaJBokWggaAtofmiTaI9okmiWaGuQaC1OdWKMCmVzY2FsYXRpb26UaACMCkVzY2FsYXRpb26Uk5QpgZR9lChoBX2UKIwNbWF0Y2hlZF9ydWxlc5RdlIwLZGlzcG9zaXRpb26UjAxub3Rfc2VsZWN0ZWSUdWgpfZRoK4+UKGihaJ+QaC1OdWKMDHZlcmlmaWNhdGlvbpROjA9zdWdnZXN0ZWRfZWRpdHOUTnVoKX2UaCuPlChodGiGaJloc2ilaKZoeGh2kGgtTnViYYwJY2l0YXRpb25zlF2UdWgpfZRoK4+UKGhlaGBoEWgLaBVoY2heaC5oaWhVaA9oUWhsaA1oZ2gTaAloqWhLaAdoa5BoLU51Yi4=", + "review__get_completed_with_untraced_claim.json": "gASV0QkAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwKMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwKMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lE6MFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUTowPY2l0YXRpb25fY2hlY2tzlE6MD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoKX2UaCuPlChoNGg4aDdoTWhCaFJoT2hLaDVoTmhRaFBoTGg2kGgtTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAnNoKX2UaCuPlChoW5BoLU51YowScG9sbF9hZnRlcl9zZWNvbmRzlE5oS12UjAhmYWlsdXJlc5RdlGhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UjAdmYWlsdXJllE6MBmNsYWltc5RdlChoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCXBvc2l0aW9uc5RdlGgAjAhQb3NpdGlvbpSTlCmBlH2UKGgFfZQojAVzdGFydJRLAIwDZW5klEsojAR0ZXh0lIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpR1aCl9lGgrj5QoaH1ofmh/kGgtTnViYYwGcmVzdWx0lGgAjAxSZXZpZXdSZXN1bHSUk5QpgZR9lChoBX2UKIwHdmVyZGljdJSMBFRydWWUaCCMBGhpZ2iUjAZzb3VyY2WUjAphc3Nlc3NtZW50lIwIaXNfaXNzdWWUiXVoKX2UaCuPlChoIGiJaIxojpBoLU51YowKYXNzZXNzbWVudJRoAIwQUmV2aWV3QXNzZXNzbWVudJSTlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJRoiYwEVHJ1ZZRoIIwEaGlnaJSMCXJhdGlvbmFsZZROjAdkaXNzZW50lE6MEHZlcmlmaWNhdGlvbl91cmyUTowKZXJyb3JfY29kZZROjBFpZGVudGlmaWVkX2NsYWltc5RdlIwEaGludJROjBFzdWdnZXN0ZWRfcmV3cml0ZZROaGtOdWgpfZRoK4+UKGigaJtonGggaAtoiWieaJponWihaGuQaC1OdWKMCmVzY2FsYXRpb26UaACMCkVzY2FsYXRpb26Uk5QpgZR9lChoBX2UKIwNbWF0Y2hlZF9ydWxlc5RdlIwLZGlzcG9zaXRpb26UjAxub3Rfc2VsZWN0ZWSUdWgpfZRoK4+UKGisaKqQaC1OdWKMDHZlcmlmaWNhdGlvbpROjA9zdWdnZXN0ZWRfZWRpdHOUTnVoKX2UaCuPlChodGiRaKRoc2iwaLFog2h2kGgtTnViaG8pgZR9lChoBX2UKGhzSwFodIwiV2F0ZXIgYm9pbHMgYXQgMTAwIEMgYXQgc2VhIGxldmVsLpRodl2UaHkpgZR9lChoBX2UKGh9SzJofktUaH+MIldhdGVyIGJvaWxzIGF0IDEwMCBDIGF0IHNlYSBsZXZlbC6UdWgpfZRoK4+UKGh9aH5of5BoLU51YmFog2iFKYGUfZQoaAV9lChoiYwEVHJ1ZZRoIIwEaGlnaJRojIwKYXNzZXNzbWVudJRojol1aCl9lGgrj5QoaCBoiWiMaI6QaC1OdWJokWiTKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGiJjARUcnVllGggjARoaWdolGiaTmibTmicTmidTmieXZRooE5ooU5oa051aCl9lGgrj5QoaKBom2icaCBoC2iJaJ5ommidaKFoa5BoLU51YmikaKYpgZR9lChoBX2UKGiqXZRorIwMbm90X3NlbGVjdGVklHVoKX2UaCuPlChorGiqkGgtTnViaLBOaLFOdWgpfZRoK4+UKGh0aJFopGhzaLBosWiDaHaQaC1OdWJljAljaXRhdGlvbnOUXZR1aCl9lGgrj5QoaGVoYGgRaAtoFWhjaF5oLmhpaFVoD2hRaGxoDWhnaBNoCWjZaEtoB2hrkGgtTnViLg==", + "review__get_during_quick_check.json": "gASVaQYAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJYXNzZXNzaW5nlIwHb3V0Y29tZZROjApjcmVhdGVkX2F0lIwbMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTZalIwMY29tcGxldGVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGWgjaB5oJWgmaCJoIZCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwGMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwCMBmZhaWxlZJRLAHVoJ32UaCmPlChoPGg9kGgrTnVijA12ZXJpZmljYXRpb25zlE6MBmlzc3Vlc5RLAIwPY2l0YXRpb25zX2ZvdW5klE6MEmNpdGF0aW9uc19zZWxlY3RlZJROjA5jaXRhdGlvbl9saW1pdJROjBZjaXRhdGlvbl9saW1pdF9yZWFjaGVklE6MD2NpdGF0aW9uX2NoZWNrc5ROjA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCd9lGgpj5QoaDJoNmg1aENoQGhIaEVoQWgzaERoR2hGaEJoNJBoK051YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwFzaCd9lGgpj5QoaFGQaCtOdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5RLCmhBXZSMCGZhaWx1cmVzlF2UaEddlIwRY2l0YXRpb25fZmFpbHVyZXOUXZSMC21vcmVfY2xhaW1zlF2UjBRtb3JlX2NsYWltX2xvY2F0aW9uc5RdlIwObW9yZV9jaXRhdGlvbnOUXZSMB2ZhaWx1cmWUTowGY2xhaW1zlF2UaACMC1Jldmlld0NsYWltlJOUKYGUfZQoaAV9lCiMBWluZGV4lEsAjAVjbGFpbZSMKFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UjAlwb3NpdGlvbnOUTowGcmVzdWx0lE6MCmFzc2Vzc21lbnSUaACMEFJldmlld0Fzc2Vzc21lbnSUk5QpgZR9lChoBX2UKGgLjAdydW5uaW5nlIwHdmVyZGljdJROaB5OjAlyYXRpb25hbGWUTowHZGlzc2VudJROjBB2ZXJpZmljYXRpb25fdXJslE6MCmVycm9yX2NvZGWUTowRaWRlbnRpZmllZF9jbGFpbXOUXZSMBGhpbnSUTowRc3VnZ2VzdGVkX3Jld3JpdGWUTmhhTnVoJ32UaCmPlChofGh3aHhoHmgLaHVoemh2aHlofWhhkGgrTnVijAplc2NhbGF0aW9ulE6MDHZlcmlmaWNhdGlvbpROjA9zdWdnZXN0ZWRfZWRpdHOUTnVoJ32UaCmPlChoamhuaIBoaWiBaIJobWhskGgrTnViYYwJY2l0YXRpb25zlF2UdWgnfZRoKY+UKGhbaFZoEGgLaBNoWWhUaCxoX2hLaA5oR2hiaA1oXWgRaAlohWhBaAdoYZBoK051Yi4=", + "review__get_failed_every_assessment_failed.json": "gASVfw0AAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwGZmFpbGVklIwHb3V0Y29tZZSMCmluY29tcGxldGWUjApjcmVhdGVkX2F0lIwbMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTZalIwMY29tcGxldGVkX2F0lIwbMjAyNi0xMC0wMVQxMDowNzowMC4xMjM0NTZalIwIbGFuZ3VhZ2WUjAJlbpSMBnBvbGljeZRoAIwQRXNjYWxhdGlvblBvbGljeZSTlCmBlH2UKGgFfZQojAh2ZXJkaWN0c5RdlCiMBUZhbHNllIwMTW9zdGx5IEZhbHNllIwFTWl4ZWSUZYwKY29uZmlkZW5jZZRdlIwDbG93lGGMD21heF9hc3Nlc3NtZW50c5RLFIwRbWF4X3ZlcmlmaWNhdGlvbnOUSwWMBWRlcHRolIwIc3RhbmRhcmSUjA1tYXhfY2l0YXRpb25zlEsAjA1zdWdnZXN0X2VkaXRzlIl1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgbaCVoIGgnaChoJGgjkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAdzdW1tYXJ5lGgAjA1SZXZpZXdTdW1tYXJ5lJOUKYGUfZQoaAV9lCiMD2NsYWltc19zZWxlY3RlZJRLAowLY2xhaW1fbGltaXSUSxSME2NsYWltX2xpbWl0X3JlYWNoZWSUiYwPaW5wdXRfdHJ1bmNhdGVklImMC2Fzc2Vzc21lbnRzlGgAjBZSZXZpZXdBc3Nlc3NtZW50Q291bnRzlJOUKYGUfZQoaAV9lCiMCWNvbXBsZXRlZJRLAIwGZmFpbGVklEsCdWgpfZRoK4+UKGg+aD+QaC1OdWKMDXZlcmlmaWNhdGlvbnOUaACMGFJldmlld1ZlcmlmaWNhdGlvbkNvdW50c5STlCmBlH2UKGgFfZQojAdwbGFubmVklEsAaD5LAGg/SwB1aCl9lGgrj5QoaD5oP2hIkGgtTnVijAZpc3N1ZXOUSwCMD2NpdGF0aW9uc19mb3VuZJROjBJjaXRhdGlvbnNfc2VsZWN0ZWSUTowOY2l0YXRpb25fbGltaXSUTowWY2l0YXRpb25fbGltaXRfcmVhY2hlZJROjA9jaXRhdGlvbl9jaGVja3OUTowPY2l0YXRpb25faXNzdWVzlEsAjBFjaXRhdGlvbnNfc2tpcHBlZJROdWgpfZRoK4+UKGg0aDhoN2hNaEJoUmhPaEtoNWhOaFFoUGhMaDaQaC1OdWKMB2NyZWRpdHOUaACMDVJldmlld0NyZWRpdHOUk5QpgZR9lChoBX2UjAdjaGFyZ2VklEsAc2gpfZRoK4+UKGhbkGgtTnVijBJwb2xsX2FmdGVyX3NlY29uZHOUTmhLXZSMCGZhaWx1cmVzlF2UKGgAjA1SZXZpZXdGYWlsdXJllJOUKYGUfZQoaAV9lCiMC2NsYWltX2luZGV4lEsAjAVjbGFpbZSMKFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UjAVzdGFnZZSMCmFzc2Vzc21lbnSUjAdmYWlsdXJllGgAjAxGYWlsdXJlQmxvY2uUk5QpgZR9lChoBX2UKIwOZmFpbHVyZV9yZWFzb26UjBR1cHN0cmVhbV91bmF2YWlsYWJsZZSMDWZhaWx1cmVfY2xhc3OUjBR1cHN0cmVhbV91bmF2YWlsYWJsZZSMCXJldHJ5YWJsZZSIjARoaW50lIxOQSBtb2RlbCBwcm92aWRlciB3YXMgdW5hdmFpbGFibGUgZm9yIHRoaXMgaXRlbS4gUmV0cnkgaXQ7IG5vdGhpbmcgd2FzIGNoYXJnZWQulIwIZG9jc191cmyUjDBodHRwczovL2xlbnouaW8vZG9jcy9lcnJvcnMjdXBzdHJlYW0tdW5hdmFpbGFibGWUdWgpfZRoK4+UKGh3aHJoeWh0aHaQaC1OdWJ1aCl9lGgrj5QoaGhoZ2hqaGyQaC1OdWJoYymBlH2UKGgFfZQoaGdLAWhojCJXYXRlciBib2lscyBhdCAxMDAgQyBhdCBzZWEgbGV2ZWwulGhqjAphc3Nlc3NtZW50lGhsaG4pgZR9lChoBX2UKGhyjBR1cHN0cmVhbV91bmF2YWlsYWJsZZRodIwUdXBzdHJlYW1fdW5hdmFpbGFibGWUaHaIaHeMTkEgbW9kZWwgcHJvdmlkZXIgd2FzIHVuYXZhaWxhYmxlIGZvciB0aGlzIGl0ZW0uIFJldHJ5IGl0OyBub3RoaW5nIHdhcyBjaGFyZ2VkLpRoeYwwaHR0cHM6Ly9sZW56LmlvL2RvY3MvZXJyb3JzI3Vwc3RyZWFtLXVuYXZhaWxhYmxllHVoKX2UaCuPlChod2hyaHlodGh2kGgtTnVidWgpfZRoK4+UKGhoaGdoamhskGgtTnViZWhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UaGxobimBlH2UKGgFfZQoaHKMEWFzc2Vzc21lbnRfZmFpbGVklGh0jBR1cHN0cmVhbV91bmF2YWlsYWJsZZRodohod4xdTm8gY2xhaW0gY291bGQgYmUgYXNzZXNzZWQuIFJldHJ5IHRoZSByZXZpZXcgd2l0aCBhIG5ldyBJZGVtcG90ZW5jeS1LZXk7IG5vdGhpbmcgd2FzIGNoYXJnZWQulGh5jDBodHRwczovL2xlbnouaW8vZG9jcy9lcnJvcnMjdXBzdHJlYW0tdW5hdmFpbGFibGWUdWgpfZRoK4+UKGh3aHJoeWh0aHaQaC1OdWKMBmNsYWltc5RdlChoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwBoaIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCXBvc2l0aW9uc5ROjAZyZXN1bHSUTowKYXNzZXNzbWVudJRoAIwQUmV2aWV3QXNzZXNzbWVudJSTlCmBlH2UKGgFfZQoaAuMBmZhaWxlZJSMB3ZlcmRpY3SUTmggTowJcmF0aW9uYWxllE6MB2Rpc3NlbnSUTowQdmVyaWZpY2F0aW9uX3VybJROjAplcnJvcl9jb2RllIwUdXBzdHJlYW1fdW5hdmFpbGFibGWUjBFpZGVudGlmaWVkX2NsYWltc5RdlGh3TowRc3VnZ2VzdGVkX3Jld3JpdGWUTmhsaG4pgZR9lChoBX2UKGhyjBR1cHN0cmVhbV91bmF2YWlsYWJsZZRodIwUdXBzdHJlYW1fdW5hdmFpbGFibGWUaHaIaHeMTkEgbW9kZWwgcHJvdmlkZXIgd2FzIHVuYXZhaWxhYmxlIGZvciB0aGlzIGl0ZW0uIFJldHJ5IGl0OyBub3RoaW5nIHdhcyBjaGFyZ2VkLpRoeYwwaHR0cHM6Ly9sZW56LmlvL2RvY3MvZXJyb3JzI3Vwc3RyZWFtLXVuYXZhaWxhYmxllHVoKX2UaCuPlChod2hyaHlodGh2kGgtTnVidWgpfZRoK4+UKGh3aLVotmggaAtos2i5aLRot2i7aGyQaC1OdWKMCmVzY2FsYXRpb26UTowMdmVyaWZpY2F0aW9ulE6MD3N1Z2dlc3RlZF9lZGl0c5ROdWgpfZRoK4+UKGhoaKxox2ioaMhoyWiraKqQaC1OdWJopCmBlH2UKGgFfZQoaKhLAWhojCJXYXRlciBib2lscyBhdCAxMDAgQyBhdCBzZWEgbGV2ZWwulGiqTmirTmisaK4pgZR9lChoBX2UKGgLjAZmYWlsZWSUaLNOaCBOaLROaLVOaLZOaLeMFHVwc3RyZWFtX3VuYXZhaWxhYmxllGi5XZRod05ou05obGhuKYGUfZQoaAV9lChocowUdXBzdHJlYW1fdW5hdmFpbGFibGWUaHSMFHVwc3RyZWFtX3VuYXZhaWxhYmxllGh2iGh3jE5BIG1vZGVsIHByb3ZpZGVyIHdhcyB1bmF2YWlsYWJsZSBmb3IgdGhpcyBpdGVtLiBSZXRyeSBpdDsgbm90aGluZyB3YXMgY2hhcmdlZC6UaHmMMGh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyN1cHN0cmVhbS11bmF2YWlsYWJsZZR1aCl9lGgrj5QoaHdocmh5aHRodpBoLU51YnVoKX2UaCuPlChod2i1aLZoIGgLaLNouWi0aLdou2hskGgtTnViaMdOaMhOaMlOdWgpfZRoK4+UKGhoaKxox2ioaMhoyWiraKqQaC1OdWJljAljaXRhdGlvbnOUXZR1aCl9lGgrj5QoaJJoYGgRaAtoFWiQaF5oLmiWaFVoD2hRaKFoDWiUaBNoCWjjaEtoB2hskGgtTnViLg==", + "review__get_failed_no_claim.json": "gASV3gUAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwGZmFpbGVklIwHb3V0Y29tZZSMCXVuY2hlY2tlZJSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjAhsYW5ndWFnZZSMAmVulIwGcG9saWN5lGgAjBBFc2NhbGF0aW9uUG9saWN5lJOUKYGUfZQoaAV9lCiMCHZlcmRpY3RzlF2UKIwFRmFsc2WUjAxNb3N0bHkgRmFsc2WUjAVNaXhlZJRljApjb25maWRlbmNllF2UjANsb3eUYYwPbWF4X2Fzc2Vzc21lbnRzlEsUjBFtYXhfdmVyaWZpY2F0aW9uc5RLBYwFZGVwdGiUjAhzdGFuZGFyZJSMDW1heF9jaXRhdGlvbnOUSwCMDXN1Z2dlc3RfZWRpdHOUiXWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBtoJWggaCdoKGgkaCOQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMB3N1bW1hcnmUaACMDVJldmlld1N1bW1hcnmUk5QpgZR9lChoBX2UKIwPY2xhaW1zX3NlbGVjdGVklE6MC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklE6MD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5ROjA12ZXJpZmljYXRpb25zlE6MBmlzc3Vlc5RLAIwPY2l0YXRpb25zX2ZvdW5klE6MEmNpdGF0aW9uc19zZWxlY3RlZJROjA5jaXRhdGlvbl9saW1pdJROjBZjaXRhdGlvbl9saW1pdF9yZWFjaGVklE6MD2NpdGF0aW9uX2NoZWNrc5ROjA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aDxoOWhBaD5oOmg1aD1oQGg/aDtoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwBzaCl9lGgrj5QoaEqQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaDpdlIwIZmFpbHVyZXOUXZRoQF2UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUTowUbW9yZV9jbGFpbV9sb2NhdGlvbnOUTowObW9yZV9jaXRhdGlvbnOUTowHZmFpbHVyZZRoAIwMRmFpbHVyZUJsb2NrlJOUKYGUfZQoaAV9lCiMDmZhaWx1cmVfcmVhc29ulIwIbm9fY2xhaW2UjA1mYWlsdXJlX2NsYXNzlIwNaW52YWxpZF9pbnB1dJSMCXJldHJ5YWJsZZSJjARoaW50lIyKVGhlIHRleHQgaXMgYSBncmVldGluZywgbm90IGEgc3RhdGVtZW50IGFib3V0IHRoZSB3b3JsZC4gU2VuZCBvbmUgZmFjdHVhbCBjbGFpbSwgb3IgcnVuIHRoZSB0ZXh0IHRocm91Z2ggL2V4dHJhY3QgdG8gZW51bWVyYXRlIGl0cyBjbGFpbXMulIwIZG9jc191cmyUjClodHRwczovL2xlbnouaW8vZG9jcy9lcnJvcnMjaW52YWxpZC1pbnB1dJR1aCl9lGgrj5QoaGJoXWhkaF9oYZBoLU51YowGY2xhaW1zlF2UjAljaXRhdGlvbnOUXZR1aCl9lGgrj5QoaFRoT2gRaAtoFWhSaE1oLmhWaERoD2hAaGhoDWhVaBNoCWhqaDpoB2hXkGgtTnViLg==", + "review__get_failed_no_claim_untraced.json": "gASV5gUAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwGZmFpbGVklIwHb3V0Y29tZZSMCXVuY2hlY2tlZJSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjAhsYW5ndWFnZZSMAmVulIwGcG9saWN5lGgAjBBFc2NhbGF0aW9uUG9saWN5lJOUKYGUfZQoaAV9lCiMCHZlcmRpY3RzlF2UKIwFRmFsc2WUjAxNb3N0bHkgRmFsc2WUjAVNaXhlZJRljApjb25maWRlbmNllF2UjANsb3eUYYwPbWF4X2Fzc2Vzc21lbnRzlEsUjBFtYXhfdmVyaWZpY2F0aW9uc5RLBYwFZGVwdGiUjAhzdGFuZGFyZJSMDW1heF9jaXRhdGlvbnOUSwCMDXN1Z2dlc3RfZWRpdHOUiXWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBtoJWggaCdoKGgkaCOQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMB3N1bW1hcnmUaACMDVJldmlld1N1bW1hcnmUk5QpgZR9lChoBX2UKIwPY2xhaW1zX3NlbGVjdGVklE6MC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklE6MD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5ROjA12ZXJpZmljYXRpb25zlE6MBmlzc3Vlc5RLAIwPY2l0YXRpb25zX2ZvdW5klE6MEmNpdGF0aW9uc19zZWxlY3RlZJROjA5jaXRhdGlvbl9saW1pdJROjBZjaXRhdGlvbl9saW1pdF9yZWFjaGVklE6MD2NpdGF0aW9uX2NoZWNrc5ROjA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aDxoOWhBaD5oOmg1aD1oQGg/aDtoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwBzaCl9lGgrj5QoaEqQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaDpdlIwIZmFpbHVyZXOUXZRoQF2UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUTowUbW9yZV9jbGFpbV9sb2NhdGlvbnOUTowObW9yZV9jaXRhdGlvbnOUTowHZmFpbHVyZZRoAIwMRmFpbHVyZUJsb2NrlJOUKYGUfZQoaAV9lCiMDmZhaWx1cmVfcmVhc29ulIwIbm9fY2xhaW2UjA1mYWlsdXJlX2NsYXNzlIwNaW52YWxpZF9pbnB1dJSMCXJldHJ5YWJsZZSJjARoaW50lIySTm9uZSBvZiB0aGUgY2xhaW1zIGZvdW5kIGluIHRoZSB0ZXh0IGNvdWxkIGJlIHRyYWNlZCBiYWNrIHRvIGl0LiBTZW5kIG9uZSBmYWN0dWFsIGNsYWltLCBvciBydW4gdGhlIHRleHQgdGhyb3VnaCAvZXh0cmFjdCB0byBlbnVtZXJhdGUgaXRzIGNsYWltcy6UjAhkb2NzX3VybJSMKWh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyNpbnZhbGlkLWlucHV0lHVoKX2UaCuPlChoYmhdaGRoX2hhkGgtTnVijAZjbGFpbXOUXZSMCWNpdGF0aW9uc5RdlHVoKX2UaCuPlChoVGhPaBFoC2gVaFJoTWguaFZoRGgPaEBoaGgNaFVoE2gJaGpoOmgHaFeQaC1OdWIu", + "review__get_more_claims.json": "gASVnQoAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSwKMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwKMC2NsYWltX2xpbWl0lEsCjBNjbGFpbV9saW1pdF9yZWFjaGVklIiMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwKMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lE6MFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUTowPY2l0YXRpb25fY2hlY2tzlE6MD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoKX2UaCuPlChoNGg4aDdoTWhCaFJoT2hLaDVoTmhRaFBoTGg2kGgtTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAnNoKX2UaCuPlChoW5BoLU51YowScG9sbF9hZnRlcl9zZWNvbmRzlE5oS12UjAhmYWlsdXJlc5RdlGhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIweVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulGGMFG1vcmVfY2xhaW1fbG9jYXRpb25zlF2UaACMDUNsYWltTG9jYXRpb26Uk5QpgZR9lChoBX2UKIwFY2xhaW2UjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UjAlwb3NpdGlvbnOUXZRoAIwIUG9zaXRpb26Uk5QpgZR9lChoBX2UKIwFc3RhcnSUS1uMA2VuZJRLeYwEdGV4dJSMHlRoZSBFaWZmZWwgVG93ZXIgaXMgaW4gQmVybGluLpR1aCl9lGgrj5QoaHhoeWh6kGgtTnViYXVoKX2UaCuPlChob2hxkGgtTnViYYwObW9yZV9jaXRhdGlvbnOUXZSMB2ZhaWx1cmWUTowGY2xhaW1zlF2UKGgAjAtSZXZpZXdDbGFpbZSTlCmBlH2UKGgFfZQojAVpbmRleJRLAGhvjChUaGUgRVUgQUkgQWN0IHRvb2sgZWZmZWN0IGluIE1hcmNoIDIwMjQulGhxXZRodCmBlH2UKGgFfZQoaHhLAGh5SyhoeowoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpR1aCl9lGgrj5QoaHhoeWh6kGgtTnViYYwGcmVzdWx0lGgAjAxSZXZpZXdSZXN1bHSUk5QpgZR9lChoBX2UKIwHdmVyZGljdJSMBFRydWWUaCCMBGhpZ2iUjAZzb3VyY2WUjAphc3Nlc3NtZW50lIwIaXNfaXNzdWWUiXVoKX2UaCuPlChoIGiZaJxonpBoLU51YowKYXNzZXNzbWVudJRoAIwQUmV2aWV3QXNzZXNzbWVudJSTlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJRomYwEVHJ1ZZRoIIwEaGlnaJSMCXJhdGlvbmFsZZROjAdkaXNzZW50lE6MEHZlcmlmaWNhdGlvbl91cmyUTowKZXJyb3JfY29kZZROjBFpZGVudGlmaWVkX2NsYWltc5RdlIwEaGludJROjBFzdWdnZXN0ZWRfcmV3cml0ZZROaIJOdWgpfZRoK4+UKGiwaKtorGggaAtomWiuaKporWixaIKQaC1OdWKMCmVzY2FsYXRpb26UaACMCkVzY2FsYXRpb26Uk5QpgZR9lChoBX2UKIwNbWF0Y2hlZF9ydWxlc5RdlIwLZGlzcG9zaXRpb26UjAxub3Rfc2VsZWN0ZWSUdWgpfZRoK4+UKGi8aLqQaC1OdWKMDHZlcmlmaWNhdGlvbpROjA9zdWdnZXN0ZWRfZWRpdHOUTnVoKX2UaCuPlChob2ihaLRoimjAaMFok2hxkGgtTnViaIYpgZR9lChoBX2UKGiKSwFob4wiV2F0ZXIgYm9pbHMgYXQgMTAwIEMgYXQgc2VhIGxldmVsLpRocV2UaHQpgZR9lChoBX2UKGh4SzJoeUtUaHqMIldhdGVyIGJvaWxzIGF0IDEwMCBDIGF0IHNlYSBsZXZlbC6UdWgpfZRoK4+UKGh4aHloepBoLU51YmFok2iVKYGUfZQoaAV9lChomYwEVHJ1ZZRoIIwEaGlnaJRonIwKYXNzZXNzbWVudJRonol1aCl9lGgrj5QoaCBomWicaJ6QaC1OdWJooWijKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGiZjARUcnVllGggjARoaWdolGiqTmirTmisTmitTmiuXZRosE5osU5ogk51aCl9lGgrj5QoaLBoq2isaCBoC2iZaK5oqmitaLFogpBoLU51Ymi0aLYpgZR9lChoBX2UKGi6XZRovIwMbm90X3NlbGVjdGVklHVoKX2UaCuPlChovGi6kGgtTnViaMBOaMFOdWgpfZRoK4+UKGhvaKFotGiKaMBowWiTaHGQaC1OdWJljAljaXRhdGlvbnOUXZR1aCl9lGgrj5QoaGVoYGgRaAtoFWhjaF5oLmiAaFVoD2hRaINoDWhoaBNoCWjpaEtoB2iCkGgtTnViLg==", + "review__get_nested_verification_modified_at_crosses_midnight_by_minutes.json": "gASVfAwAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMDGlzc3Vlc19mb3VuZJSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjAhsYW5ndWFnZZSMAmVulIwGcG9saWN5lGgAjBBFc2NhbGF0aW9uUG9saWN5lJOUKYGUfZQoaAV9lCiMCHZlcmRpY3RzlF2UKIwFRmFsc2WUjAxNb3N0bHkgRmFsc2WUjAVNaXhlZJRljApjb25maWRlbmNllF2UjANsb3eUYYwPbWF4X2Fzc2Vzc21lbnRzlEsUjBFtYXhfdmVyaWZpY2F0aW9uc5RLBYwFZGVwdGiUjAhzdGFuZGFyZJSMDW1heF9jaXRhdGlvbnOUSwCMDXN1Z2dlc3RfZWRpdHOUiXWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBtoJWggaCdoKGgkaCOQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMB3N1bW1hcnmUaACMDVJldmlld1N1bW1hcnmUk5QpgZR9lChoBX2UKIwPY2xhaW1zX3NlbGVjdGVklEsBjAtjbGFpbV9saW1pdJRLFIwTY2xhaW1fbGltaXRfcmVhY2hlZJSJjA9pbnB1dF90cnVuY2F0ZWSUiYwLYXNzZXNzbWVudHOUaACMFlJldmlld0Fzc2Vzc21lbnRDb3VudHOUk5QpgZR9lChoBX2UKIwJY29tcGxldGVklEsBjAZmYWlsZWSUSwB1aCl9lGgrj5QoaD5oP5BoLU51YowNdmVyaWZpY2F0aW9uc5RoAIwYUmV2aWV3VmVyaWZpY2F0aW9uQ291bnRzlJOUKYGUfZQoaAV9lCiMB3BsYW5uZWSUSwFoPksBaD9LAHVoKX2UaCuPlChoPmg/aEiQaC1OdWKMBmlzc3Vlc5RLAYwPY2l0YXRpb25zX2ZvdW5klE6MEmNpdGF0aW9uc19zZWxlY3RlZJROjA5jaXRhdGlvbl9saW1pdJROjBZjaXRhdGlvbl9saW1pdF9yZWFjaGVklE6MD2NpdGF0aW9uX2NoZWNrc5ROjA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aE1oQmhSaE9oS2g1aE5oUWhQaExoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwtzaCl9lGgrj5QoaFuQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaEtdlGgAjAtSZXZpZXdJc3N1ZZSTlCmBlH2UKGgFfZQojAtjbGFpbV9pbmRleJRLAIwFY2xhaW2UjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UjA52ZXJpZmllZF9jbGFpbZROjAd2ZXJkaWN0lIwFRmFsc2WUaCCMBGhpZ2iUjAZzb3VyY2WUjAx2ZXJpZmljYXRpb26UjA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSME3ZlcmlmaWNhdGlvbl9zdGF0dXOUjAljb21wbGV0ZWSUjBB2ZXJpZmljYXRpb25fdXJslIwtaHR0cHM6Ly9sZW56LmlvL2FwaS92MS92ZXJpZmljYXRpb25zLzY4Y2E0YWFmlIwDdXJslIwtaHR0cHM6Ly9sZW56LmlvL2MvdGhlLWVhcnRoLWlzLXJvdW5kLTY4Y2E0YWFmlIwKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAd2ZXJkaWN0lGGMC2Rpc3Bvc2l0aW9ulIwHcGxhbm5lZJR1aCl9lGgrj5QoaH9ofJBoLU51YowLa2V5X2ZpbmRpbmeUjCpGaW5kaW5nIGZvciBUaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UjAlyYXRpb25hbGWUTowRc3VnZ2VzdGVkX3Jld3JpdGWUjCVGaXhlZDogVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulIwHZmFpbHVyZZROjA9zdWdnZXN0ZWRfZWRpdHOUTnVoKX2UaCuPlChoZmhuaHJoIGhpaHBodmiFaIlodGhsaGhoZWiDaIZoiJBoLU51YmGMCGZhaWx1cmVzlF2UaFFdlIwRY2l0YXRpb25fZmFpbHVyZXOUXZSMC21vcmVfY2xhaW1zlF2UjBRtb3JlX2NsYWltX2xvY2F0aW9uc5RdlIwObW9yZV9jaXRhdGlvbnOUXZRoiE6MBmNsYWltc5RdlGgAjAtSZXZpZXdDbGFpbZSTlCmBlH2UKGgFfZQojAVpbmRleJRLAGhmjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UjAlwb3NpdGlvbnOUTowGcmVzdWx0lGgAjAxSZXZpZXdSZXN1bHSUk5QpgZR9lChoBX2UKGhpjAVGYWxzZZRoIIwEaGlnaJRobIwMdmVyaWZpY2F0aW9ulIwIaXNfaXNzdWWUiHVoKX2UaCuPlChoIGhpaGxoqpBoLU51YowKYXNzZXNzbWVudJRoAIwQUmV2aWV3QXNzZXNzbWVudJSTlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJRoaYwFRmFsc2WUaCCMBGhpZ2iUaIVOjAdkaXNzZW50lE5ock6MCmVycm9yX2NvZGWUTowRaWRlbnRpZmllZF9jbGFpbXOUXZSMBGhpbnSUTmiGTmiITnVoKX2UaCuPlChoumi2aHJoIGgLaGlouGiFaLdohmiIkGgtTnViaHZoeCmBlH2UKGgFfZQoaHxdlIwHdmVyZGljdJRhaH+MB3BsYW5uZWSUdWgpfZRoK4+UKGh/aHyQaC1OdWKMDHZlcmlmaWNhdGlvbpRoAIwSUmV2aWV3VmVyaWZpY2F0aW9ulJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklIwOY29udGVudF9zdGF0dXOUjAlhdmFpbGFibGWUaG6MCDY4Y2E0YWFmlIwHdGFza19pZJSMIDdjZmYxOGRhMmQ5NzlkNjM3MGU1NGExNjBiZTEyMWFklGhmjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UaBOMAmVulIwKdmlzaWJpbGl0eZSMB3ByaXZhdGWUaCWMCHN0YW5kYXJklIwGZG9tYWlulIwAlIwIZW50aXRpZXOUXZRoaYwFRmFsc2WUaCCMBGhpZ2iUjApsZW56X3Njb3JllEsCaIOMKkZpbmRpbmcgZm9yIFRoZSBFaWZmZWwgVG93ZXIgaXMgaW4gQmVybGluLpSMEWV4ZWN1dGl2ZV9zdW1tYXJ5lIwqU3VtbWFyeSBmb3IgVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulGiGjCVGaXhlZDogVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulIwId2FybmluZ3OUXZSMAncxlGFoD4wgMjAyNi0xMC0wMVQyMzo1NTowMC4xMjM0NTYrMDA6MDCUjAttb2RpZmllZF9hdJSMIDIwMjYtMTAtMDJUMDA6MDM6MDAuMTIzNDU2KzAwOjAwlGhyjC1odHRwczovL2xlbnouaW8vYXBpL3YxL3ZlcmlmaWNhdGlvbnMvNjhjYTRhYWaUaHSMLWh0dHBzOi8vbGVuei5pby9jL3RoZS1lYXJ0aC1pcy1yb3VuZC02OGNhNGFhZpRoiE51aCl9lGgrj5QoaG5ocmjYaCBo5WjeaHRo02gLaNZog2hmaCVoD2hpaIZo4WjPaBNo3GjMaIiQaC1OdWJoiU51aCl9lGgrj5QoaGZorWh2aJ5oxWiJaKFooJBoLU51YmGMCWNpdGF0aW9uc5RdlHVoKX2UaCuPlChokWiMaBFoC2gVaI9oXmguaJVoVWgPaFFol2gNaJNoE2gJaO1oS2gHaIiQaC1OdWIu", + "review__get_nested_verification_modified_at_same_day_hours_apart.json": "gASVWgwAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMDGlzc3Vlc19mb3VuZJSMCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUjBsyMDI2LTEwLTAxVDEwOjA3OjAwLjEyMzQ1NlqUjAhsYW5ndWFnZZSMAmVulIwGcG9saWN5lGgAjBBFc2NhbGF0aW9uUG9saWN5lJOUKYGUfZQoaAV9lCiMCHZlcmRpY3RzlF2UKIwFRmFsc2WUjAxNb3N0bHkgRmFsc2WUjAVNaXhlZJRljApjb25maWRlbmNllF2UjANsb3eUYYwPbWF4X2Fzc2Vzc21lbnRzlEsUjBFtYXhfdmVyaWZpY2F0aW9uc5RLBYwFZGVwdGiUjAhzdGFuZGFyZJSMDW1heF9jaXRhdGlvbnOUSwCMDXN1Z2dlc3RfZWRpdHOUiXWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBtoJWggaCdoKGgkaCOQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMB3N1bW1hcnmUaACMDVJldmlld1N1bW1hcnmUk5QpgZR9lChoBX2UKIwPY2xhaW1zX3NlbGVjdGVklEsBjAtjbGFpbV9saW1pdJRLFIwTY2xhaW1fbGltaXRfcmVhY2hlZJSJjA9pbnB1dF90cnVuY2F0ZWSUiYwLYXNzZXNzbWVudHOUaACMFlJldmlld0Fzc2Vzc21lbnRDb3VudHOUk5QpgZR9lChoBX2UKIwJY29tcGxldGVklEsBjAZmYWlsZWSUSwB1aCl9lGgrj5QoaD5oP5BoLU51YowNdmVyaWZpY2F0aW9uc5RoAIwYUmV2aWV3VmVyaWZpY2F0aW9uQ291bnRzlJOUKYGUfZQoaAV9lCiMB3BsYW5uZWSUSwFoPksBaD9LAHVoKX2UaCuPlChoPmg/aEiQaC1OdWKMBmlzc3Vlc5RLAYwPY2l0YXRpb25zX2ZvdW5klE6MEmNpdGF0aW9uc19zZWxlY3RlZJROjA5jaXRhdGlvbl9saW1pdJROjBZjaXRhdGlvbl9saW1pdF9yZWFjaGVklE6MD2NpdGF0aW9uX2NoZWNrc5ROjA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCl9lGgrj5QoaDRoOGg3aE1oQmhSaE9oS2g1aE5oUWhQaExoNpBoLU51YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwtzaCl9lGgrj5QoaFuQaC1OdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaEtdlGgAjAtSZXZpZXdJc3N1ZZSTlCmBlH2UKGgFfZQojAtjbGFpbV9pbmRleJRLAIwFY2xhaW2UjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UjA52ZXJpZmllZF9jbGFpbZROjAd2ZXJkaWN0lIwFRmFsc2WUaCCMBGhpZ2iUjAZzb3VyY2WUjAx2ZXJpZmljYXRpb26UjA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSME3ZlcmlmaWNhdGlvbl9zdGF0dXOUjAljb21wbGV0ZWSUjBB2ZXJpZmljYXRpb25fdXJslIwtaHR0cHM6Ly9sZW56LmlvL2FwaS92MS92ZXJpZmljYXRpb25zLzY4Y2E0YWFmlIwDdXJslIwtaHR0cHM6Ly9sZW56LmlvL2MvdGhlLWVhcnRoLWlzLXJvdW5kLTY4Y2E0YWFmlIwKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAd2ZXJkaWN0lGGMC2Rpc3Bvc2l0aW9ulIwHcGxhbm5lZJR1aCl9lGgrj5QoaH9ofJBoLU51YowLa2V5X2ZpbmRpbmeUjCpGaW5kaW5nIGZvciBUaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UjAlyYXRpb25hbGWUTowRc3VnZ2VzdGVkX3Jld3JpdGWUjCVGaXhlZDogVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulIwHZmFpbHVyZZROjA9zdWdnZXN0ZWRfZWRpdHOUTnVoKX2UaCuPlChoZmhuaHJoIGhpaHBodmiFaIlodGhsaGhoZWiDaIZoiJBoLU51YmGMCGZhaWx1cmVzlF2UaFFdlIwRY2l0YXRpb25fZmFpbHVyZXOUXZSMC21vcmVfY2xhaW1zlF2UjBRtb3JlX2NsYWltX2xvY2F0aW9uc5RdlIwObW9yZV9jaXRhdGlvbnOUXZRoiE6MBmNsYWltc5RdlGgAjAtSZXZpZXdDbGFpbZSTlCmBlH2UKGgFfZQojAVpbmRleJRLAGhmjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UjAlwb3NpdGlvbnOUTowGcmVzdWx0lGgAjAxSZXZpZXdSZXN1bHSUk5QpgZR9lChoBX2UKGhpjAVGYWxzZZRoIIwEaGlnaJRobIwMdmVyaWZpY2F0aW9ulIwIaXNfaXNzdWWUiHVoKX2UaCuPlChoIGhpaGxoqpBoLU51YowKYXNzZXNzbWVudJRoAIwQUmV2aWV3QXNzZXNzbWVudJSTlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJRoaYwFRmFsc2WUaCCMBGhpZ2iUaIVOjAdkaXNzZW50lE5ock6MCmVycm9yX2NvZGWUTowRaWRlbnRpZmllZF9jbGFpbXOUXZSMBGhpbnSUTmiGTmiITnVoKX2UaCuPlChoumi2aHJoIGgLaGlouGiFaLdohmiIkGgtTnViaHZoeCmBlH2UKGgFfZQoaHxdlIwHdmVyZGljdJRhaH+MB3BsYW5uZWSUdWgpfZRoK4+UKGh/aHyQaC1OdWKMDHZlcmlmaWNhdGlvbpRoAIwSUmV2aWV3VmVyaWZpY2F0aW9ulJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklIwOY29udGVudF9zdGF0dXOUjAlhdmFpbGFibGWUaG6MCDY4Y2E0YWFmlIwHdGFza19pZJSMIDdjZmYxOGRhMmQ5NzlkNjM3MGU1NGExNjBiZTEyMWFklGhmjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UaBOMAmVulIwKdmlzaWJpbGl0eZSMB3ByaXZhdGWUaCWMCHN0YW5kYXJklIwGZG9tYWlulIwAlIwIZW50aXRpZXOUXZRoaYwFRmFsc2WUaCCMBGhpZ2iUjApsZW56X3Njb3JllEsCaIOMKkZpbmRpbmcgZm9yIFRoZSBFaWZmZWwgVG93ZXIgaXMgaW4gQmVybGluLpSMEWV4ZWN1dGl2ZV9zdW1tYXJ5lIwqU3VtbWFyeSBmb3IgVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulGiGjCVGaXhlZDogVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulIwId2FybmluZ3OUXZSMAncxlGFoD4wgMjAyNi0xMC0wMVQwODowMDowMC4xMjM0NTYrMDA6MDCUjAttb2RpZmllZF9hdJROaHKMLWh0dHBzOi8vbGVuei5pby9hcGkvdjEvdmVyaWZpY2F0aW9ucy82OGNhNGFhZpRodIwtaHR0cHM6Ly9sZW56LmlvL2MvdGhlLWVhcnRoLWlzLXJvdW5kLTY4Y2E0YWFmlGiITnVoKX2UaCuPlChobmhyaNhoIGjlaN5odGjTaAto1miDaGZoJWgPaGlohmjhaM9oE2jcaMxoiJBoLU51YmiJTnVoKX2UaCuPlChoZmitaHZonmjFaIlooWigkGgtTnViYYwJY2l0YXRpb25zlF2UdWgpfZRoK4+UKGiRaIxoEWgLaBVoj2heaC5olWhVaA9oUWiXaA1ok2gTaAlo7GhLaAdoiJBoLU51Yi4=", + "review__get_policy_resolved.json": "gASVlwcAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZSMBUZhbHNllGGMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsCjAVkZXB0aJSMA2xvd5SMDW1heF9jaXRhdGlvbnOUSwCMDXN1Z2dlc3RfZWRpdHOUiXWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBtoI2geaCVoJmgiaCGQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMB3N1bW1hcnmUaACMDVJldmlld1N1bW1hcnmUk5QpgZR9lChoBX2UKIwPY2xhaW1zX3NlbGVjdGVklEsBjAtjbGFpbV9saW1pdJRLFIwTY2xhaW1fbGltaXRfcmVhY2hlZJSJjA9pbnB1dF90cnVuY2F0ZWSUiYwLYXNzZXNzbWVudHOUaACMFlJldmlld0Fzc2Vzc21lbnRDb3VudHOUk5QpgZR9lChoBX2UKIwJY29tcGxldGVklEsBjAZmYWlsZWSUSwB1aCd9lGgpj5QoaDxoPZBoK051YowNdmVyaWZpY2F0aW9uc5RoAIwYUmV2aWV3VmVyaWZpY2F0aW9uQ291bnRzlJOUKYGUfZQoaAV9lCiMB3BsYW5uZWSUSwBoPEsAaD1LAHVoJ32UaCmPlChoPGg9aEaQaCtOdWKMBmlzc3Vlc5RLAIwPY2l0YXRpb25zX2ZvdW5klE6MEmNpdGF0aW9uc19zZWxlY3RlZJROjA5jaXRhdGlvbl9saW1pdJROjBZjaXRhdGlvbl9saW1pdF9yZWFjaGVklE6MD2NpdGF0aW9uX2NoZWNrc5ROjA9jaXRhdGlvbl9pc3N1ZXOUSwCMEWNpdGF0aW9uc19za2lwcGVklE51aCd9lGgpj5QoaDJoNmg1aEtoQGhQaE1oSWgzaExoT2hOaEpoNJBoK051YowHY3JlZGl0c5RoAIwNUmV2aWV3Q3JlZGl0c5STlCmBlH2UKGgFfZSMB2NoYXJnZWSUSwFzaCd9lGgpj5QoaFmQaCtOdWKMEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROaEldlIwIZmFpbHVyZXOUXZRoT12UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUXZSMFG1vcmVfY2xhaW1fbG9jYXRpb25zlF2UjA5tb3JlX2NpdGF0aW9uc5RdlIwHZmFpbHVyZZROjAZjbGFpbXOUXZRoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwCMBWNsYWltlIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpSMCXBvc2l0aW9uc5ROjAZyZXN1bHSUaACMDFJldmlld1Jlc3VsdJSTlCmBlH2UKGgFfZQojAd2ZXJkaWN0lIwEVHJ1ZZRoHowEaGlnaJSMBnNvdXJjZZSMCmFzc2Vzc21lbnSUjAhpc19pc3N1ZZSJdWgnfZRoKY+UKGgeaHtofmiAkGgrTnVijAphc3Nlc3NtZW50lGgAjBBSZXZpZXdBc3Nlc3NtZW50lJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGh7jARUcnVllGgejARoaWdolIwJcmF0aW9uYWxllE6MB2Rpc3NlbnSUTowQdmVyaWZpY2F0aW9uX3VybJROjAplcnJvcl9jb2RllE6MEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE6MEXN1Z2dlc3RlZF9yZXdyaXRllE5oaU51aCd9lGgpj5QoaJJojWiOaB5oC2h7aJBojGiPaJNoaZBoK051YowKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAtkaXNwb3NpdGlvbpSMDG5vdF9zZWxlY3RlZJR1aCd9lGgpj5QoaJ5onJBoK051YowMdmVyaWZpY2F0aW9ulE6MD3N1Z2dlc3RlZF9lZGl0c5ROdWgnfZRoKY+UKGhyaINolmhxaKJoo2h1aHSQaCtOdWJhjAljaXRhdGlvbnOUXZR1aCd9lGgpj5QoaGNoXmgRaAtoFWhhaFxoLGhnaFNoD2hPaGpoDWhlaBNoCWimaEloB2hpkGgrTnViLg==", + "review__get_queued.json": "gASVbAQAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwGcXVldWVklIwHb3V0Y29tZZROjApjcmVhdGVkX2F0lIwbMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTZalIwMY29tcGxldGVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGWgjaB5oJWgmaCJoIZCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUTowLY2xhaW1fbGltaXSUSxSME2NsYWltX2xpbWl0X3JlYWNoZWSUTowPaW5wdXRfdHJ1bmNhdGVklImMC2Fzc2Vzc21lbnRzlE6MDXZlcmlmaWNhdGlvbnOUTowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lE6MFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUTowPY2l0YXRpb25fY2hlY2tzlE6MD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoJ32UaCmPlChoMmg2aDVoOmg3aD9oPGg4aDNoO2g+aD1oOWg0kGgrTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAHNoJ32UaCmPlChoSJBoK051YowScG9sbF9hZnRlcl9zZWNvbmRzlEsKaDhdlIwIZmFpbHVyZXOUXZRoPl2UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUTowUbW9yZV9jbGFpbV9sb2NhdGlvbnOUTowObW9yZV9jaXRhdGlvbnOUTowHZmFpbHVyZZROjAZjbGFpbXOUXZSMCWNpdGF0aW9uc5RdlHVoJ32UaCmPlChoUmhNaBBoC2gTaFBoS2gsaFRoQmgOaD5oVmgNaFNoEWgJaFhoOGgHaFWQaCtOdWIu", + "review__get_suggested_edits.json": "gASV2xEAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJdmVyaWZ5aW5nlIwHb3V0Y29tZZROjApjcmVhdGVkX2F0lIwbMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTZalIwMY29tcGxldGVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAIwNc3VnZ2VzdF9lZGl0c5SIdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGWgjaB5oJWgmaCJoIZCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwKMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwKMBmZhaWxlZJRLAHVoJ32UaCmPlChoPGg9kGgrTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAmg8SwFoPUsAdWgnfZRoKY+UKGg8aD1oRpBoK051YowGaXNzdWVzlEsCjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lE6MFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUTowPY2l0YXRpb25fY2hlY2tzlE6MD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoJ32UaCmPlChoMmg2aDVoS2hAaFBoTWhJaDNoTGhPaE5oSmg0kGgrTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLDHNoJ32UaCmPlChoWZBoK051YowScG9sbF9hZnRlcl9zZWNvbmRzlEsPaEldlChoAIwLUmV2aWV3SXNzdWWUk5QpgZR9lChoBX2UKIwLY2xhaW1faW5kZXiUSwCMBWNsYWltlIweVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulIwOdmVyaWZpZWRfY2xhaW2UTowHdmVyZGljdJSMBUZhbHNllGgejARoaWdolIwGc291cmNllIwMdmVyaWZpY2F0aW9ulIwPdmVyaWZpY2F0aW9uX2lklIwINjhjYTRhYWaUjBN2ZXJpZmljYXRpb25fc3RhdHVzlIwJY29tcGxldGVklIwQdmVyaWZpY2F0aW9uX3VybJSMLWh0dHBzOi8vbGVuei5pby9hcGkvdjEvdmVyaWZpY2F0aW9ucy82OGNhNGFhZpSMA3VybJSMLWh0dHBzOi8vbGVuei5pby9jL3RoZS1lYXJ0aC1pcy1yb3VuZC02OGNhNGFhZpSMCmVzY2FsYXRpb26UaACMCkVzY2FsYXRpb26Uk5QpgZR9lChoBX2UKIwNbWF0Y2hlZF9ydWxlc5RdlIwHdmVyZGljdJRhjAtkaXNwb3NpdGlvbpSMB3BsYW5uZWSUdWgnfZRoKY+UKGh9aHqQaCtOdWKMC2tleV9maW5kaW5nlIwqRmluZGluZyBmb3IgVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulIwJcmF0aW9uYWxllE6MEXN1Z2dlc3RlZF9yZXdyaXRllIwlRml4ZWQ6IFRoZSBFaWZmZWwgVG93ZXIgaXMgaW4gQmVybGluLpSMB2ZhaWx1cmWUTowPc3VnZ2VzdGVkX2VkaXRzlGgAjA5TdWdnZXN0ZWRFZGl0c5STlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJSMBWVkaXRzlF2UaACMDVN1Z2dlc3RlZEVkaXSUk5QpgZR9lChoBX2UKIwIcG9zaXRpb26USwCMBXN0YXJ0lEsXjANlbmSUSx2MBHRleHSUjAZCZXJsaW6UjAtyZXBsYWNlbWVudJSMBVBhcmlzlHVoJ32UaCmPlCholmiVaJpol2iYkGgrTnViYXVoJ32UaCmPlChojmgLkGgrTnVidWgnfZRoKY+UKGhkaGxocGgeaGdobmh0aINoh2hyaGpoZmhjaIFohGiGkGgrTnViaF8pgZR9lChoBX2UKGhjSwFoZIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpRoZk5oZ4wFRmFsc2WUaB6MBGhpZ2iUaGqMCmFzc2Vzc21lbnSUaGxOaG6MCnByb2Nlc3NpbmeUaHBOaHJOaHRodimBlH2UKGgFfZQoaHpdlIwHdmVyZGljdJRhaH2MB3BsYW5uZWSUdWgnfZRoKY+UKGh9aHqQaCtOdWJogU5og05ohE5ohk5oh2iJKYGUfZQoaAV9lChoC4wHcGVuZGluZ5Rojk51aCd9lGgpj5QoaI5oC5BoK051YnVoJ32UaCmPlChoZGhsaHBoHmhnaG5odGiDaIdocmhqaGZoY2iBaIRohpBoK051YmWMCGZhaWx1cmVzlF2UaE9dlIwRY2l0YXRpb25fZmFpbHVyZXOUXZSMC21vcmVfY2xhaW1zlF2UjBRtb3JlX2NsYWltX2xvY2F0aW9uc5RdlIwObW9yZV9jaXRhdGlvbnOUXZRohk6MBmNsYWltc5RdlChoAIwLUmV2aWV3Q2xhaW2Uk5QpgZR9lChoBX2UKIwFaW5kZXiUSwBoZIweVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulIwJcG9zaXRpb25zlF2UaACMCFBvc2l0aW9ulJOUKYGUfZQoaAV9lCholksAaJdLHmiYjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UdWgnfZRoKY+UKGiWaJdomJBoK051YmGMBnJlc3VsdJRoAIwMUmV2aWV3UmVzdWx0lJOUKYGUfZQoaAV9lChoZ4wFRmFsc2WUaB6MBGhpZ2iUaGqMDHZlcmlmaWNhdGlvbpSMCGlzX2lzc3VllIh1aCd9lGgpj5QoaB5oZ2hqaOGQaCtOdWKMCmFzc2Vzc21lbnSUaACMEFJldmlld0Fzc2Vzc21lbnSUk5QpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaGeMBUZhbHNllGgejARoaWdolGiDTowHZGlzc2VudJROaHBOjAplcnJvcl9jb2RllE6MEWlkZW50aWZpZWRfY2xhaW1zlF2UjARoaW50lE5ohE5ohk51aCd9lGgpj5QoaPFo7WhwaB5oC2hnaO9og2juaIRohpBoK051Ymh0aHYpgZR9lChoBX2UKGh6XZSMB3ZlcmRpY3SUYWh9jAdwbGFubmVklHVoJ32UaCmPlChofWh6kGgrTnVijAx2ZXJpZmljYXRpb26UaACMElJldmlld1ZlcmlmaWNhdGlvbpSTlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJSMDmNvbnRlbnRfc3RhdHVzlIwJYXZhaWxhYmxllGhsjAg2OGNhNGFhZpSMB3Rhc2tfaWSUjCA3Y2ZmMThkYTJkOTc5ZDYzNzBlNTRhMTYwYmUxMjFhZJRoZIweVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulGgRjAJlbpSMCnZpc2liaWxpdHmUjAdwcml2YXRllGgjjAhzdGFuZGFyZJSMBmRvbWFpbpSMAJSMCGVudGl0aWVzlF2UaGeMBUZhbHNllGgejARoaWdolIwKbGVuel9zY29yZZRLAmiBjCpGaW5kaW5nIGZvciBUaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UjBFleGVjdXRpdmVfc3VtbWFyeZSMKlN1bW1hcnkgZm9yIFRoZSBFaWZmZWwgVG93ZXIgaXMgaW4gQmVybGluLpRohIwlRml4ZWQ6IFRoZSBFaWZmZWwgVG93ZXIgaXMgaW4gQmVybGluLpSMCHdhcm5pbmdzlF2UjAJ3MZRhaA6MIDIwMjYtMTAtMDFUMDk6MTQ6MDAuMTIzNDU2KzAwOjAwlIwLbW9kaWZpZWRfYXSUTmhwjC1odHRwczovL2xlbnouaW8vYXBpL3YxL3ZlcmlmaWNhdGlvbnMvNjhjYTRhYWaUaHKMLWh0dHBzOi8vbGVuei5pby9jL3RoZS1lYXJ0aC1pcy1yb3VuZC02OGNhNGFhZpRohk51aCd9lGgpj5QoaGxocGoPAQAAaB5qHAEAAGoVAQAAaHJqCgEAAGgLag0BAABogWhkaCNoDmhnaIRqGAEAAGoGAQAAaBFqEwEAAGoDAQAAaIaQaCtOdWJoh2iJKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGiOXZRokSmBlH2UKGgFfZQoaJVLAGiWSxdol0sdaJiMBkJlcmxpbpRomowFUGFyaXOUdWgnfZRoKY+UKGiWaJVommiXaJiQaCtOdWJhdWgnfZRoKY+UKGiOaAuQaCtOdWJ1aCd9lGgpj5QoaGRo5Gh0aMxo/GiHaNhozpBoK051YmjIKYGUfZQoaAV9lChozEsBaGSMKFRoZSBFVSBBSSBBY3QgdG9vayBlZmZlY3QgaW4gTWFyY2ggMjAyNC6UaM5dlGjRKYGUfZQoaAV9lCholkstaJdLVWiYjChUaGUgRVUgQUkgQWN0IHRvb2sgZWZmZWN0IGluIE1hcmNoIDIwMjQulHVoJ32UaCmPlCholmiXaJiQaCtOdWJhaNho2imBlH2UKGgFfZQoaGeMBUZhbHNllGgejARoaWdolGhqjAphc3Nlc3NtZW50lGjhiHVoJ32UaCmPlChoHmhnaGpo4ZBoK051YmjkaOYpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaGeMBUZhbHNllGgejARoaWdolGiDTmjtTmhwTmjuTmjvXZRo8U5ohE5ohk51aCd9lGgpj5QoaPFo7WhwaB5oC2hnaO9og2juaIRohpBoK051Ymh0aHYpgZR9lChoBX2UKGh6XZSMB3ZlcmRpY3SUYWh9jAdwbGFubmVklHVoJ32UaCmPlChofWh6kGgrTnViaPxo/imBlH2UKGgFfZQoaAuMCnByb2Nlc3NpbmeUagMBAACMCWF2YWlsYWJsZZRobE5qBgEAAE5oZE5oEU5qCgEAAE5oI05qDQEAAE5qDwEAAF2UaGdOaB5OahMBAABOaIFOahUBAABOaIROahgBAABdlGgOTmocAQAATmhwTmhyTmiGTnVoJ32UaCmPlChobGhwag8BAABoHmocAQAAahUBAABocmoKAQAAaAtqDQEAAGiBaGRoI2gOaGdohGoYAQAAagYBAABoEWoTAQAAagMBAABohpBoK051YmiHaIkpgZR9lChoBX2UKGgLjAdwZW5kaW5nlGiOTnVoJ32UaCmPlChojmgLkGgrTnVidWgnfZRoKY+UKGhkaORodGjMaPxoh2jYaM6QaCtOdWJljAljaXRhdGlvbnOUXZR1aCd9lGgpj5QoaL9oumgQaAtoE2i9aFxoLGjDaFNoDmhPaMVoDWjBaBFoCWpmAQAAaEloB2iGkGgrTnViLg==", + "review__get_suggested_edits_issues_view.json": "gASVmgkAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjAZpc3N1ZXOUjAZzdGF0dXOUjAl2ZXJpZnlpbmeUjAdvdXRjb21llE6MCmNyZWF0ZWRfYXSUjBsyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NlqUjAxjb21wbGV0ZWRfYXSUTowIbGFuZ3VhZ2WUjAJlbpSMBnBvbGljeZRoAIwQRXNjYWxhdGlvblBvbGljeZSTlCmBlH2UKGgFfZQojAh2ZXJkaWN0c5RdlCiMBUZhbHNllIwMTW9zdGx5IEZhbHNllIwFTWl4ZWSUZYwKY29uZmlkZW5jZZRdlIwDbG93lGGMD21heF9hc3Nlc3NtZW50c5RLFIwRbWF4X3ZlcmlmaWNhdGlvbnOUSwWMBWRlcHRolIwIc3RhbmRhcmSUjA1tYXhfY2l0YXRpb25zlEsAjA1zdWdnZXN0X2VkaXRzlIh1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgZaCNoHmglaCZoImghkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAdzdW1tYXJ5lGgAjA1SZXZpZXdTdW1tYXJ5lJOUKYGUfZQoaAV9lCiMD2NsYWltc19zZWxlY3RlZJRLAowLY2xhaW1fbGltaXSUSxSME2NsYWltX2xpbWl0X3JlYWNoZWSUiYwPaW5wdXRfdHJ1bmNhdGVklImMC2Fzc2Vzc21lbnRzlGgAjBZSZXZpZXdBc3Nlc3NtZW50Q291bnRzlJOUKYGUfZQoaAV9lCiMCWNvbXBsZXRlZJRLAowGZmFpbGVklEsAdWgnfZRoKY+UKGg8aD2QaCtOdWKMDXZlcmlmaWNhdGlvbnOUaACMGFJldmlld1ZlcmlmaWNhdGlvbkNvdW50c5STlCmBlH2UKGgFfZQojAdwbGFubmVklEsCaDxLAWg9SwB1aCd9lGgpj5QoaDxoPWhGkGgrTnVijAZpc3N1ZXOUSwKMD2NpdGF0aW9uc19mb3VuZJROjBJjaXRhdGlvbnNfc2VsZWN0ZWSUTowOY2l0YXRpb25fbGltaXSUTowWY2l0YXRpb25fbGltaXRfcmVhY2hlZJROjA9jaXRhdGlvbl9jaGVja3OUTowPY2l0YXRpb25faXNzdWVzlEsAjBFjaXRhdGlvbnNfc2tpcHBlZJROdWgnfZRoKY+UKGgyaDZoNWhLaEBoUGhNaEloM2hMaE9oTmhKaDSQaCtOdWKMB2NyZWRpdHOUaACMDVJldmlld0NyZWRpdHOUk5QpgZR9lChoBX2UjAdjaGFyZ2VklEsMc2gnfZRoKY+UKGhZkGgrTnVijBJwb2xsX2FmdGVyX3NlY29uZHOUSw9oSV2UKGgAjAtSZXZpZXdJc3N1ZZSTlCmBlH2UKGgFfZQojAtjbGFpbV9pbmRleJRLAIwFY2xhaW2UjB5UaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UjA52ZXJpZmllZF9jbGFpbZROjAd2ZXJkaWN0lIwFRmFsc2WUaB6MBGhpZ2iUjAZzb3VyY2WUjAx2ZXJpZmljYXRpb26UjA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSME3ZlcmlmaWNhdGlvbl9zdGF0dXOUjAljb21wbGV0ZWSUjBB2ZXJpZmljYXRpb25fdXJslIwtaHR0cHM6Ly9sZW56LmlvL2FwaS92MS92ZXJpZmljYXRpb25zLzY4Y2E0YWFmlIwDdXJslIwtaHR0cHM6Ly9sZW56LmlvL2MvdGhlLWVhcnRoLWlzLXJvdW5kLTY4Y2E0YWFmlIwKZXNjYWxhdGlvbpRoAIwKRXNjYWxhdGlvbpSTlCmBlH2UKGgFfZQojA1tYXRjaGVkX3J1bGVzlF2UjAd2ZXJkaWN0lGGMC2Rpc3Bvc2l0aW9ulIwHcGxhbm5lZJR1aCd9lGgpj5QoaH1oepBoK051YowLa2V5X2ZpbmRpbmeUjCpGaW5kaW5nIGZvciBUaGUgRWlmZmVsIFRvd2VyIGlzIGluIEJlcmxpbi6UjAlyYXRpb25hbGWUTowRc3VnZ2VzdGVkX3Jld3JpdGWUjCVGaXhlZDogVGhlIEVpZmZlbCBUb3dlciBpcyBpbiBCZXJsaW4ulIwHZmFpbHVyZZROjA9zdWdnZXN0ZWRfZWRpdHOUaACMDlN1Z2dlc3RlZEVkaXRzlJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklIwFZWRpdHOUXZRoAIwNU3VnZ2VzdGVkRWRpdJSTlCmBlH2UKGgFfZQojAhwb3NpdGlvbpRLAIwFc3RhcnSUSxeMA2VuZJRLHYwEdGV4dJSMBkJlcmxpbpSMC3JlcGxhY2VtZW50lIwFUGFyaXOUdWgnfZRoKY+UKGiWaJVommiXaJiQaCtOdWJhdWgnfZRoKY+UKGiOaAuQaCtOdWJ1aCd9lGgpj5QoaGRobGhwaB5oZ2huaHRog2iHaHJoamhmaGNogWiEaIaQaCtOdWJoXymBlH2UKGgFfZQoaGNLAWhkjChUaGUgRVUgQUkgQWN0IHRvb2sgZWZmZWN0IGluIE1hcmNoIDIwMjQulGhmTmhnjAVGYWxzZZRoHowEaGlnaJRoaowKYXNzZXNzbWVudJRobE5obowKcHJvY2Vzc2luZ5RocE5ock5odGh2KYGUfZQoaAV9lChoel2UjAd2ZXJkaWN0lGFofYwHcGxhbm5lZJR1aCd9lGgpj5QoaH1oepBoK051YmiBTmiDTmiETmiGTmiHaIkpgZR9lChoBX2UKGgLjAdwZW5kaW5nlGiOTnVoJ32UaCmPlChojmgLkGgrTnVidWgnfZRoKY+UKGhkaGxocGgeaGdobmh0aINoh2hyaGpoZmhjaIFohGiGkGgrTnViZYwIZmFpbHVyZXOUXZRoT12UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUXZSMFG1vcmVfY2xhaW1fbG9jYXRpb25zlF2UjA5tb3JlX2NpdGF0aW9uc5RdlGiGTowGY2xhaW1zlF2UjAljaXRhdGlvbnOUXZR1aCd9lGgpj5QoaL9oumgQaAtoE2i9aFxoLGjDaFNoDmhPaA1owWgRaAloSWgHaIaQaCtOdWIu", + "review__get_url_review.json": "gASVKAgAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJY29tcGxldGVklIwHb3V0Y29tZZSMBWNsZWFulIwKY3JlYXRlZF9hdJSMGzIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2WpSMDGNvbXBsZXRlZF9hdJSMGzIwMjYtMTAtMDFUMTA6MDc6MDAuMTIzNDU2WpSMCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoG2glaCBoJ2goaCRoI5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwGMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwGMBmZhaWxlZJRLAHVoKX2UaCuPlChoPmg/kGgtTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAGg+SwBoP0sAdWgpfZRoK4+UKGg+aD9oSJBoLU51YowGaXNzdWVzlEsAjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lE6MFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUTowPY2l0YXRpb25fY2hlY2tzlE6MD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoKX2UaCuPlChoNGg4aDdoTWhCaFJoT2hLaDVoTmhRaFBoTGg2kGgtTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAXNoKX2UaCuPlChoW5BoLU51YowScG9sbF9hZnRlcl9zZWNvbmRzlE5oS12UjAhmYWlsdXJlc5RdlGhRXZSMEWNpdGF0aW9uX2ZhaWx1cmVzlF2UjAttb3JlX2NsYWltc5RdlIwUbW9yZV9jbGFpbV9sb2NhdGlvbnOUXZSMDm1vcmVfY2l0YXRpb25zlF2UjAdmYWlsdXJllE6MBmNsYWltc5RdlGgAjAtSZXZpZXdDbGFpbZSTlCmBlH2UKGgFfZQojAVpbmRleJRLAIwFY2xhaW2UjChUaGUgRVUgQUkgQWN0IHRvb2sgZWZmZWN0IGluIE1hcmNoIDIwMjQulIwJcG9zaXRpb25zlF2UaACMCFBvc2l0aW9ulJOUKYGUfZQoaAV9lCiMBXN0YXJ0lE6MA2VuZJROjAR0ZXh0lIwoVGhlIEVVIEFJIEFjdCB0b29rIGVmZmVjdCBpbiBNYXJjaCAyMDI0LpR1aCl9lGgrj5QoaH1ofmh/kGgtTnViYYwGcmVzdWx0lGgAjAxSZXZpZXdSZXN1bHSUk5QpgZR9lChoBX2UKIwHdmVyZGljdJSMBFRydWWUaCCMBGhpZ2iUjAZzb3VyY2WUjAphc3Nlc3NtZW50lIwIaXNfaXNzdWWUiXVoKX2UaCuPlChoIGiJaIxojpBoLU51YowKYXNzZXNzbWVudJRoAIwQUmV2aWV3QXNzZXNzbWVudJSTlCmBlH2UKGgFfZQoaAuMCWNvbXBsZXRlZJRoiYwEVHJ1ZZRoIIwEaGlnaJSMCXJhdGlvbmFsZZROjAdkaXNzZW50lE6MEHZlcmlmaWNhdGlvbl91cmyUTowKZXJyb3JfY29kZZROjBFpZGVudGlmaWVkX2NsYWltc5RdlIwEaGludJROjBFzdWdnZXN0ZWRfcmV3cml0ZZROaGtOdWgpfZRoK4+UKGigaJtonGggaAtoiWieaJponWihaGuQaC1OdWKMCmVzY2FsYXRpb26UaACMCkVzY2FsYXRpb26Uk5QpgZR9lChoBX2UKIwNbWF0Y2hlZF9ydWxlc5RdlIwLZGlzcG9zaXRpb26UjAxub3Rfc2VsZWN0ZWSUdWgpfZRoK4+UKGisaKqQaC1OdWKMDHZlcmlmaWNhdGlvbpROjA9zdWdnZXN0ZWRfZWRpdHOUTnVoKX2UaCuPlChodGiRaKRoc2iwaLFog2h2kGgtTnViYYwJY2l0YXRpb25zlF2UdWgpfZRoK4+UKGhlaGBoEWgLaBVoY2heaC5oaWhVaA9oUWhsaA1oZ2gTaAlotGhLaAdoa5BoLU51Yi4=", + "review__get_verifying.json": "gASVYgsAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKUmV2aWV3RnVsbJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBHZpZXeUjARmdWxslIwGc3RhdHVzlIwJdmVyaWZ5aW5nlIwHb3V0Y29tZZROjApjcmVhdGVkX2F0lIwbMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTZalIwMY29tcGxldGVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAZwb2xpY3mUaACMEEVzY2FsYXRpb25Qb2xpY3mUk5QpgZR9lChoBX2UKIwIdmVyZGljdHOUXZQojAVGYWxzZZSMDE1vc3RseSBGYWxzZZSMBU1peGVklGWMCmNvbmZpZGVuY2WUXZSMA2xvd5RhjA9tYXhfYXNzZXNzbWVudHOUSxSMEW1heF92ZXJpZmljYXRpb25zlEsFjAVkZXB0aJSMCHN0YW5kYXJklIwNbWF4X2NpdGF0aW9uc5RLAIwNc3VnZ2VzdF9lZGl0c5SJdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGWgjaB5oJWgmaCJoIZCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YowHc3VtbWFyeZRoAIwNUmV2aWV3U3VtbWFyeZSTlCmBlH2UKGgFfZQojA9jbGFpbXNfc2VsZWN0ZWSUSwKMC2NsYWltX2xpbWl0lEsUjBNjbGFpbV9saW1pdF9yZWFjaGVklImMD2lucHV0X3RydW5jYXRlZJSJjAthc3Nlc3NtZW50c5RoAIwWUmV2aWV3QXNzZXNzbWVudENvdW50c5STlCmBlH2UKGgFfZQojAljb21wbGV0ZWSUSwKMBmZhaWxlZJRLAHVoJ32UaCmPlChoPGg9kGgrTnVijA12ZXJpZmljYXRpb25zlGgAjBhSZXZpZXdWZXJpZmljYXRpb25Db3VudHOUk5QpgZR9lChoBX2UKIwHcGxhbm5lZJRLAWg8SwBoPUsAdWgnfZRoKY+UKGg8aD1oRpBoK051YowGaXNzdWVzlEsBjA9jaXRhdGlvbnNfZm91bmSUTowSY2l0YXRpb25zX3NlbGVjdGVklE6MDmNpdGF0aW9uX2xpbWl0lE6MFmNpdGF0aW9uX2xpbWl0X3JlYWNoZWSUTowPY2l0YXRpb25fY2hlY2tzlE6MD2NpdGF0aW9uX2lzc3Vlc5RLAIwRY2l0YXRpb25zX3NraXBwZWSUTnVoJ32UaCmPlChoMmg2aDVoS2hAaFBoTWhJaDNoTGhPaE5oSmg0kGgrTnVijAdjcmVkaXRzlGgAjA1SZXZpZXdDcmVkaXRzlJOUKYGUfZQoaAV9lIwHY2hhcmdlZJRLAnNoJ32UaCmPlChoWZBoK051YowScG9sbF9hZnRlcl9zZWNvbmRzlEsPaEldlGgAjAtSZXZpZXdJc3N1ZZSTlCmBlH2UKGgFfZQojAtjbGFpbV9pbmRleJRLAIwFY2xhaW2UjChUaGUgRVUgQUkgQWN0IHRvb2sgZWZmZWN0IGluIE1hcmNoIDIwMjQulIwOdmVyaWZpZWRfY2xhaW2UTowHdmVyZGljdJSMBUZhbHNllGgejARoaWdolIwGc291cmNllIwKYXNzZXNzbWVudJSMD3ZlcmlmaWNhdGlvbl9pZJROjBN2ZXJpZmljYXRpb25fc3RhdHVzlIwKcHJvY2Vzc2luZ5SMEHZlcmlmaWNhdGlvbl91cmyUTowDdXJslE6MCmVzY2FsYXRpb26UaACMCkVzY2FsYXRpb26Uk5QpgZR9lChoBX2UKIwNbWF0Y2hlZF9ydWxlc5RdlIwHdmVyZGljdJRhjAtkaXNwb3NpdGlvbpSMB3BsYW5uZWSUdWgnfZRoKY+UKGh6aHeQaCtOdWKMC2tleV9maW5kaW5nlE6MCXJhdGlvbmFsZZROjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdmYWlsdXJllE6MD3N1Z2dlc3RlZF9lZGl0c5ROdWgnfZRoKY+UKGhkaGxob2geaGdobWhxaH9ogmhwaGpoZmhjaH5ogGiBkGgrTnViYYwIZmFpbHVyZXOUXZRoT12UjBFjaXRhdGlvbl9mYWlsdXJlc5RdlIwLbW9yZV9jbGFpbXOUXZSMFG1vcmVfY2xhaW1fbG9jYXRpb25zlF2UjA5tb3JlX2NpdGF0aW9uc5RdlGiBTowGY2xhaW1zlF2UKGgAjAtSZXZpZXdDbGFpbZSTlCmBlH2UKGgFfZQojAVpbmRleJRLAGhkjChUaGUgRVUgQUkgQWN0IHRvb2sgZWZmZWN0IGluIE1hcmNoIDIwMjQulIwJcG9zaXRpb25zlE6MBnJlc3VsdJRoAIwMUmV2aWV3UmVzdWx0lJOUKYGUfZQoaAV9lChoZ4wFRmFsc2WUaB6MBGhpZ2iUaGqMCmFzc2Vzc21lbnSUjAhpc19pc3N1ZZSIdWgnfZRoKY+UKGgeaGdoamijkGgrTnVijAphc3Nlc3NtZW50lGgAjBBSZXZpZXdBc3Nlc3NtZW50lJOUKYGUfZQoaAV9lChoC4wJY29tcGxldGVklGhnjAVGYWxzZZRoHowEaGlnaJRof06MB2Rpc3NlbnSUTmhvTowKZXJyb3JfY29kZZROjBFpZGVudGlmaWVkX2NsYWltc5RdlIwEaGludJROaIBOaIFOdWgnfZRoKY+UKGizaK9ob2geaAtoZ2ixaH9osGiAaIGQaCtOdWJocWhzKYGUfZQoaAV9lChod12UjAd2ZXJkaWN0lGFoeowHcGxhbm5lZJR1aCd9lGgpj5QoaHpod5BoK051YowMdmVyaWZpY2F0aW9ulGgAjBJSZXZpZXdWZXJpZmljYXRpb26Uk5QpgZR9lChoBX2UKGgLjApwcm9jZXNzaW5nlIwOY29udGVudF9zdGF0dXOUjAlhdmFpbGFibGWUaGxOjAd0YXNrX2lklE5oZE5oEU6MCnZpc2liaWxpdHmUTmgjTowGZG9tYWlulE6MCGVudGl0aWVzlF2UaGdOaB5OjApsZW56X3Njb3JllE5ofk6MEWV4ZWN1dGl2ZV9zdW1tYXJ5lE5ogE6MCHdhcm5pbmdzlF2UaA5OjAttb2RpZmllZF9hdJROaG9OaHBOaIFOdWgnfZRoKY+UKGhsaG9oymgeaNBozWhwaMhoC2jJaH5oZGgjaA5oZ2iAaM5ox2gRaMxoxWiBkGgrTnViaIJOdWgnfZRoKY+UKGhkaKZocWiXaL5ogmiaaJmQaCtOdWJokymBlH2UKGgFfZQoaJdLAWhkjCJXYXRlciBib2lscyBhdCAxMDAgQyBhdCBzZWEgbGV2ZWwulGiZTmiaaJwpgZR9lChoBX2UKGhnjARUcnVllGgejARoaWdolGhqjAphc3Nlc3NtZW50lGijiXVoJ32UaCmPlChoHmhnaGpoo5BoK051YmimaKgpgZR9lChoBX2UKGgLjAljb21wbGV0ZWSUaGeMBFRydWWUaB6MBGhpZ2iUaH9OaK9OaG9OaLBOaLFdlGizTmiATmiBTnVoJ32UaCmPlChos2ivaG9oHmgLaGdosWh/aLBogGiBkGgrTnViaHFocymBlH2UKGgFfZQoaHddlGh6jAxub3Rfc2VsZWN0ZWSUdWgnfZRoKY+UKGh6aHeQaCtOdWJovk5ogk51aCd9lGgpj5QoaGRopmhxaJdovmiCaJpomZBoK051YmWMCWNpdGF0aW9uc5RdlHVoJ32UaCmPlChoimiFaBBoC2gTaIhoXGgsaI5oU2gOaE9okGgNaIxoEWgJaPNoSWgHaIGQaCtOdWIu", + "review__idempotent_replay_202.json": "gASVtQAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwNUmV2aWV3U3RhcnRlZJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBnN0YXR1c5SMBnF1ZXVlZJR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgJaAeQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWIu", + "review__receipt_202.json": "gASVtQAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwNUmV2aWV3U3RhcnRlZJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBnN0YXR1c5SMBnF1ZXVlZJR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgJaAeQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWIu", + "review__receipt_202_empty_webhook_url.json": "gASVtQAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwNUmV2aWV3U3RhcnRlZJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBnN0YXR1c5SMBnF1ZXVlZJR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgJaAeQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWIu", + "review__receipt_202_webhook_url.json": "gASVtQAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwNUmV2aWV3U3RhcnRlZJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBnN0YXR1c5SMBnF1ZXVlZJR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgJaAeQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWIu", + "review__replay_later_202.json": "gASVtQAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwNUmV2aWV3U3RhcnRlZJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAlyZXZpZXdfaWSUjAhkNmIyYmQ3MpSMBnN0YXR1c5SMBnF1ZXVlZJR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgJaAeQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWIu", + "verify__batch_202.json": "gASVpAEAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwNQmF0Y2hBY2NlcHRlZJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAhiYXRjaF9pZJSMEDdlYTljZGJkNDA2NGUzY2aUjAVpdGVtc5RdlChoAIwMVGFza0FjY2VwdGVklJOUKYGUfZQoaAV9lCiMB3Rhc2tfaWSUjCA3Y2ZmMThkYTJkOTc5ZDYzNzBlNTRhMTYwYmUxMjFhZJSMCmNsYWltX3RleHSUjBNUaGUgRWFydGggaXMgcm91bmQulHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBJoEJCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmgMKYGUfZQoaAV9lChoEIwgMGI5MmI0NDNlYjY5YjljNzE0MzRmZGM2NGYyY2E4YmWUaBKMIVdhdGVyIGJvaWxzIGF0IDEwMEMgYXQgc2VhIGxldmVsLpR1aBR9lGgWj5QoaBJoEJBoGE51YmV1aBR9lGgWj5QoaAdoCZBoGE51Yi4=", + "verify__batch_partial_202.json": "gASVPgEAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwNQmF0Y2hBY2NlcHRlZJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAhiYXRjaF9pZJSMEDdlYTljZGJkNDA2NGUzY2aUjAVpdGVtc5RdlGgAjAxUYXNrQWNjZXB0ZWSUk5QpgZR9lChoBX2UKIwHdGFza19pZJSMIDdjZmYxOGRhMmQ5NzlkNjM3MGU1NGExNjBiZTEyMWFklIwKY2xhaW1fdGV4dJSMDEZpcnN0IGNsYWltLpR1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgSaBCQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWJhdWgUfZSMB3BhcnRpYWyUiHNoFo+UKGgHaBpoCZBoGE51Yi4=", + "verify__delete_200.json": "gASVrAAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVGFza0FjY2VwdGVklJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMB3Rhc2tfaWSUjACUjApjbGFpbV90ZXh0lGgIdYwSX19weWRhbnRpY19leHRyYV9flH2UjAJva5SIc4wXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaAyQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWIu", + "verify__idempotency_key_replay.json": "gASV/AAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVGFza0FjY2VwdGVklJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMB3Rhc2tfaWSUjCA3Y2ZmMThkYTJkOTc5ZDYzNzBlNTRhMTYwYmUxMjFhZJSMCmNsYWltX3RleHSUjACUdYwSX19weWRhbnRpY19leHRyYV9flH2UKIwGc3RhdHVzlIwGcXVldWVklIwIY2hhaW5faWSUjBA5OWEwYTljYTg5ZTFlNzJjlHWMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgPaA1oB5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51Yi4=", + "verify__implicit_dedup_200.json": "gASV2wAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVGFza0FjY2VwdGVklJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMB3Rhc2tfaWSUjCA3Y2ZmMThkYTJkOTc5ZDYzNzBlNTRhMTYwYmUxMjFhZJSMCmNsYWltX3RleHSUjACUdYwSX19weWRhbnRpY19leHRyYV9flH2UjAZzdGF0dXOUjAZxdWV1ZWSUc4wXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaA1oB5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51Yi4=", + "verify__implicit_repeat_replay.json": "gASV/AAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVGFza0FjY2VwdGVklJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMB3Rhc2tfaWSUjCA3Y2ZmMThkYTJkOTc5ZDYzNzBlNTRhMTYwYmUxMjFhZJSMCmNsYWltX3RleHSUjACUdYwSX19weWRhbnRpY19leHRyYV9flH2UKIwGc3RhdHVzlIwGcXVldWVklIwIY2hhaW5faWSUjBA5OWEwYTljYTg5ZTFlNzJjlHWMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgPaA1oB5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51Yi4=", + "verify__list_200.json": "gASVcQMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwQVmVyaWZpY2F0aW9uTGlzdJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAVpdGVtc5RdlChoAIwUVmVyaWZpY2F0aW9uTGlzdEl0ZW2Uk5QpgZR9lChoBX2UKIwPdmVyaWZpY2F0aW9uX2lklIwINjhjYTRhYWaUjAVjbGFpbZSME1RoZSBFYXJ0aCBpcyByb3VuZC6UjAZkb21haW6UjAdTY2llbmNllIwIZW50aXRpZXOUXZSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjBFzdWdnZXN0ZWRfcmV3cml0ZZROjApjcmVhdGVkX2F0lIwgMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTYrMDA6MDCUjAttb2RpZmllZF9hdJROjAhsYW5ndWFnZZSMAmVulHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBBoDmgUaBhoIGgSaBZoI2giaB1oGmgbaB+QjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWJoCimBlH2UKGgFfZQoaA6MCDRkNDRkZmFmlGgQjBNUaGUgRWFydGggaXMgcm91bmQulGgSjAdTY2llbmNllGgUXZRoFowEVHJ1ZZRoGIwEaGlnaJRoGksJaBuMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UaB2MFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UaB9OaCCMIDIwMjYtMTAtMDFUMDk6MTQ6MDAuMTIzNDU2KzAwOjAwlGgiTmgjjAJlbpR1aCV9lGgnj5QoaBBoDmgUaBhoIGgSaBZoI2giaB1oGmgbaB+QaClOdWJljAV0b3RhbJRLAowEcGFnZZRLAYwJcGFnZV9zaXpllEsUdWglfZRoJ4+UKGg6aDtoOWgHkGgpTnViLg==", + "verify__list_200_modified_at_crosses_midnight_by_minutes.json": "gASVkAIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwQVmVyaWZpY2F0aW9uTGlzdJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAVpdGVtc5RdlGgAjBRWZXJpZmljYXRpb25MaXN0SXRlbZSTlCmBlH2UKGgFfZQojA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSMBWNsYWltlIwTVGhlIEVhcnRoIGlzIHJvdW5kLpSMBmRvbWFpbpSMB1NjaWVuY2WUjAhlbnRpdGllc5RdlIwHdmVyZGljdJSMBFRydWWUjApjb25maWRlbmNllIwEaGlnaJSMCmxlbnpfc2NvcmWUSwmMC2tleV9maW5kaW5nlIwuVGhlIEVhcnRoIGlzIGFwcHJveGltYXRlbHkgc3BoZXJpY2FsIGluIHNoYXBlLpSMEWV4ZWN1dGl2ZV9zdW1tYXJ5lIwWVGhlIGNsYWltIGlzIHZlcmlmaWVkLpSMEXN1Z2dlc3RlZF9yZXdyaXRllE6MCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDIzOjU1OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lIwgMjAyNi0xMC0wMlQwMDowMzowMC4xMjM0NTYrMDA6MDCUjAhsYW5ndWFnZZSMAmVulHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBBoDmgUaBhoIGgSaBZoJGgiaB1oGmgbaB+QjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWJhjAV0b3RhbJRLAYwEcGFnZZRLAYwJcGFnZV9zaXpllEsUdWgmfZRoKI+UKGgsaC1oK2gHkGgqTnViLg==", + "verify__list_200_modified_at_same_day_hours_apart.json": "gASVbgIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwQVmVyaWZpY2F0aW9uTGlzdJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAVpdGVtc5RdlGgAjBRWZXJpZmljYXRpb25MaXN0SXRlbZSTlCmBlH2UKGgFfZQojA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSMBWNsYWltlIwTVGhlIEVhcnRoIGlzIHJvdW5kLpSMBmRvbWFpbpSMB1NjaWVuY2WUjAhlbnRpdGllc5RdlIwHdmVyZGljdJSMBFRydWWUjApjb25maWRlbmNllIwEaGlnaJSMCmxlbnpfc2NvcmWUSwmMC2tleV9maW5kaW5nlIwuVGhlIEVhcnRoIGlzIGFwcHJveGltYXRlbHkgc3BoZXJpY2FsIGluIHNoYXBlLpSMEWV4ZWN1dGl2ZV9zdW1tYXJ5lIwWVGhlIGNsYWltIGlzIHZlcmlmaWVkLpSMEXN1Z2dlc3RlZF9yZXdyaXRllE6MCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA4OjAwOjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoEGgOaBRoGGggaBJoFmgjaCJoHWgaaBtoH5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMBXRvdGFslEsBjARwYWdllEsBjAlwYWdlX3NpemWUSxR1aCV9lGgnj5QoaCtoLGgqaAeQaClOdWIu", + "verify__list_clamped_200.json": "gASVvgAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwQVmVyaWZpY2F0aW9uTGlzdJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAVpdGVtc5RdlIwFdG90YWyUSwCMBHBhZ2WUSwGMCXBhZ2Vfc2l6ZZRLZHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaApoC2gJaAeQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWIu", + "verify__list_empty_200.json": "gASVvgAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwQVmVyaWZpY2F0aW9uTGlzdJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAVpdGVtc5RdlIwFdG90YWyUSwCMBHBhZ2WUSwGMCXBhZ2Vfc2l6ZZRLFHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaApoC2gJaAeQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWIu", + "verify__list_page2_200.json": "gASVbgIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwQVmVyaWZpY2F0aW9uTGlzdJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAVpdGVtc5RdlGgAjBRWZXJpZmljYXRpb25MaXN0SXRlbZSTlCmBlH2UKGgFfZQojA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSMBWNsYWltlIwTVGhlIEVhcnRoIGlzIHJvdW5kLpSMBmRvbWFpbpSMB1NjaWVuY2WUjAhlbnRpdGllc5RdlIwHdmVyZGljdJSMBFRydWWUjApjb25maWRlbmNllIwEaGlnaJSMCmxlbnpfc2NvcmWUSwmMC2tleV9maW5kaW5nlIwuVGhlIEVhcnRoIGlzIGFwcHJveGltYXRlbHkgc3BoZXJpY2FsIGluIHNoYXBlLpSMEWV4ZWN1dGl2ZV9zdW1tYXJ5lIwWVGhlIGNsYWltIGlzIHZlcmlmaWVkLpSMEXN1Z2dlc3RlZF9yZXdyaXRllE6MCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoEGgOaBRoGGggaBJoFmgjaCJoHWgaaBtoH5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMBXRvdGFslEsDjARwYWdllEsCjAlwYWdlX3NpemWUSwJ1aCV9lGgnj5QoaCtoLGgqaAeQaClOdWIu", + "verify__replay_later_202.json": "gASV/AAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVGFza0FjY2VwdGVklJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMB3Rhc2tfaWSUjCA3Y2ZmMThkYTJkOTc5ZDYzNzBlNTRhMTYwYmUxMjFhZJSMCmNsYWltX3RleHSUjACUdYwSX19weWRhbnRpY19leHRyYV9flH2UKIwGc3RhdHVzlIwGcXVldWVklIwIY2hhaW5faWSUjBA5OWEwYTljYTg5ZTFlNzJjlHWMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgPaA1oB5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51Yi4=", + "verify__select_202.json": "gASVpAEAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwNQmF0Y2hBY2NlcHRlZJSTlCmBlH2UKIwIX19kaWN0X1+UfZQojAhiYXRjaF9pZJSMEDdlYTljZGJkNDA2NGUzY2aUjAVpdGVtc5RdlChoAIwMVGFza0FjY2VwdGVklJOUKYGUfZQoaAV9lCiMB3Rhc2tfaWSUjCA3Y2ZmMThkYTJkOTc5ZDYzNzBlNTRhMTYwYmUxMjFhZJSMCmNsYWltX3RleHSUjBNUaGUgRWFydGggaXMgcm91bmQulHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBJoEJCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmgMKYGUfZQoaAV9lChoEIwgMGI5MmI0NDNlYjY5YjljNzE0MzRmZGM2NGYyY2E4YmWUaBKMIVdhdGVyIGJvaWxzIGF0IDEwMEMgYXQgc2VhIGxldmVsLpR1aBR9lGgWj5QoaBJoEJBoGE51YmV1aBR9lGgWj5QoaAdoCZBoGE51Yi4=", + "verify__status_cancelled_after_a_while.json": "gASVNgIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAZmYWlsZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUTowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUjApDYW5jZWxsZWQulIwOZmFpbHVyZV9yZWFzb26UjAljYW5jZWxsZWSUjA5mYWlsdXJlX2RldGFpbJRoDIwNZmFpbHVyZV9jbGFzc5SMCWNhbmNlbGxlZJSMCXJldHJ5YWJsZZSJjAhkb2NzX3VybJSMJWh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyNjYW5jZWxsZWSUdWgZfZRoG4+UKGgJaAdoJ2gtaCpoLGglkGgdTnViLg==", + "verify__status_completed.json": "gASV5wkAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAljb21wbGV0ZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUaACMDFZlcmlmaWNhdGlvbpSTlCmBlH2UKGgFfZQojA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSMBWNsYWltlIwTVGhlIEVhcnRoIGlzIHJvdW5kLpSMCnZpc2liaWxpdHmUjAdwcml2YXRllIwFZGVwdGiUjAhzdGFuZGFyZJSMBmRvbWFpbpSMB1NjaWVuY2WUjAhlbnRpdGllc5RdlGgAjAlFbnRpdHlSZWaUk5QpgZR9lChoBX2UKIwEbmFtZZSMBUVhcnRolIwDcWlklE51aBl9lGgbj5QoaDVoN5BoHU51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoGX2UaBuPlChoUGhYaFRoUmhWkGgdTnViaEwpgZR9lChoBX2UKGhQjANFU0GUaFKMEEVhcnRoIGZyb20gc3BhY2WUaFSMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaFaMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaFiMCjIwMjUtMDEtMTaUdWgZfZRoG4+UKGhQaFhoVGhSaFaQaB1OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoRV2UdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJocSmBlH2UKGgFfZQoaHWMClJldmlld2VyIEKUaHeMB1NvdXJjZXOUaHlHQCIAAAAAAABoeowXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaEVdlIwNd2VhayBzb3VyY2UgQZRhdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoGX2UaBuPlChokWiTaI+QaB1OdWKMCmRlYmF0ZV9jb26UaIspgZR9lChoBX2UKGiPjAdTa2VwdGljlGiRjCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGiTjCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBl9lGgbj5QoaJFok2iPkGgdTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgZfZRoG4+UKGhuaJdobGigaImQaB1OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAhjb3ZlcmFnZZRoAIwIQ292ZXJhZ2WUk5QpgZR9lChoBX2UKGgHjAl1bmNvdmVyZWSUjAdyZWFzb25zlF2UjARwbGFulGGMDmNlcnRpZmljYXRlX2lklE6MD2NlcnRpZmljYXRlX3VybJROjAVhc19vZpROjAhjdXJyZW5jeZSMA0VVUpSMA2NhcJRNECeMCWFnZ3JlZ2F0ZZRKIKEHAIwNdGVybXNfdmVyc2lvbpSMAnYxlHVoGX2UaBuPlChouWi0aLhotWgHaLZoumizaLCQaB1OdWJ1aBl9lGgbj5QoaCRoLmg+aKZoQ2goaCxoQWgmaCpopGg8aDpoSGhFaKdoqWhJaGZoQJBoHU51YowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUaAyMDmZhaWx1cmVfcmVhc29ulGgMjA5mYWlsdXJlX2RldGFpbJRoDIwNZmFpbHVyZV9jbGFzc5RoDIwJcmV0cnlhYmxllE6MCGRvY3NfdXJslGgMdWgZfZRoG4+UKGgeaAdoCZBoHU51Yi4=", + "verify__status_completed_after_a_while.json": "gASV5wkAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAljb21wbGV0ZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUaACMDFZlcmlmaWNhdGlvbpSTlCmBlH2UKGgFfZQojA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSMBWNsYWltlIwTVGhlIEVhcnRoIGlzIHJvdW5kLpSMCnZpc2liaWxpdHmUjAdwcml2YXRllIwFZGVwdGiUjAhzdGFuZGFyZJSMBmRvbWFpbpSMB1NjaWVuY2WUjAhlbnRpdGllc5RdlGgAjAlFbnRpdHlSZWaUk5QpgZR9lChoBX2UKIwEbmFtZZSMBUVhcnRolIwDcWlklE51aBl9lGgbj5QoaDVoN5BoHU51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoGX2UaBuPlChoUGhYaFRoUmhWkGgdTnViaEwpgZR9lChoBX2UKGhQjANFU0GUaFKMEEVhcnRoIGZyb20gc3BhY2WUaFSMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaFaMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaFiMCjIwMjUtMDEtMTaUdWgZfZRoG4+UKGhQaFhoVGhSaFaQaB1OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoRV2UdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJocSmBlH2UKGgFfZQoaHWMClJldmlld2VyIEKUaHeMB1NvdXJjZXOUaHlHQCIAAAAAAABoeowXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaEVdlIwNd2VhayBzb3VyY2UgQZRhdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoGX2UaBuPlChokWiTaI+QaB1OdWKMCmRlYmF0ZV9jb26UaIspgZR9lChoBX2UKGiPjAdTa2VwdGljlGiRjCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGiTjCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBl9lGgbj5QoaJFok2iPkGgdTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgZfZRoG4+UKGhuaJdobGigaImQaB1OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAhjb3ZlcmFnZZRoAIwIQ292ZXJhZ2WUk5QpgZR9lChoBX2UKGgHjAl1bmNvdmVyZWSUjAdyZWFzb25zlF2UjARwbGFulGGMDmNlcnRpZmljYXRlX2lklE6MD2NlcnRpZmljYXRlX3VybJROjAVhc19vZpROjAhjdXJyZW5jeZSMA0VVUpSMA2NhcJRNECeMCWFnZ3JlZ2F0ZZRKIKEHAIwNdGVybXNfdmVyc2lvbpSMAnYxlHVoGX2UaBuPlChouWi0aLhotWgHaLZoumizaLCQaB1OdWJ1aBl9lGgbj5QoaCRoLmg+aKZoQ2goaCxoQWgmaCpopGg8aDpoSGhFaKdoqWhJaGZoQJBoHU51YowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUaAyMDmZhaWx1cmVfcmVhc29ulGgMjA5mYWlsdXJlX2RldGFpbJRoDIwNZmFpbHVyZV9jbGFzc5RoDIwJcmV0cnlhYmxllE6MCGRvY3NfdXJslGgMdWgZfZRoG4+UKGgeaAdoCZBoHU51Yi4=", + "verify__status_completed_after_a_while_modified_at_crosses_midnight_by_minutes.json": "gASVCQoAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAljb21wbGV0ZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUaACMDFZlcmlmaWNhdGlvbpSTlCmBlH2UKGgFfZQojA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSMBWNsYWltlIwTVGhlIEVhcnRoIGlzIHJvdW5kLpSMCnZpc2liaWxpdHmUjAdwcml2YXRllIwFZGVwdGiUjAhzdGFuZGFyZJSMBmRvbWFpbpSMB1NjaWVuY2WUjAhlbnRpdGllc5RdlGgAjAlFbnRpdHlSZWaUk5QpgZR9lChoBX2UKIwEbmFtZZSMBUVhcnRolIwDcWlklE51aBl9lGgbj5QoaDVoN5BoHU51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoGX2UaBuPlChoUGhYaFRoUmhWkGgdTnViaEwpgZR9lChoBX2UKGhQjANFU0GUaFKMEEVhcnRoIGZyb20gc3BhY2WUaFSMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaFaMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaFiMCjIwMjUtMDEtMTaUdWgZfZRoG4+UKGhQaFhoVGhSaFaQaB1OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoRV2UdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJocSmBlH2UKGgFfZQoaHWMClJldmlld2VyIEKUaHeMB1NvdXJjZXOUaHlHQCIAAAAAAABoeowXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaEVdlIwNd2VhayBzb3VyY2UgQZRhdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoGX2UaBuPlChokWiTaI+QaB1OdWKMCmRlYmF0ZV9jb26UaIspgZR9lChoBX2UKGiPjAdTa2VwdGljlGiRjCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGiTjCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBl9lGgbj5QoaJFok2iPkGgdTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgZfZRoG4+UKGhuaJdobGigaImQaB1OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDIzOjU1OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lIwgMjAyNi0xMC0wMlQwMDowMzowMC4xMjM0NTYrMDA6MDCUjAhsYW5ndWFnZZSMAmVulIwIY292ZXJhZ2WUaACMCENvdmVyYWdllJOUKYGUfZQoaAV9lChoB4wJdW5jb3ZlcmVklIwHcmVhc29uc5RdlIwEcGxhbpRhjA5jZXJ0aWZpY2F0ZV9pZJROjA9jZXJ0aWZpY2F0ZV91cmyUTowFYXNfb2aUTowIY3VycmVuY3mUjANFVVKUjANjYXCUTRAnjAlhZ2dyZWdhdGWUSiChBwCMDXRlcm1zX3ZlcnNpb26UjAJ2MZR1aBl9lGgbj5QoaLpotWi5aLZoB2i3aLtotGixkGgdTnVidWgZfZRoG4+UKGgkaC5oPmimaENoKGgsaEFoJmgqaKRoPGg6aEhoRWioaKpoSWhmaECQaB1OdWKMBmNsYWltc5RdlIwKY2FuZGlkYXRlc5RdlIwOc2ltaWxhcl9jbGFpbXOUXZSMBWVycm9ylGgMjA5mYWlsdXJlX3JlYXNvbpRoDIwOZmFpbHVyZV9kZXRhaWyUaAyMDWZhaWx1cmVfY2xhc3OUaAyMCXJldHJ5YWJsZZROjAhkb2NzX3VybJRoDHVoGX2UaBuPlChoHmgHaAmQaB1OdWIu", + "verify__status_completed_after_a_while_modified_at_same_day_hours_apart.json": "gASV5wkAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAljb21wbGV0ZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUaACMDFZlcmlmaWNhdGlvbpSTlCmBlH2UKGgFfZQojA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSMBWNsYWltlIwTVGhlIEVhcnRoIGlzIHJvdW5kLpSMCnZpc2liaWxpdHmUjAdwcml2YXRllIwFZGVwdGiUjAhzdGFuZGFyZJSMBmRvbWFpbpSMB1NjaWVuY2WUjAhlbnRpdGllc5RdlGgAjAlFbnRpdHlSZWaUk5QpgZR9lChoBX2UKIwEbmFtZZSMBUVhcnRolIwDcWlklE51aBl9lGgbj5QoaDVoN5BoHU51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoGX2UaBuPlChoUGhYaFRoUmhWkGgdTnViaEwpgZR9lChoBX2UKGhQjANFU0GUaFKMEEVhcnRoIGZyb20gc3BhY2WUaFSMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaFaMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaFiMCjIwMjUtMDEtMTaUdWgZfZRoG4+UKGhQaFhoVGhSaFaQaB1OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoRV2UdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJocSmBlH2UKGgFfZQoaHWMClJldmlld2VyIEKUaHeMB1NvdXJjZXOUaHlHQCIAAAAAAABoeowXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaEVdlIwNd2VhayBzb3VyY2UgQZRhdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoGX2UaBuPlChokWiTaI+QaB1OdWKMCmRlYmF0ZV9jb26UaIspgZR9lChoBX2UKGiPjAdTa2VwdGljlGiRjCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGiTjCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBl9lGgbj5QoaJFok2iPkGgdTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgZfZRoG4+UKGhuaJdobGigaImQaB1OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA4OjAwOjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAhjb3ZlcmFnZZRoAIwIQ292ZXJhZ2WUk5QpgZR9lChoBX2UKGgHjAl1bmNvdmVyZWSUjAdyZWFzb25zlF2UjARwbGFulGGMDmNlcnRpZmljYXRlX2lklE6MD2NlcnRpZmljYXRlX3VybJROjAVhc19vZpROjAhjdXJyZW5jeZSMA0VVUpSMA2NhcJRNECeMCWFnZ3JlZ2F0ZZRKIKEHAIwNdGVybXNfdmVyc2lvbpSMAnYxlHVoGX2UaBuPlChouWi0aLhotWgHaLZoumizaLCQaB1OdWJ1aBl9lGgbj5QoaCRoLmg+aKZoQ2goaCxoQWgmaCpopGg8aDpoSGhFaKdoqWhJaGZoQJBoHU51YowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUaAyMDmZhaWx1cmVfcmVhc29ulGgMjA5mYWlsdXJlX2RldGFpbJRoDIwNZmFpbHVyZV9jbGFzc5RoDIwJcmV0cnlhYmxllE6MCGRvY3NfdXJslGgMdWgZfZRoG4+UKGgeaAdoCZBoHU51Yi4=", + "verify__status_completed_modified_at_crosses_midnight_by_minutes.json": "gASVCQoAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAljb21wbGV0ZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUaACMDFZlcmlmaWNhdGlvbpSTlCmBlH2UKGgFfZQojA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSMBWNsYWltlIwTVGhlIEVhcnRoIGlzIHJvdW5kLpSMCnZpc2liaWxpdHmUjAdwcml2YXRllIwFZGVwdGiUjAhzdGFuZGFyZJSMBmRvbWFpbpSMB1NjaWVuY2WUjAhlbnRpdGllc5RdlGgAjAlFbnRpdHlSZWaUk5QpgZR9lChoBX2UKIwEbmFtZZSMBUVhcnRolIwDcWlklE51aBl9lGgbj5QoaDVoN5BoHU51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoGX2UaBuPlChoUGhYaFRoUmhWkGgdTnViaEwpgZR9lChoBX2UKGhQjANFU0GUaFKMEEVhcnRoIGZyb20gc3BhY2WUaFSMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaFaMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaFiMCjIwMjUtMDEtMTaUdWgZfZRoG4+UKGhQaFhoVGhSaFaQaB1OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoRV2UdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJocSmBlH2UKGgFfZQoaHWMClJldmlld2VyIEKUaHeMB1NvdXJjZXOUaHlHQCIAAAAAAABoeowXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaEVdlIwNd2VhayBzb3VyY2UgQZRhdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoGX2UaBuPlChokWiTaI+QaB1OdWKMCmRlYmF0ZV9jb26UaIspgZR9lChoBX2UKGiPjAdTa2VwdGljlGiRjCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGiTjCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBl9lGgbj5QoaJFok2iPkGgdTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgZfZRoG4+UKGhuaJdobGigaImQaB1OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDIzOjU1OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lIwgMjAyNi0xMC0wMlQwMDowMzowMC4xMjM0NTYrMDA6MDCUjAhsYW5ndWFnZZSMAmVulIwIY292ZXJhZ2WUaACMCENvdmVyYWdllJOUKYGUfZQoaAV9lChoB4wJdW5jb3ZlcmVklIwHcmVhc29uc5RdlIwEcGxhbpRhjA5jZXJ0aWZpY2F0ZV9pZJROjA9jZXJ0aWZpY2F0ZV91cmyUTowFYXNfb2aUTowIY3VycmVuY3mUjANFVVKUjANjYXCUTRAnjAlhZ2dyZWdhdGWUSiChBwCMDXRlcm1zX3ZlcnNpb26UjAJ2MZR1aBl9lGgbj5QoaLpotWi5aLZoB2i3aLtotGixkGgdTnVidWgZfZRoG4+UKGgkaC5oPmimaENoKGgsaEFoJmgqaKRoPGg6aEhoRWioaKpoSWhmaECQaB1OdWKMBmNsYWltc5RdlIwKY2FuZGlkYXRlc5RdlIwOc2ltaWxhcl9jbGFpbXOUXZSMBWVycm9ylGgMjA5mYWlsdXJlX3JlYXNvbpRoDIwOZmFpbHVyZV9kZXRhaWyUaAyMDWZhaWx1cmVfY2xhc3OUaAyMCXJldHJ5YWJsZZROjAhkb2NzX3VybJRoDHVoGX2UaBuPlChoHmgHaAmQaB1OdWIu", + "verify__status_completed_modified_at_same_day_hours_apart.json": "gASV5wkAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAljb21wbGV0ZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUaACMDFZlcmlmaWNhdGlvbpSTlCmBlH2UKGgFfZQojA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSMBWNsYWltlIwTVGhlIEVhcnRoIGlzIHJvdW5kLpSMCnZpc2liaWxpdHmUjAdwcml2YXRllIwFZGVwdGiUjAhzdGFuZGFyZJSMBmRvbWFpbpSMB1NjaWVuY2WUjAhlbnRpdGllc5RdlGgAjAlFbnRpdHlSZWaUk5QpgZR9lChoBX2UKIwEbmFtZZSMBUVhcnRolIwDcWlklE51aBl9lGgbj5QoaDVoN5BoHU51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoGX2UaBuPlChoUGhYaFRoUmhWkGgdTnViaEwpgZR9lChoBX2UKGhQjANFU0GUaFKMEEVhcnRoIGZyb20gc3BhY2WUaFSMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaFaMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaFiMCjIwMjUtMDEtMTaUdWgZfZRoG4+UKGhQaFhoVGhSaFaQaB1OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoRV2UdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJocSmBlH2UKGgFfZQoaHWMClJldmlld2VyIEKUaHeMB1NvdXJjZXOUaHlHQCIAAAAAAABoeowXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaEVdlIwNd2VhayBzb3VyY2UgQZRhdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoGX2UaBuPlChokWiTaI+QaB1OdWKMCmRlYmF0ZV9jb26UaIspgZR9lChoBX2UKGiPjAdTa2VwdGljlGiRjCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGiTjCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBl9lGgbj5QoaJFok2iPkGgdTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgZfZRoG4+UKGhuaJdobGigaImQaB1OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA4OjAwOjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAhjb3ZlcmFnZZRoAIwIQ292ZXJhZ2WUk5QpgZR9lChoBX2UKGgHjAl1bmNvdmVyZWSUjAdyZWFzb25zlF2UjARwbGFulGGMDmNlcnRpZmljYXRlX2lklE6MD2NlcnRpZmljYXRlX3VybJROjAVhc19vZpROjAhjdXJyZW5jeZSMA0VVUpSMA2NhcJRNECeMCWFnZ3JlZ2F0ZZRKIKEHAIwNdGVybXNfdmVyc2lvbpSMAnYxlHVoGX2UaBuPlChouWi0aLhotWgHaLZoumizaLCQaB1OdWJ1aBl9lGgbj5QoaCRoLmg+aKZoQ2goaCxoQWgmaCpopGg8aDpoSGhFaKdoqWhJaGZoQJBoHU51YowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUaAyMDmZhaWx1cmVfcmVhc29ulGgMjA5mYWlsdXJlX2RldGFpbJRoDIwNZmFpbHVyZV9jbGFzc5RoDIwJcmV0cnlhYmxllE6MCGRvY3NfdXJslGgMdWgZfZRoG4+UKGgeaAdoCZBoHU51Yi4=", + "verify__status_failed.json": "gASVbAIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAZmYWlsZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUTowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUjCNQaXBlbGluZSBzdG9wcGVkIGF0OiByZXNlYXJjaF9lbXB0eZSMDmZhaWx1cmVfcmVhc29ulIwOcmVzZWFyY2hfZW1wdHmUjA5mYWlsdXJlX2RldGFpbJRoDIwNZmFpbHVyZV9jbGFzc5SMFWluc3VmZmljaWVudF9ldmlkZW5jZZSMCXJldHJ5YWJsZZSJjAhkb2NzX3VybJSMMWh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyNpbnN1ZmZpY2llbnQtZXZpZGVuY2WUdWgZfZRoG4+UKGgJaAdoJ2gtaCpoLGglkGgdTnViLg==", + "verify__status_failed_after_a_while.json": "gASVVgIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAZmYWlsZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUTowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUjCRQaXBlbGluZSBzdG9wcGVkOiBjb25jbHVzaW9uX2ZhaWxlZC6UjA5mYWlsdXJlX3JlYXNvbpSMEWNvbmNsdXNpb25fZmFpbGVklIwOZmFpbHVyZV9kZXRhaWyUaAyMDWZhaWx1cmVfY2xhc3OUjAhpbnRlcm5hbJSMCXJldHJ5YWJsZZSJjAhkb2NzX3VybJSMJGh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyNpbnRlcm5hbJR1aBl9lGgbj5QoaAloB2gnaC1oKmgsaCWQaB1OdWIu", + "verify__status_failed_after_a_while_framing.json": "gASVaAIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAZmYWlsZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUTowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUjCFQaXBlbGluZSBzdG9wcGVkOiBmcmFtaW5nX2ZhaWxlZC6UjA5mYWlsdXJlX3JlYXNvbpSMDmZyYW1pbmdfZmFpbGVklIwOZmFpbHVyZV9kZXRhaWyUaAyMDWZhaWx1cmVfY2xhc3OUjBR1cHN0cmVhbV91bmF2YWlsYWJsZZSMCXJldHJ5YWJsZZSIjAhkb2NzX3VybJSMMGh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyN1cHN0cmVhbS11bmF2YWlsYWJsZZR1aBl9lGgbj5QoaAloB2gnaC1oKmgsaCWQaB1OdWIu", + "verify__status_failed_retryable.json": "gASVdAIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAZmYWlsZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUTowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUjChQaXBlbGluZSBzdG9wcGVkIGF0OiBhZGp1ZGljYXRpb25fZmFpbGVklIwOZmFpbHVyZV9yZWFzb26UjBNhZGp1ZGljYXRpb25fZmFpbGVklIwOZmFpbHVyZV9kZXRhaWyUaAyMDWZhaWx1cmVfY2xhc3OUjBR1cHN0cmVhbV91bmF2YWlsYWJsZZSMCXJldHJ5YWJsZZSIjAhkb2NzX3VybJSMMGh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyN1cHN0cmVhbS11bmF2YWlsYWJsZZR1aBl9lGgbj5QoaAloB2gnaC1oKmgsaCWQaB1OdWIu", + "verify__status_needs_input.json": "gASVGAMAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAtuZWVkc19pbnB1dJSMB3Rhc2tfaWSUjCA3Y2ZmMThkYTJkOTc5ZDYzNzBlNTRhMTYwYmUxMjFhZJSMBnJlYXNvbpSMC211bHRpX2NsYWltlIwEaGludJSMYFRoZSB0ZXh0IGhvbGRzIHNldmVyYWwgZGlzdGluY3QgY2xhaW1zLiBTZW5kIHRoZSBvbmVzIHRvIGNoZWNrIHRvIFBPU1QgL3ZlcmlmeS97dGFza19pZH0vc2VsZWN0LpSMCHByb2dyZXNzlGgAjAhQcm9ncmVzc5STlCmBlH2UKGgFfZQojARzdGVwlIwAlIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUTowGY2xhaW1zlF2UKGgAjA5DYW5kaWRhdGVDbGFpbZSTlCmBlH2UKGgFfZQojAR0ZXh0lIwTVGhlIEVhcnRoIGlzIHJvdW5kLpSMBmRvbWFpbpSMB1NjaWVuY2WUdWgbfZRoHY+UKGgqaCiQaB9OdWJoJCmBlH2UKGgFfZQoaCiMIVdhdGVyIGJvaWxzIGF0IDEwMEMgYXQgc2VhIGxldmVsLpRoKowHU2NpZW5jZZR1aBt9lGgdj5QoaCpoKJBoH051YmWMCmNhbmRpZGF0ZXOUXZSMDnNpbWlsYXJfY2xhaW1zlF2UjAVlcnJvcpRoFowOZmFpbHVyZV9yZWFzb26UaBaMDmZhaWx1cmVfZGV0YWlslGgWjA1mYWlsdXJlX2NsYXNzlGgWjAlyZXRyeWFibGWUTowIZG9jc191cmyUaBZ1aBt9lGgdj5QoaA1oC2gJaAdoIZBoH051Yi4=", + "verify__status_not_a_claim.json": "gASV3wIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAZmYWlsZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lIyPVGhlIGlucHV0IGlzIGEgZ3JlZXRpbmcsIG5vdCBhIHN0YXRlbWVudCB0aGF0IGNhbiBiZSBjaGVja2VkLiBTZW5kIG9uZSBmYWN0dWFsIGNsYWltLCBvciBydW4gdGhlIHRleHQgdGhyb3VnaCAvZXh0cmFjdCB0byBlbnVtZXJhdGUgaXRzIGNsYWltcy6UjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUTowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUjBdOb3QgYSB2ZXJpZmlhYmxlIGNsYWltLpSMDmZhaWx1cmVfcmVhc29ulIwLbm90X2FfY2xhaW2UjA5mYWlsdXJlX2RldGFpbJRoDIwNZmFpbHVyZV9jbGFzc5SMDWludmFsaWRfaW5wdXSUjAlyZXRyeWFibGWUiYwIZG9jc191cmyUjClodHRwczovL2xlbnouaW8vZG9jcy9lcnJvcnMjaW52YWxpZC1pbnB1dJR1aBp9lGgcj5QoaA1oCWgHaChoLmgraC1oJpBoHk51Yi4=", + "verify__status_not_a_claim_after_a_while.json": "gASVVAIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAZmYWlsZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUTowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUjB5QaXBlbGluZSBzdG9wcGVkOiBub3RfYV9jbGFpbS6UjA5mYWlsdXJlX3JlYXNvbpSMC25vdF9hX2NsYWltlIwOZmFpbHVyZV9kZXRhaWyUaAyMDWZhaWx1cmVfY2xhc3OUjA1pbnZhbGlkX2lucHV0lIwJcmV0cnlhYmxllImMCGRvY3NfdXJslIwpaHR0cHM6Ly9sZW56LmlvL2RvY3MvZXJyb3JzI2ludmFsaWQtaW5wdXSUdWgZfZRoG4+UKGgJaAdoJ2gtaCpoLGglkGgdTnViLg==", + "verify__status_older_run_completed.json": "gASV5wkAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAljb21wbGV0ZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUaACMDFZlcmlmaWNhdGlvbpSTlCmBlH2UKGgFfZQojA92ZXJpZmljYXRpb25faWSUjAg2OGNhNGFhZpSMBWNsYWltlIwTVGhlIEVhcnRoIGlzIHJvdW5kLpSMCnZpc2liaWxpdHmUjAdwcml2YXRllIwFZGVwdGiUjAhzdGFuZGFyZJSMBmRvbWFpbpSMB1NjaWVuY2WUjAhlbnRpdGllc5RdlGgAjAlFbnRpdHlSZWaUk5QpgZR9lChoBX2UKIwEbmFtZZSMBUVhcnRolIwDcWlklE51aBl9lGgbj5QoaDVoN5BoHU51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoGX2UaBuPlChoUGhYaFRoUmhWkGgdTnViaEwpgZR9lChoBX2UKGhQjANFU0GUaFKMEEVhcnRoIGZyb20gc3BhY2WUaFSMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaFaMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaFiMCjIwMjUtMDEtMTaUdWgZfZRoG4+UKGhQaFhoVGhSaFaQaB1OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoRV2UdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJocSmBlH2UKGgFfZQoaHWMClJldmlld2VyIEKUaHeMB1NvdXJjZXOUaHlHQCIAAAAAAABoeowXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaEVdlIwNd2VhayBzb3VyY2UgQZRhdWgZfZRoG4+UKGhFaHdodWh5aHqQaB1OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoGX2UaBuPlChokWiTaI+QaB1OdWKMCmRlYmF0ZV9jb26UaIspgZR9lChoBX2UKGiPjAdTa2VwdGljlGiRjCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGiTjCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBl9lGgbj5QoaJFok2iPkGgdTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgZfZRoG4+UKGhuaJdobGigaImQaB1OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAhjb3ZlcmFnZZRoAIwIQ292ZXJhZ2WUk5QpgZR9lChoBX2UKGgHjAl1bmNvdmVyZWSUjAdyZWFzb25zlF2UjARwbGFulGGMDmNlcnRpZmljYXRlX2lklE6MD2NlcnRpZmljYXRlX3VybJROjAVhc19vZpROjAhjdXJyZW5jeZSMA0VVUpSMA2NhcJRNECeMCWFnZ3JlZ2F0ZZRKIKEHAIwNdGVybXNfdmVyc2lvbpSMAnYxlHVoGX2UaBuPlChouWi0aLhotWgHaLZoumizaLCQaB1OdWJ1aBl9lGgbj5QoaCRoLmg+aKZoQ2goaCxoQWgmaCpopGg8aDpoSGhFaKdoqWhJaGZoQJBoHU51YowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUaAyMDmZhaWx1cmVfcmVhc29ulGgMjA5mYWlsdXJlX2RldGFpbJRoDIwNZmFpbHVyZV9jbGFzc5RoDIwJcmV0cnlhYmxllE6MCGRvY3NfdXJslGgMdWgZfZRoG4+UKGgeaAdoCZBoHU51Yi4=", + "verify__status_older_run_failed_crashed.json": "gASVOwIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAZmYWlsZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUTowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUjBBQaXBlbGluZSBmYWlsZWQulIwOZmFpbHVyZV9yZWFzb26UjAp0YXNrX2Vycm9ylIwOZmFpbHVyZV9kZXRhaWyUaAyMDWZhaWx1cmVfY2xhc3OUjAhpbnRlcm5hbJSMCXJldHJ5YWJsZZSJjAhkb2NzX3VybJSMJGh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyNpbnRlcm5hbJR1aBl9lGgbj5QoaAloB2gnaC1oKmgsaCWQaB1OdWIu", + "verify__status_older_run_failed_insufficient_evidence.json": "gASVbAIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAZmYWlsZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUTowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUjCNQaXBlbGluZSBzdG9wcGVkIGF0OiByZXNlYXJjaF9lbXB0eZSMDmZhaWx1cmVfcmVhc29ulIwOcmVzZWFyY2hfZW1wdHmUjA5mYWlsdXJlX2RldGFpbJRoDIwNZmFpbHVyZV9jbGFzc5SMFWluc3VmZmljaWVudF9ldmlkZW5jZZSMCXJldHJ5YWJsZZSJjAhkb2NzX3VybJSMMWh0dHBzOi8vbGVuei5pby9kb2NzL2Vycm9ycyNpbnN1ZmZpY2llbnQtZXZpZGVuY2WUdWgZfZRoG4+UKGgJaAdoJ2gtaCpoLGglkGgdTnViLg==", + "verify__status_older_run_in_progress.json": "gASVBgIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjApwcm9jZXNzaW5nlIwHdGFza19pZJSMIDdjZmYxOGRhMmQ5NzlkNjM3MGU1NGExNjBiZTEyMWFklIwGcmVhc29ulIwAlIwEaGludJRoDIwIcHJvZ3Jlc3OUaACMCFByb2dyZXNzlJOUKYGUfZQoaAV9lCiMBHN0ZXCUjAhyZXNlYXJjaJSMBWluZGV4lEsCjAV0b3RhbJRLBYwPZWxhcHNlZF9zZWNvbmRzlEsBjBJwb2xsX2FmdGVyX3NlY29uZHOUSwV1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgYaBdoFmgUaBmQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMBnJlc3VsdJROjAZjbGFpbXOUXZSMCmNhbmRpZGF0ZXOUXZSMDnNpbWlsYXJfY2xhaW1zlF2UjAVlcnJvcpRoDIwOZmFpbHVyZV9yZWFzb26UaAyMDmZhaWx1cmVfZGV0YWlslGgMjA1mYWlsdXJlX2NsYXNzlGgMjAlyZXRyeWFibGWUTowIZG9jc191cmyUaAx1aBp9lGgcj5QoaA5oB2gJkGgeTnViLg==", + "verify__status_processing.json": "gASVBgIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjApwcm9jZXNzaW5nlIwHdGFza19pZJSMIDdjZmYxOGRhMmQ5NzlkNjM3MGU1NGExNjBiZTEyMWFklIwGcmVhc29ulIwAlIwEaGludJRoDIwIcHJvZ3Jlc3OUaACMCFByb2dyZXNzlJOUKYGUfZQoaAV9lCiMBHN0ZXCUjAhyZXNlYXJjaJSMBWluZGV4lEsCjAV0b3RhbJRLBYwPZWxhcHNlZF9zZWNvbmRzlEsBjBJwb2xsX2FmdGVyX3NlY29uZHOUSwV1jBJfX3B5ZGFudGljX2V4dHJhX1+UfZSMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgYaBdoFmgUaBmQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMBnJlc3VsdJROjAZjbGFpbXOUXZSMCmNhbmRpZGF0ZXOUXZSMDnNpbWlsYXJfY2xhaW1zlF2UjAVlcnJvcpRoDIwOZmFpbHVyZV9yZWFzb26UaAyMDmZhaWx1cmVfZGV0YWlslGgMjA1mYWlsdXJlX2NsYXNzlGgMjAlyZXRyeWFibGWUTowIZG9jc191cmyUaAx1aBp9lGgcj5QoaA5oB2gJkGgeTnViLg==", + "verify__status_processing_after_a_while.json": "gASVCgIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjApwcm9jZXNzaW5nlIwHdGFza19pZJSMIDdjZmYxOGRhMmQ5NzlkNjM3MGU1NGExNjBiZTEyMWFklIwGcmVhc29ulIwAlIwEaGludJRoDIwIcHJvZ3Jlc3OUaACMCFByb2dyZXNzlJOUKYGUfZQoaAV9lCiMBHN0ZXCUjAxhZGp1ZGljYXRpb26UjAVpbmRleJRLBIwFdG90YWyUSwWMD2VsYXBzZWRfc2Vjb25kc5RLAYwScG9sbF9hZnRlcl9zZWNvbmRzlEsFdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGGgXaBZoFGgZkIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUTowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUaAyMDmZhaWx1cmVfcmVhc29ulGgMjA5mYWlsdXJlX2RldGFpbJRoDIwNZmFpbHVyZV9jbGFzc5RoDIwJcmV0cnlhYmxllE6MCGRvY3NfdXJslGgMdWgafZRoHI+UKGgOaAdoCZBoHk51Yi4=", + "verify__status_task_stuck.json": "gASVewIAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwKVGFza1N0YXR1c5STlCmBlH2UKIwIX19kaWN0X1+UfZQojAZzdGF0dXOUjAZmYWlsZWSUjAd0YXNrX2lklIwgN2NmZjE4ZGEyZDk3OWQ2MzcwZTU0YTE2MGJlMTIxYWSUjAZyZWFzb26UjACUjARoaW50lGgMjAhwcm9ncmVzc5RoAIwIUHJvZ3Jlc3OUk5QpgZR9lChoBX2UKIwEc3RlcJRoDIwFaW5kZXiUTowFdG90YWyUTowPZWxhcHNlZF9zZWNvbmRzlE6MEnBvbGxfYWZ0ZXJfc2Vjb25kc5ROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlIwUX19weWRhbnRpY19wcml2YXRlX1+UTnVijAZyZXN1bHSUTowGY2xhaW1zlF2UjApjYW5kaWRhdGVzlF2UjA5zaW1pbGFyX2NsYWltc5RdlIwFZXJyb3KUjDhUaGUgdGFzayB3YXMgbmV2ZXIgY29tcGxldGVkIGFuZCBoYXMgYmVlbiBtYXJrZWQgZmFpbGVkLpSMDmZhaWx1cmVfcmVhc29ulIwKdGFza19zdHVja5SMDmZhaWx1cmVfZGV0YWlslGgMjA1mYWlsdXJlX2NsYXNzlIwUdXBzdHJlYW1fdW5hdmFpbGFibGWUjAlyZXRyeWFibGWUiIwIZG9jc191cmyUjDBodHRwczovL2xlbnouaW8vZG9jcy9lcnJvcnMjdXBzdHJlYW0tdW5hdmFpbGFibGWUdWgZfZRoG4+UKGgJaAdoJ2gtaCpoLGglkGgdTnViLg==", + "verify__submit_202.json": "gASV/AAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVGFza0FjY2VwdGVklJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMB3Rhc2tfaWSUjCA3Y2ZmMThkYTJkOTc5ZDYzNzBlNTRhMTYwYmUxMjFhZJSMCmNsYWltX3RleHSUjACUdYwSX19weWRhbnRpY19leHRyYV9flH2UKIwGc3RhdHVzlIwGcXVldWVklIwIY2hhaW5faWSUjBA5OWEwYTljYTg5ZTFlNzJjlHWMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgPaA1oB5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51Yi4=", + "verify__submit_202_options.json": "gASV/AAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVGFza0FjY2VwdGVklJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMB3Rhc2tfaWSUjCA3Y2ZmMThkYTJkOTc5ZDYzNzBlNTRhMTYwYmUxMjFhZJSMCmNsYWltX3RleHSUjACUdYwSX19weWRhbnRpY19leHRyYV9flH2UKIwGc3RhdHVzlIwGcXVldWVklIwIY2hhaW5faWSUjBA5OWEwYTljYTg5ZTFlNzJjlHWMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgPaA1oB5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51Yi4=", + "verify__submit_202_text_alias.json": "gASV/AAAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVGFza0FjY2VwdGVklJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMB3Rhc2tfaWSUjCA3Y2ZmMThkYTJkOTc5ZDYzNzBlNTRhMTYwYmUxMjFhZJSMCmNsYWltX3RleHSUjACUdYwSX19weWRhbnRpY19leHRyYV9flH2UKIwGc3RhdHVzlIwGcXVldWVklIwIY2hhaW5faWSUjBA5OWEwYTljYTg5ZTFlNzJjlHWMF19fcHlkYW50aWNfZmllbGRzX3NldF9flI+UKGgPaA1oB5CMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51Yi4=", + "verify__verification_200.json": "gASVXAgAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVmVyaWZpY2F0aW9ulJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBNUaGUgRWFydGggaXMgcm91bmQulIwKdmlzaWJpbGl0eZSMB3ByaXZhdGWUjAVkZXB0aJSMCHN0YW5kYXJklIwGZG9tYWlulIwHU2NpZW5jZZSMCGVudGl0aWVzlF2UaACMCUVudGl0eVJlZpSTlCmBlH2UKGgFfZQojARuYW1llIwFRWFydGiUjANxaWSUTnWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBhoGpCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoG32UaB2PlChoNmg+aDpoOGg8kGgfTnViaDIpgZR9lChoBX2UKGg2jANFU0GUaDiMEEVhcnRoIGZyb20gc3BhY2WUaDqMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaDyMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaD6MCjIwMjUtMDEtMTaUdWgbfZRoHY+UKGg2aD5oOmg4aDyQaB9OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoK12UdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJoVymBlH2UKGgFfZQoaFuMClJldmlld2VyIEKUaF2MB1NvdXJjZXOUaF9HQCIAAAAAAABoYIwXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaCtdlIwNd2VhayBzb3VyY2UgQZRhdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoG32UaB2PlChod2h5aHWQaB9OdWKMCmRlYmF0ZV9jb26UaHEpgZR9lChoBX2UKGh1jAdTa2VwdGljlGh3jCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGh5jCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBt9lGgdj5QoaHdoeWh1kGgfTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgbfZRoHY+UKGhUaH1oUmiGaG+QaB9OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAhjb3ZlcmFnZZRoAIwIQ292ZXJhZ2WUk5QpgZR9lChoBX2UKIwGc3RhdHVzlIwJdW5jb3ZlcmVklIwHcmVhc29uc5RdlIwEcGxhbpRhjA5jZXJ0aWZpY2F0ZV9pZJROjA9jZXJ0aWZpY2F0ZV91cmyUTowFYXNfb2aUTowIY3VycmVuY3mUjANFVVKUjANjYXCUTRAnjAlhZ2dyZWdhdGWUSiChBwCMDXRlcm1zX3ZlcnNpb26UjAJ2MZR1aBt9lGgdj5QoaKBom2ifaJxolWidaKFommiXkGgfTnVidWgbfZRoHY+UKGgHaBFoJGiMaCloC2gPaCdoCWgNaIpoImggaC5oK2iNaI9oL2hMaCaQaB9OdWIu", + "verify__verification_200_covered.json": "gASVzQgAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVmVyaWZpY2F0aW9ulJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBNUaGUgRWFydGggaXMgcm91bmQulIwKdmlzaWJpbGl0eZSMB3ByaXZhdGWUjAVkZXB0aJSMCHN0YW5kYXJklIwGZG9tYWlulIwHU2NpZW5jZZSMCGVudGl0aWVzlF2UaACMCUVudGl0eVJlZpSTlCmBlH2UKGgFfZQojARuYW1llIwFRWFydGiUjANxaWSUTnWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBhoGpCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoG32UaB2PlChoNmg+aDpoOGg8kGgfTnViaDIpgZR9lChoBX2UKGg2jANFU0GUaDiMEEVhcnRoIGZyb20gc3BhY2WUaDqMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaDyMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaD6MCjIwMjUtMDEtMTaUdWgbfZRoHY+UKGg2aD5oOmg4aDyQaB9OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoK12UdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJoVymBlH2UKGgFfZQoaFuMClJldmlld2VyIEKUaF2MB1NvdXJjZXOUaF9HQCIAAAAAAABoYIwXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaCtdlIwNd2VhayBzb3VyY2UgQZRhdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoG32UaB2PlChod2h5aHWQaB9OdWKMCmRlYmF0ZV9jb26UaHEpgZR9lChoBX2UKGh1jAdTa2VwdGljlGh3jCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGh5jCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBt9lGgdj5QoaHdoeWh1kGgfTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgbfZRoHY+UKGhUaH1oUmiGaG+QaB9OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAhjb3ZlcmFnZZRoAIwIQ292ZXJhZ2WUk5QpgZR9lChoBX2UKIwGc3RhdHVzlIwHY292ZXJlZJSMB3JlYXNvbnOUXZSMDmNlcnRpZmljYXRlX2lklIwgOTViMGYzZGQwMDhiNDY4NDZiNmRkNmIxNTA5OWUyYjOUjA9jZXJ0aWZpY2F0ZV91cmyUjDxodHRwczovL2xlbnouaW8vY2VydGlmaWNhdGUvOTViMGYzZGQwMDhiNDY4NDZiNmRkNmIxNTA5OWUyYjOUjAVhc19vZpSMGTIwMjYtMDMtMTBUMTI6MDE6MzArMDA6MDCUjAhjdXJyZW5jeZSMA0VVUpSMA2NhcJRNECeMCWFnZ3JlZ2F0ZZRKIKEHAIwNdGVybXNfdmVyc2lvbpSMAnYxlHVoG32UaB2PlChoomibaKFonWiVaJ9oo2iZaJeQaB9OdWJ1aBt9lGgdj5QoaAdoEWgkaIxoKWgLaA9oJ2gJaA1oimgiaCBoLmgraI1oj2gvaExoJpBoH051Yi4=", + "verify__verification_200_modified_at_crosses_midnight_by_minutes.json": "gASVfggAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVmVyaWZpY2F0aW9ulJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBNUaGUgRWFydGggaXMgcm91bmQulIwKdmlzaWJpbGl0eZSMB3ByaXZhdGWUjAVkZXB0aJSMCHN0YW5kYXJklIwGZG9tYWlulIwHU2NpZW5jZZSMCGVudGl0aWVzlF2UaACMCUVudGl0eVJlZpSTlCmBlH2UKGgFfZQojARuYW1llIwFRWFydGiUjANxaWSUTnWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBhoGpCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoG32UaB2PlChoNmg+aDpoOGg8kGgfTnViaDIpgZR9lChoBX2UKGg2jANFU0GUaDiMEEVhcnRoIGZyb20gc3BhY2WUaDqMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaDyMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaD6MCjIwMjUtMDEtMTaUdWgbfZRoHY+UKGg2aD5oOmg4aDyQaB9OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoK12UdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJoVymBlH2UKGgFfZQoaFuMClJldmlld2VyIEKUaF2MB1NvdXJjZXOUaF9HQCIAAAAAAABoYIwXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaCtdlIwNd2VhayBzb3VyY2UgQZRhdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoG32UaB2PlChod2h5aHWQaB9OdWKMCmRlYmF0ZV9jb26UaHEpgZR9lChoBX2UKGh1jAdTa2VwdGljlGh3jCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGh5jCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBt9lGgdj5QoaHdoeWh1kGgfTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgbfZRoHY+UKGhUaH1oUmiGaG+QaB9OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDIzOjU1OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lIwgMjAyNi0xMC0wMlQwMDowMzowMC4xMjM0NTYrMDA6MDCUjAhsYW5ndWFnZZSMAmVulIwIY292ZXJhZ2WUaACMCENvdmVyYWdllJOUKYGUfZQoaAV9lCiMBnN0YXR1c5SMCXVuY292ZXJlZJSMB3JlYXNvbnOUXZSMBHBsYW6UYYwOY2VydGlmaWNhdGVfaWSUTowPY2VydGlmaWNhdGVfdXJslE6MBWFzX29mlE6MCGN1cnJlbmN5lIwDRVVSlIwDY2FwlE0QJ4wJYWdncmVnYXRllEogoQcAjA10ZXJtc192ZXJzaW9ulIwCdjGUdWgbfZRoHY+UKGihaJxooGidaJZonmiiaJtomJBoH051YnVoG32UaB2PlChoB2gRaCRojGgpaAtoD2gnaAloDWiKaCJoIGguaCtojmiQaC9oTGgmkGgfTnViLg==", + "verify__verification_200_modified_at_null.json": "gASVXAgAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVmVyaWZpY2F0aW9ulJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBNUaGUgRWFydGggaXMgcm91bmQulIwKdmlzaWJpbGl0eZSMB3ByaXZhdGWUjAVkZXB0aJSMCHN0YW5kYXJklIwGZG9tYWlulIwHU2NpZW5jZZSMCGVudGl0aWVzlF2UaACMCUVudGl0eVJlZpSTlCmBlH2UKGgFfZQojARuYW1llIwFRWFydGiUjANxaWSUTnWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBhoGpCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoG32UaB2PlChoNmg+aDpoOGg8kGgfTnViaDIpgZR9lChoBX2UKGg2jANFU0GUaDiMEEVhcnRoIGZyb20gc3BhY2WUaDqMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaDyMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaD6MCjIwMjUtMDEtMTaUdWgbfZRoHY+UKGg2aD5oOmg4aDyQaB9OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoK12UdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJoVymBlH2UKGgFfZQoaFuMClJldmlld2VyIEKUaF2MB1NvdXJjZXOUaF9HQCIAAAAAAABoYIwXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaCtdlIwNd2VhayBzb3VyY2UgQZRhdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoG32UaB2PlChod2h5aHWQaB9OdWKMCmRlYmF0ZV9jb26UaHEpgZR9lChoBX2UKGh1jAdTa2VwdGljlGh3jCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGh5jCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBt9lGgdj5QoaHdoeWh1kGgfTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgbfZRoHY+UKGhUaH1oUmiGaG+QaB9OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAhjb3ZlcmFnZZRoAIwIQ292ZXJhZ2WUk5QpgZR9lChoBX2UKIwGc3RhdHVzlIwJdW5jb3ZlcmVklIwHcmVhc29uc5RdlIwEcGxhbpRhjA5jZXJ0aWZpY2F0ZV9pZJROjA9jZXJ0aWZpY2F0ZV91cmyUTowFYXNfb2aUTowIY3VycmVuY3mUjANFVVKUjANjYXCUTRAnjAlhZ2dyZWdhdGWUSiChBwCMDXRlcm1zX3ZlcnNpb26UjAJ2MZR1aBt9lGgdj5QoaKBom2ifaJxolWidaKFommiXkGgfTnVidWgbfZRoHY+UKGgHaBFoJGiMaCloC2gPaCdoCWgNaIpoImggaC5oK2iNaI9oL2hMaCaQaB9OdWIu", + "verify__verification_200_modified_at_same_day_hours_apart.json": "gASVXAgAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVmVyaWZpY2F0aW9ulJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBNUaGUgRWFydGggaXMgcm91bmQulIwKdmlzaWJpbGl0eZSMB3ByaXZhdGWUjAVkZXB0aJSMCHN0YW5kYXJklIwGZG9tYWlulIwHU2NpZW5jZZSMCGVudGl0aWVzlF2UaACMCUVudGl0eVJlZpSTlCmBlH2UKGgFfZQojARuYW1llIwFRWFydGiUjANxaWSUTnWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBhoGpCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoG32UaB2PlChoNmg+aDpoOGg8kGgfTnViaDIpgZR9lChoBX2UKGg2jANFU0GUaDiMEEVhcnRoIGZyb20gc3BhY2WUaDqMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaDyMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaD6MCjIwMjUtMDEtMTaUdWgbfZRoHY+UKGg2aD5oOmg4aDyQaB9OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoK12UdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJoVymBlH2UKGgFfZQoaFuMClJldmlld2VyIEKUaF2MB1NvdXJjZXOUaF9HQCIAAAAAAABoYIwXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaCtdlIwNd2VhayBzb3VyY2UgQZRhdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoG32UaB2PlChod2h5aHWQaB9OdWKMCmRlYmF0ZV9jb26UaHEpgZR9lChoBX2UKGh1jAdTa2VwdGljlGh3jCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGh5jCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBt9lGgdj5QoaHdoeWh1kGgfTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgbfZRoHY+UKGhUaH1oUmiGaG+QaB9OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA4OjAwOjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAhjb3ZlcmFnZZRoAIwIQ292ZXJhZ2WUk5QpgZR9lChoBX2UKIwGc3RhdHVzlIwJdW5jb3ZlcmVklIwHcmVhc29uc5RdlIwEcGxhbpRhjA5jZXJ0aWZpY2F0ZV9pZJROjA9jZXJ0aWZpY2F0ZV91cmyUTowFYXNfb2aUTowIY3VycmVuY3mUjANFVVKUjANjYXCUTRAnjAlhZ2dyZWdhdGWUSiChBwCMDXRlcm1zX3ZlcnNpb26UjAJ2MZR1aBt9lGgdj5QoaKBom2ifaJxolWidaKFommiXkGgfTnVidWgbfZRoHY+UKGgHaBFoJGiMaCloC2gPaCdoCWgNaIpoImggaC5oK2iNaI9oL2hMaCaQaB9OdWIu", + "verify__verification_200_modified_at_set.json": "gASVfggAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVmVyaWZpY2F0aW9ulJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBNUaGUgRWFydGggaXMgcm91bmQulIwKdmlzaWJpbGl0eZSMB3ByaXZhdGWUjAVkZXB0aJSMCHN0YW5kYXJklIwGZG9tYWlulIwHU2NpZW5jZZSMCGVudGl0aWVzlF2UaACMCUVudGl0eVJlZpSTlCmBlH2UKGgFfZQojARuYW1llIwFRWFydGiUjANxaWSUTnWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBhoGpCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoG32UaB2PlChoNmg+aDpoOGg8kGgfTnViaDIpgZR9lChoBX2UKGg2jANFU0GUaDiMEEVhcnRoIGZyb20gc3BhY2WUaDqMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaDyMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaD6MCjIwMjUtMDEtMTaUdWgbfZRoHY+UKGg2aD5oOmg4aDyQaB9OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoK12UdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJoVymBlH2UKGgFfZQoaFuMClJldmlld2VyIEKUaF2MB1NvdXJjZXOUaF9HQCIAAAAAAABoYIwXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaCtdlIwNd2VhayBzb3VyY2UgQZRhdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoG32UaB2PlChod2h5aHWQaB9OdWKMCmRlYmF0ZV9jb26UaHEpgZR9lChoBX2UKGh1jAdTa2VwdGljlGh3jCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGh5jCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBt9lGgdj5QoaHdoeWh1kGgfTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgbfZRoHY+UKGhUaH1oUmiGaG+QaB9OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDIzOjU1OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lIwgMjAyNi0xMC0wMlQwMDowMzowMC4xMjM0NTYrMDA6MDCUjAhsYW5ndWFnZZSMAmVulIwIY292ZXJhZ2WUaACMCENvdmVyYWdllJOUKYGUfZQoaAV9lCiMBnN0YXR1c5SMCXVuY292ZXJlZJSMB3JlYXNvbnOUXZSMBHBsYW6UYYwOY2VydGlmaWNhdGVfaWSUTowPY2VydGlmaWNhdGVfdXJslE6MBWFzX29mlE6MCGN1cnJlbmN5lIwDRVVSlIwDY2FwlE0QJ4wJYWdncmVnYXRllEogoQcAjA10ZXJtc192ZXJzaW9ulIwCdjGUdWgbfZRoHY+UKGihaJxooGidaJZonmiiaJtomJBoH051YnVoG32UaB2PlChoB2gRaCRojGgpaAtoD2gnaAloDWiKaCJoIGguaCtojmiQaC9oTGgmkGgfTnViLg==", + "verify__verification_200_result_json_conclusion_only.json": "gASVXgQAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVmVyaWZpY2F0aW9ulJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBNUaGUgRWFydGggaXMgcm91bmQulIwKdmlzaWJpbGl0eZSMB3ByaXZhdGWUjAVkZXB0aJSMCHN0YW5kYXJklIwGZG9tYWlulIwHU2NpZW5jZZSMCGVudGl0aWVzlF2UjA9wcmVzdW1lZF9pbnRlbnSUjACUjAd2ZXJkaWN0lIwEVHJ1ZZSMCmNvbmZpZGVuY2WUjARoaWdolIwKbGVuel9zY29yZZRLCYwLa2V5X2ZpbmRpbmeUjC5UaGUgRWFydGggaXMgYXBwcm94aW1hdGVseSBzcGhlcmljYWwgaW4gc2hhcGUulIwRZXhlY3V0aXZlX3N1bW1hcnmUjBZUaGUgY2xhaW0gaXMgdmVyaWZpZWQulIwId2FybmluZ3OUXZSMEXN1Z2dlc3RlZF9yZXdyaXRllE6MB3NvdXJjZXOUXZSMBWF1ZGl0lGgAjAVBdWRpdJSTlCmBlH2UKGgFfZQojBRhZGp1ZGljYXRpb25fc3VtbWFyeZRoFIwLYXNzZXNzbWVudHOUXZSMCmRlYmF0ZV9wcm+UaACMCkRlYmF0ZVNpZGWUk5QpgZR9lChoBX2UKIwEcm9sZZRoFIwIYXJndW1lbnSUaBSMCHJlYnV0dGFslGgUdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoM2g0aDKQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMCmRlYmF0ZV9jb26UaC4pgZR9lChoBX2UKGgyaBRoM2gUaDRoFHVoNX2UaDePlChoM2g0aDKQaDlOdWKMD3BhbmVsX2FncmVlbWVudJSMBXNwbGl0lHVoNX2UaDePlChoKmg6aCloQGgskGg5TnVijApjcmVhdGVkX2F0lIwgMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTYrMDA6MDCUjAttb2RpZmllZF9hdJROjAhsYW5ndWFnZZSMAmVulIwIY292ZXJhZ2WUaACMCENvdmVyYWdllJOUKYGUfZQoaAV9lCiMBnN0YXR1c5SMCXVuY292ZXJlZJSMB3JlYXNvbnOUXZSMBHBsYW6UYYwOY2VydGlmaWNhdGVfaWSUTowPY2VydGlmaWNhdGVfdXJslE6MBWFzX29mlE6MCGN1cnJlbmN5lIwDRVVSlIwDY2FwlE0QJ4wJYWdncmVnYXRllEogoQcAjA10ZXJtc192ZXJzaW9ulIwCdjGUdWg1fZRoN4+UKGhaaFVoWWhWaE9oV2hbaFRoUZBoOU51YnVoNX2UaDePlChoB2gRaBdoRmgcaAtoD2gaaAloDWhEaBVoE2ggaB5oR2hJaCFoI2gZkGg5TnViLg==", + "verify__verification_200_result_json_empty.json": "gASVXgQAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVmVyaWZpY2F0aW9ulJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBNUaGUgRWFydGggaXMgcm91bmQulIwKdmlzaWJpbGl0eZSMB3ByaXZhdGWUjAVkZXB0aJSMCHN0YW5kYXJklIwGZG9tYWlulIwHU2NpZW5jZZSMCGVudGl0aWVzlF2UjA9wcmVzdW1lZF9pbnRlbnSUjACUjAd2ZXJkaWN0lIwEVHJ1ZZSMCmNvbmZpZGVuY2WUjARoaWdolIwKbGVuel9zY29yZZRLCYwLa2V5X2ZpbmRpbmeUjC5UaGUgRWFydGggaXMgYXBwcm94aW1hdGVseSBzcGhlcmljYWwgaW4gc2hhcGUulIwRZXhlY3V0aXZlX3N1bW1hcnmUjBZUaGUgY2xhaW0gaXMgdmVyaWZpZWQulIwId2FybmluZ3OUXZSMEXN1Z2dlc3RlZF9yZXdyaXRllE6MB3NvdXJjZXOUXZSMBWF1ZGl0lGgAjAVBdWRpdJSTlCmBlH2UKGgFfZQojBRhZGp1ZGljYXRpb25fc3VtbWFyeZRoFIwLYXNzZXNzbWVudHOUXZSMCmRlYmF0ZV9wcm+UaACMCkRlYmF0ZVNpZGWUk5QpgZR9lChoBX2UKIwEcm9sZZRoFIwIYXJndW1lbnSUaBSMCHJlYnV0dGFslGgUdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoM2g0aDKQjBRfX3B5ZGFudGljX3ByaXZhdGVfX5ROdWKMCmRlYmF0ZV9jb26UaC4pgZR9lChoBX2UKGgyaBRoM2gUaDRoFHVoNX2UaDePlChoM2g0aDKQaDlOdWKMD3BhbmVsX2FncmVlbWVudJSMBXNwbGl0lHVoNX2UaDePlChoKmg6aCloQGgskGg5TnVijApjcmVhdGVkX2F0lIwgMjAyNi0xMC0wMVQwOTowNzowMC4xMjM0NTYrMDA6MDCUjAttb2RpZmllZF9hdJROjAhsYW5ndWFnZZSMAmVulIwIY292ZXJhZ2WUaACMCENvdmVyYWdllJOUKYGUfZQoaAV9lCiMBnN0YXR1c5SMCXVuY292ZXJlZJSMB3JlYXNvbnOUXZSMBHBsYW6UYYwOY2VydGlmaWNhdGVfaWSUTowPY2VydGlmaWNhdGVfdXJslE6MBWFzX29mlE6MCGN1cnJlbmN5lIwDRVVSlIwDY2FwlE0QJ4wJYWdncmVnYXRllEogoQcAjA10ZXJtc192ZXJzaW9ulIwCdjGUdWg1fZRoN4+UKGhaaFVoWWhWaE9oV2hbaFRoUZBoOU51YnVoNX2UaDePlChoB2gRaBdoRmgcaAtoD2gaaAloDWhEaBVoE2ggaB5oR2hJaCFoI2gZkGg5TnViLg==", + "verify__verification_200_result_json_old_shape_strings.json": "gASVZQUAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVmVyaWZpY2F0aW9ulJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBNUaGUgRWFydGggaXMgcm91bmQulIwKdmlzaWJpbGl0eZSMB3ByaXZhdGWUjAVkZXB0aJSMCHN0YW5kYXJklIwGZG9tYWlulIwHU2NpZW5jZZSMCGVudGl0aWVzlF2UjA9wcmVzdW1lZF9pbnRlbnSUjACUjAd2ZXJkaWN0lIwEVHJ1ZZSMCmNvbmZpZGVuY2WUjARoaWdolIwKbGVuel9zY29yZZRLCYwLa2V5X2ZpbmRpbmeUjC5UaGUgRWFydGggaXMgYXBwcm94aW1hdGVseSBzcGhlcmljYWwgaW4gc2hhcGUulIwRZXhlY3V0aXZlX3N1bW1hcnmUjBZUaGUgY2xhaW0gaXMgdmVyaWZpZWQulIwId2FybmluZ3OUXZSMEXN1Z2dlc3RlZF9yZXdyaXRllE6MB3NvdXJjZXOUXZRoAIwGU291cmNllJOUKYGUfZQoaAV9lCiMC3NvdXJjZV9uYW1llGgUjAV0aXRsZZRoFIwDdXJslIwVaHR0cHM6Ly9vbGQuZXhhbXBsZS9hlIwHc25pcHBldJSMCE9sZCByb3culIwEZGF0ZZRoFHWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaChoLmgqaCloLJCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMBWF1ZGl0lGgAjAVBdWRpdJSTlCmBlH2UKGgFfZQojBRhZGp1ZGljYXRpb25fc3VtbWFyeZRoFIwLYXNzZXNzbWVudHOUXZRoAIwKQXNzZXNzbWVudJSTlCmBlH2UKGgFfZQojA1wYW5lbGlzdF9uYW1llIwKUmV2aWV3ZXIgQZSMCmZvY3VzX2FyZWGUaBSMBXNjb3JllE6MCXJlYXNvbmluZ5RoFGgeXZR1aC99lGgxj5QoaB5oRGhCaEVoRpBoM051YmGMCmRlYmF0ZV9wcm+UaACMCkRlYmF0ZVNpZGWUk5QpgZR9lChoBX2UKIwEcm9sZZRoFIwIYXJndW1lbnSUaBSMCHJlYnV0dGFslGgUdWgvfZRoMY+UKGhRaFJoUJBoM051YowKZGViYXRlX2NvbpRoTCmBlH2UKGgFfZQoaFBoFGhRaBRoUmgUdWgvfZRoMY+UKGhRaFJoUJBoM051YowPcGFuZWxfYWdyZWVtZW50lIwFc3BsaXSUdWgvfZRoMY+UKGg7aFVoOmhbaEqQaDNOdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAhjb3ZlcmFnZZRoAIwIQ292ZXJhZ2WUk5QpgZR9lChoBX2UKIwGc3RhdHVzlIwJdW5jb3ZlcmVklIwHcmVhc29uc5RdlIwEcGxhbpRhjA5jZXJ0aWZpY2F0ZV9pZJROjA9jZXJ0aWZpY2F0ZV91cmyUTowFYXNfb2aUTowIY3VycmVuY3mUjANFVVKUjANjYXCUTRAnjAlhZ2dyZWdhdGWUSiChBwCMDXRlcm1zX3ZlcnNpb26UjAJ2MZR1aC99lGgxj5QoaHVocGh0aHFoamhyaHZob2hskGgzTnVidWgvfZRoMY+UKGgHaBFoF2hhaBxoC2gPaBpoCWgNaF9oFWgTaCBoHmhiaGRoIWg0aBmQaDNOdWIu", + "verify__verification_by_task_id_200.json": "gASVXAgAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVmVyaWZpY2F0aW9ulJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBNUaGUgRWFydGggaXMgcm91bmQulIwKdmlzaWJpbGl0eZSMB3ByaXZhdGWUjAVkZXB0aJSMCHN0YW5kYXJklIwGZG9tYWlulIwHU2NpZW5jZZSMCGVudGl0aWVzlF2UaACMCUVudGl0eVJlZpSTlCmBlH2UKGgFfZQojARuYW1llIwFRWFydGiUjANxaWSUTnWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBhoGpCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMLlRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbCBpbiBzaGFwZS6UjBFleGVjdXRpdmVfc3VtbWFyeZSMFlRoZSBjbGFpbSBpcyB2ZXJpZmllZC6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoG32UaB2PlChoNmg+aDpoOGg8kGgfTnViaDIpgZR9lChoBX2UKGg2jANFU0GUaDiMEEVhcnRoIGZyb20gc3BhY2WUaDqMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaDyMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaD6MCjIwMjUtMDEtMTaUdWgbfZRoHY+UKGg2aD5oOmg4aDyQaB9OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoK12UdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJoVymBlH2UKGgFfZQoaFuMClJldmlld2VyIEKUaF2MB1NvdXJjZXOUaF9HQCIAAAAAAABoYIwXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaCtdlIwNd2VhayBzb3VyY2UgQZRhdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoG32UaB2PlChod2h5aHWQaB9OdWKMCmRlYmF0ZV9jb26UaHEpgZR9lChoBX2UKGh1jAdTa2VwdGljlGh3jCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGh5jCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBt9lGgdj5QoaHdoeWh1kGgfTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgbfZRoHY+UKGhUaH1oUmiGaG+QaB9OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAhjb3ZlcmFnZZRoAIwIQ292ZXJhZ2WUk5QpgZR9lChoBX2UKIwGc3RhdHVzlIwJdW5jb3ZlcmVklIwHcmVhc29uc5RdlIwEcGxhbpRhjA5jZXJ0aWZpY2F0ZV9pZJROjA9jZXJ0aWZpY2F0ZV91cmyUTowFYXNfb2aUTowIY3VycmVuY3mUjANFVVKUjANjYXCUTRAnjAlhZ2dyZWdhdGWUSiChBwCMDXRlcm1zX3ZlcnNpb26UjAJ2MZR1aBt9lGgdj5QoaKBom2ifaJxolWidaKFommiXkGgfTnVidWgbfZRoHY+UKGgHaBFoJGiMaCloC2gPaCdoCWgNaIpoImggaC5oK2iNaI9oL2hMaCaQaB9OdWIu", + "verify__verification_public_anonymous.json": "gASViQcAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVmVyaWZpY2F0aW9ulJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBNUaGUgRWFydGggaXMgcm91bmQulIwKdmlzaWJpbGl0eZSMBnB1YmxpY5SMBWRlcHRolIwIc3RhbmRhcmSUjAZkb21haW6UjAdTY2llbmNllIwIZW50aXRpZXOUXZRoAIwJRW50aXR5UmVmlJOUKYGUfZQoaAV9lCiMBG5hbWWUjAVFYXJ0aJSMA3FpZJROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGGgakIwUX19weWRhbnRpY19wcml2YXRlX1+UTnViYYwPcHJlc3VtZWRfaW50ZW50lIweVmVyaWZ5IGEgYmFzaWMgc2NpZW50aWZpYyBmYWN0lIwHdmVyZGljdJSMBFRydWWUjApjb25maWRlbmNllIwEaGlnaJSMCmxlbnpfc2NvcmWUSwmMC2tleV9maW5kaW5nlIwuVGhlIEVhcnRoIGlzIGFwcHJveGltYXRlbHkgc3BoZXJpY2FsIGluIHNoYXBlLpSMEWV4ZWN1dGl2ZV9zdW1tYXJ5lIwWVGhlIGNsYWltIGlzIHZlcmlmaWVkLpSMCHdhcm5pbmdzlF2UjBlSZWxpZXMgb24gbGltaXRlZCBzb3VyY2VzlGGMEXN1Z2dlc3RlZF9yZXdyaXRllE6MB3NvdXJjZXOUXZQoaACMBlNvdXJjZZSTlCmBlH2UKGgFfZQojAtzb3VyY2VfbmFtZZSMBE5BU0GUjAV0aXRsZZSMFlRoZSBzaGFwZSBvZiB0aGUgRWFydGiUjAN1cmyUjBpodHRwczovL25hc2EuZXhhbXBsZS9zaGFwZZSMB3NuaXBwZXSUjCtTYXRlbGxpdGUgaW1hZ2VyeSBzaG93cyBhbiBvYmxhdGUgc3BoZXJvaWQulIwEZGF0ZZSMCjIwMjUtMDEtMTWUdWgbfZRoHY+UKGg2aD5oOmg4aDyQaB9OdWJoMimBlH2UKGgFfZQoaDaMA0VTQZRoOIwQRWFydGggZnJvbSBzcGFjZZRoOowZaHR0cHM6Ly9lc2EuZXhhbXBsZS9lYXJ0aJRoPIwrT3JiaXRhbCBtZWFzdXJlbWVudHMgY29uZmlybSB0aGUgY3VydmF0dXJlLpRoPowKMjAyNS0wMS0xNpR1aBt9lGgdj5QoaDZoPmg6aDhoPJBoH051YmWMBWF1ZGl0lGgAjAVBdWRpdJSTlCmBlH2UKGgFfZQojBRhZGp1ZGljYXRpb25fc3VtbWFyeZSMFkJvdGggcmV2aWV3ZXJzIGFncmVlZC6UjAthc3Nlc3NtZW50c5RdlChoAIwKQXNzZXNzbWVudJSTlCmBlH2UKGgFfZQojA1wYW5lbGlzdF9uYW1llIwKUmV2aWV3ZXIgQZSMCmZvY3VzX2FyZWGUjCdDbGFpbSBQcmVjaXNpb24gJiBRdWFudGl0YXRpdmUgQWNjdXJhY3mUjAVzY29yZZRHQCIAAAAAAACMCXJlYXNvbmluZ5SMHVByZWNpc2lvbiBhbmFseXNpcyByZWFzb25pbmculGgrXZR1aBt9lGgdj5QoaCtoXWhbaF9oYJBoH051YmhXKYGUfZQoaAV9lChoW4wKUmV2aWV3ZXIgQpRoXYwHU291cmNlc5RoX0dAIgAAAAAAAGhgjBdTb3VyY2UgYXVkaXQgcmVhc29uaW5nLpRoK12UjA13ZWFrIHNvdXJjZSBBlGF1aBt9lGgdj5QoaCtoXWhbaF9oYJBoH051YmWMCmRlYmF0ZV9wcm+UaACMCkRlYmF0ZVNpZGWUk5QpgZR9lChoBX2UKIwEcm9sZZSMCEFkdm9jYXRllIwIYXJndW1lbnSUjCRTYXRlbGxpdGUgaW1hZ2VyeSBhbmQgZ2VvZGVzeSBhZ3JlZS6UjAhyZWJ1dHRhbJSMIkZsYXQtRWFydGggb2JqZWN0aW9ucyBkbyBub3QgaG9sZC6UdWgbfZRoHY+UKGh3aHlodZBoH051YowKZGViYXRlX2NvbpRocSmBlH2UKGgFfZQoaHWMB1NrZXB0aWOUaHeMIlRoZSBFYXJ0aCBpcyBub3QgYSBwZXJmZWN0IHNwaGVyZS6UaHmMIE9ibGF0ZSwgYnV0IHJvdW5kIGZvciB0aGUgY2xhaW0ulHVoG32UaB2PlChod2h5aHWQaB9OdWKMD3BhbmVsX2FncmVlbWVudJSMCXVuYW5pbW91c5R1aBt9lGgdj5QoaFRofWhSaIZob5BoH051YowKY3JlYXRlZF9hdJSMIDIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2KzAwOjAwlIwLbW9kaWZpZWRfYXSUTowIbGFuZ3VhZ2WUjAJlbpSMCGNvdmVyYWdllE51aBt9lGgdj5QoaAdoEWgkaIxoKWgLaA9oJ2gJaA1oimgiaCBoLmgraI1oj2gvaExoJpBoH051Yi4=", + "verify__verification_public_of_another_user.json": "gASVWwgAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVmVyaWZpY2F0aW9ulJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBNUaGUgRWFydGggaXMgcm91bmQulIwKdmlzaWJpbGl0eZSMBnB1YmxpY5SMBWRlcHRolIwIc3RhbmRhcmSUjAZkb21haW6UjAdTY2llbmNllIwIZW50aXRpZXOUXZRoAIwJRW50aXR5UmVmlJOUKYGUfZQoaAV9lCiMBG5hbWWUjAVFYXJ0aJSMA3FpZJROdYwSX19weWRhbnRpY19leHRyYV9flH2UjBdfX3B5ZGFudGljX2ZpZWxkc19zZXRfX5SPlChoGGgakIwUX19weWRhbnRpY19wcml2YXRlX1+UTnViYYwPcHJlc3VtZWRfaW50ZW50lIweVmVyaWZ5IGEgYmFzaWMgc2NpZW50aWZpYyBmYWN0lIwHdmVyZGljdJSMBFRydWWUjApjb25maWRlbmNllIwEaGlnaJSMCmxlbnpfc2NvcmWUSwmMC2tleV9maW5kaW5nlIwuVGhlIEVhcnRoIGlzIGFwcHJveGltYXRlbHkgc3BoZXJpY2FsIGluIHNoYXBlLpSMEWV4ZWN1dGl2ZV9zdW1tYXJ5lIwWVGhlIGNsYWltIGlzIHZlcmlmaWVkLpSMCHdhcm5pbmdzlF2UjBlSZWxpZXMgb24gbGltaXRlZCBzb3VyY2VzlGGMEXN1Z2dlc3RlZF9yZXdyaXRllE6MB3NvdXJjZXOUXZQoaACMBlNvdXJjZZSTlCmBlH2UKGgFfZQojAtzb3VyY2VfbmFtZZSMBE5BU0GUjAV0aXRsZZSMFlRoZSBzaGFwZSBvZiB0aGUgRWFydGiUjAN1cmyUjBpodHRwczovL25hc2EuZXhhbXBsZS9zaGFwZZSMB3NuaXBwZXSUjCtTYXRlbGxpdGUgaW1hZ2VyeSBzaG93cyBhbiBvYmxhdGUgc3BoZXJvaWQulIwEZGF0ZZSMCjIwMjUtMDEtMTWUdWgbfZRoHY+UKGg2aD5oOmg4aDyQaB9OdWJoMimBlH2UKGgFfZQoaDaMA0VTQZRoOIwQRWFydGggZnJvbSBzcGFjZZRoOowZaHR0cHM6Ly9lc2EuZXhhbXBsZS9lYXJ0aJRoPIwrT3JiaXRhbCBtZWFzdXJlbWVudHMgY29uZmlybSB0aGUgY3VydmF0dXJlLpRoPowKMjAyNS0wMS0xNpR1aBt9lGgdj5QoaDZoPmg6aDhoPJBoH051YmWMBWF1ZGl0lGgAjAVBdWRpdJSTlCmBlH2UKGgFfZQojBRhZGp1ZGljYXRpb25fc3VtbWFyeZSMFkJvdGggcmV2aWV3ZXJzIGFncmVlZC6UjAthc3Nlc3NtZW50c5RdlChoAIwKQXNzZXNzbWVudJSTlCmBlH2UKGgFfZQojA1wYW5lbGlzdF9uYW1llIwKUmV2aWV3ZXIgQZSMCmZvY3VzX2FyZWGUjCdDbGFpbSBQcmVjaXNpb24gJiBRdWFudGl0YXRpdmUgQWNjdXJhY3mUjAVzY29yZZRHQCIAAAAAAACMCXJlYXNvbmluZ5SMHVByZWNpc2lvbiBhbmFseXNpcyByZWFzb25pbmculGgrXZR1aBt9lGgdj5QoaCtoXWhbaF9oYJBoH051YmhXKYGUfZQoaAV9lChoW4wKUmV2aWV3ZXIgQpRoXYwHU291cmNlc5RoX0dAIgAAAAAAAGhgjBdTb3VyY2UgYXVkaXQgcmVhc29uaW5nLpRoK12UjA13ZWFrIHNvdXJjZSBBlGF1aBt9lGgdj5QoaCtoXWhbaF9oYJBoH051YmWMCmRlYmF0ZV9wcm+UaACMCkRlYmF0ZVNpZGWUk5QpgZR9lChoBX2UKIwEcm9sZZSMCEFkdm9jYXRllIwIYXJndW1lbnSUjCRTYXRlbGxpdGUgaW1hZ2VyeSBhbmQgZ2VvZGVzeSBhZ3JlZS6UjAhyZWJ1dHRhbJSMIkZsYXQtRWFydGggb2JqZWN0aW9ucyBkbyBub3QgaG9sZC6UdWgbfZRoHY+UKGh3aHlodZBoH051YowKZGViYXRlX2NvbpRocSmBlH2UKGgFfZQoaHWMB1NrZXB0aWOUaHeMIlRoZSBFYXJ0aCBpcyBub3QgYSBwZXJmZWN0IHNwaGVyZS6UaHmMIE9ibGF0ZSwgYnV0IHJvdW5kIGZvciB0aGUgY2xhaW0ulHVoG32UaB2PlChod2h5aHWQaB9OdWKMD3BhbmVsX2FncmVlbWVudJSMCXVuYW5pbW91c5R1aBt9lGgdj5QoaFRofWhSaIZob5BoH051YowKY3JlYXRlZF9hdJSMIDIwMjYtMTAtMDFUMDk6MDc6MDAuMTIzNDU2KzAwOjAwlIwLbW9kaWZpZWRfYXSUTowIbGFuZ3VhZ2WUjAJlbpSMCGNvdmVyYWdllGgAjAhDb3ZlcmFnZZSTlCmBlH2UKGgFfZQojAZzdGF0dXOUjAl1bmNvdmVyZWSUjAdyZWFzb25zlF2UjARwbGFulGGMDmNlcnRpZmljYXRlX2lklE6MD2NlcnRpZmljYXRlX3VybJROjAVhc19vZpROjAhjdXJyZW5jeZSMA0VVUpSMA2NhcJRNECeMCWFnZ3JlZ2F0ZZRKIKEHAIwNdGVybXNfdmVyc2lvbpSMAnYxlHVoG32UaB2PlChooGibaJ9onGiVaJ1ooWiaaJeQaB9OdWJ1aBt9lGgdj5QoaAdoEWgkaIxoKWgLaA9oJ2gJaA1oimgiaCBoLmgraI1oj2gvaExoJpBoH051Yi4=", + "verify__verification_zero_retention_served.json": "gASVZQgAAAAAAACMDmxlbnpfaW8ubW9kZWxzlIwMVmVyaWZpY2F0aW9ulJOUKYGUfZQojAhfX2RpY3RfX5R9lCiMD3ZlcmlmaWNhdGlvbl9pZJSMCDY4Y2E0YWFmlIwFY2xhaW2UjBNUaGUgRWFydGggaXMgcm91bmQulIwKdmlzaWJpbGl0eZSMB3ByaXZhdGWUjAVkZXB0aJSMCHN0YW5kYXJklIwGZG9tYWlulIwHU2NpZW5jZZSMCGVudGl0aWVzlF2UaACMCUVudGl0eVJlZpSTlCmBlH2UKGgFfZQojARuYW1llIwFRWFydGiUjANxaWSUTnWMEl9fcHlkYW50aWNfZXh0cmFfX5R9lIwXX19weWRhbnRpY19maWVsZHNfc2V0X1+Uj5QoaBhoGpCMFF9fcHlkYW50aWNfcHJpdmF0ZV9flE51YmGMD3ByZXN1bWVkX2ludGVudJSMHlZlcmlmeSBhIGJhc2ljIHNjaWVudGlmaWMgZmFjdJSMB3ZlcmRpY3SUjARUcnVllIwKY29uZmlkZW5jZZSMBGhpZ2iUjApsZW56X3Njb3JllEsJjAtrZXlfZmluZGluZ5SMJVRoZSBFYXJ0aCBpcyBhcHByb3hpbWF0ZWx5IHNwaGVyaWNhbC6UjBFleGVjdXRpdmVfc3VtbWFyeZSMKFRoZSBjbGFpbSBpcyB3ZWxsIHN1cHBvcnRlZCBieSBldmlkZW5jZS6UjAh3YXJuaW5nc5RdlIwZUmVsaWVzIG9uIGxpbWl0ZWQgc291cmNlc5RhjBFzdWdnZXN0ZWRfcmV3cml0ZZROjAdzb3VyY2VzlF2UKGgAjAZTb3VyY2WUk5QpgZR9lChoBX2UKIwLc291cmNlX25hbWWUjAROQVNBlIwFdGl0bGWUjBZUaGUgc2hhcGUgb2YgdGhlIEVhcnRolIwDdXJslIwaaHR0cHM6Ly9uYXNhLmV4YW1wbGUvc2hhcGWUjAdzbmlwcGV0lIwrU2F0ZWxsaXRlIGltYWdlcnkgc2hvd3MgYW4gb2JsYXRlIHNwaGVyb2lkLpSMBGRhdGWUjAoyMDI1LTAxLTE1lHVoG32UaB2PlChoNmg+aDpoOGg8kGgfTnViaDIpgZR9lChoBX2UKGg2jANFU0GUaDiMEEVhcnRoIGZyb20gc3BhY2WUaDqMGWh0dHBzOi8vZXNhLmV4YW1wbGUvZWFydGiUaDyMK09yYml0YWwgbWVhc3VyZW1lbnRzIGNvbmZpcm0gdGhlIGN1cnZhdHVyZS6UaD6MCjIwMjUtMDEtMTaUdWgbfZRoHY+UKGg2aD5oOmg4aDyQaB9OdWJljAVhdWRpdJRoAIwFQXVkaXSUk5QpgZR9lChoBX2UKIwUYWRqdWRpY2F0aW9uX3N1bW1hcnmUjBZCb3RoIHJldmlld2VycyBhZ3JlZWQulIwLYXNzZXNzbWVudHOUXZQoaACMCkFzc2Vzc21lbnSUk5QpgZR9lChoBX2UKIwNcGFuZWxpc3RfbmFtZZSMClJldmlld2VyIEGUjApmb2N1c19hcmVhlIwnQ2xhaW0gUHJlY2lzaW9uICYgUXVhbnRpdGF0aXZlIEFjY3VyYWN5lIwFc2NvcmWUR0AiAAAAAAAAjAlyZWFzb25pbmeUjB1QcmVjaXNpb24gYW5hbHlzaXMgcmVhc29uaW5nLpRoK12UdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJoVymBlH2UKGgFfZQoaFuMClJldmlld2VyIEKUaF2MB1NvdXJjZXOUaF9HQCIAAAAAAABoYIwXU291cmNlIGF1ZGl0IHJlYXNvbmluZy6UaCtdlIwNd2VhayBzb3VyY2UgQZRhdWgbfZRoHY+UKGgraF1oW2hfaGCQaB9OdWJljApkZWJhdGVfcHJvlGgAjApEZWJhdGVTaWRllJOUKYGUfZQoaAV9lCiMBHJvbGWUjAhBZHZvY2F0ZZSMCGFyZ3VtZW50lIwkU2F0ZWxsaXRlIGltYWdlcnkgYW5kIGdlb2Rlc3kgYWdyZWUulIwIcmVidXR0YWyUjCJGbGF0LUVhcnRoIG9iamVjdGlvbnMgZG8gbm90IGhvbGQulHVoG32UaB2PlChod2h5aHWQaB9OdWKMCmRlYmF0ZV9jb26UaHEpgZR9lChoBX2UKGh1jAdTa2VwdGljlGh3jCJUaGUgRWFydGggaXMgbm90IGEgcGVyZmVjdCBzcGhlcmUulGh5jCBPYmxhdGUsIGJ1dCByb3VuZCBmb3IgdGhlIGNsYWltLpR1aBt9lGgdj5QoaHdoeWh1kGgfTnVijA9wYW5lbF9hZ3JlZW1lbnSUjAl1bmFuaW1vdXOUdWgbfZRoHY+UKGhUaH1oUmiGaG+QaB9OdWKMCmNyZWF0ZWRfYXSUjCAyMDI2LTEwLTAxVDA5OjA3OjAwLjEyMzQ1NiswMDowMJSMC21vZGlmaWVkX2F0lE6MCGxhbmd1YWdllIwCZW6UjAhjb3ZlcmFnZZRoAIwIQ292ZXJhZ2WUk5QpgZR9lChoBX2UKIwGc3RhdHVzlIwJdW5jb3ZlcmVklIwHcmVhc29uc5RdlIwEcGxhbpRhjA5jZXJ0aWZpY2F0ZV9pZJROjA9jZXJ0aWZpY2F0ZV91cmyUTowFYXNfb2aUTowIY3VycmVuY3mUjANFVVKUjANjYXCUTRAnjAlhZ2dyZWdhdGWUSiChBwCMDXRlcm1zX3ZlcnNpb26UjAJ2MZR1aBt9lGgdj5QoaKBom2ifaJxolWidaKFommiXkGgfTnVidWgbfZRoHY+UKGgHaBFoJGiMaCloC2gPaCdoCWgNaIpoImggaC5oK2iNaI9oL2hMaCaQaB9OdWIu" +} diff --git a/tests/fixtures/parity/requests.json b/tests/fixtures/parity/requests.json new file mode 100644 index 0000000..699837e --- /dev/null +++ b/tests/fixtures/parity/requests.json @@ -0,0 +1,68 @@ +{ + "citecheck_default": { + "text": "The Eiffel Tower is in Berlin. See https://example.org/eiffel." + }, + "citecheck_pairs": { + "language": "fr", + "pairs": [ + { + "statement": "The tower is in Paris.", + "url": "https://example.org/eiffel" + } + ] + }, + "citecheck_webhook_empty": { + "text": "The Eiffel Tower is in Berlin. See https://example.org/eiffel.", + "webhook_url": "" + }, + "citecheck_webhook_url": { + "max_citations": 4, + "text": "The Eiffel Tower is in Berlin. See https://example.org/eiffel.", + "webhook_url": "https://hooks.example.test/x" + }, + "review_default": { + "text": "The Eiffel Tower is in Berlin. See https://example.org/eiffel.", + "visibility": "private" + }, + "review_options": { + "escalate": { + "confidence": [ + "low" + ], + "depth": "low", + "max_assessments": 5, + "max_citations": 3, + "max_verifications": 2, + "suggest_edits": true, + "verdicts": [ + "False" + ] + }, + "language": "de", + "text": "The Eiffel Tower is in Berlin. See https://example.org/eiffel.", + "visibility": "unlisted" + }, + "review_webhook_empty": { + "text": "The Eiffel Tower is in Berlin. See https://example.org/eiffel.", + "visibility": "private", + "webhook_url": "" + }, + "review_webhook_url": { + "text": "The Eiffel Tower is in Berlin. See https://example.org/eiffel.", + "visibility": "private", + "webhook_url": "https://hooks.example.test/x" + }, + "verify_batch_webhook_url": { + "claims": [ + { + "text": "The Earth is round." + } + ], + "webhook_url": "https://hooks.example.test/x" + }, + "verify_webhook_url": { + "source_url": "", + "text": "The Earth is round.", + "webhook_url": "https://hooks.example.test/x" + } +} diff --git a/tests/fixtures/parity/schemas.json b/tests/fixtures/parity/schemas.json new file mode 100644 index 0000000..4c8b1a6 --- /dev/null +++ b/tests/fixtures/parity/schemas.json @@ -0,0 +1,26564 @@ +{ + "AskHistory:serialization": { + "$defs": { + "AskMessage": { + "additionalProperties": true, + "description": "One message in an ``/ask`` conversation thread.", + "properties": { + "content": { + "default": "", + "title": "Content", + "type": "string" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "AskMessage", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Returned by ``GET /ask/{verification_id}``.", + "properties": { + "can_send": { + "default": false, + "title": "Can Send", + "type": "boolean" + }, + "exchange_limit": { + "default": 0, + "title": "Exchange Limit", + "type": "integer" + }, + "exchanges_used": { + "default": 0, + "title": "Exchanges Used", + "type": "integer" + }, + "messages": { + "items": { + "$ref": "#/$defs/AskMessage" + }, + "title": "Messages", + "type": "array" + } + }, + "title": "AskHistory", + "type": "object" + }, + "AskHistory:validation": { + "$defs": { + "AskMessage": { + "additionalProperties": true, + "description": "One message in an ``/ask`` conversation thread.", + "properties": { + "content": { + "default": "", + "title": "Content", + "type": "string" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "AskMessage", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Returned by ``GET /ask/{verification_id}``.", + "properties": { + "can_send": { + "default": false, + "title": "Can Send", + "type": "boolean" + }, + "exchange_limit": { + "default": 0, + "title": "Exchange Limit", + "type": "integer" + }, + "exchanges_used": { + "default": 0, + "title": "Exchanges Used", + "type": "integer" + }, + "messages": { + "items": { + "$ref": "#/$defs/AskMessage" + }, + "title": "Messages", + "type": "array" + } + }, + "title": "AskHistory", + "type": "object" + }, + "AskMessage:serialization": { + "additionalProperties": true, + "description": "One message in an ``/ask`` conversation thread.", + "properties": { + "content": { + "default": "", + "title": "Content", + "type": "string" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "AskMessage", + "type": "object" + }, + "AskMessage:validation": { + "additionalProperties": true, + "description": "One message in an ``/ask`` conversation thread.", + "properties": { + "content": { + "default": "", + "title": "Content", + "type": "string" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "AskMessage", + "type": "object" + }, + "AskReply:serialization": { + "additionalProperties": true, + "description": "Returned by ``POST /ask/{verification_id}``.\n\n``content`` is the assistant's reply text in a small markdown\nsubset:\n\n- ``**bold**`` and ``*italic*``\n- ``- `` or ``* `` bullet lists\n- Blank-line paragraph breaks; single newlines inside a paragraph\n mean line break\n\nThe model only produces these \u2014 no headings, no tables, no code\nblocks. Pass it through any markdown library or display it\nverbatim. See https://lenz.io/docs/quickstart#ask-reply-format.\n\nPre-1.0.2 the SDK declared a single ``reply`` field that never\nmatched the wire \u2014 the server has always returned\n``{role, content, created_at}``. 1.0.2 aligned the typed surface.", + "properties": { + "content": { + "default": "", + "title": "Content", + "type": "string" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "AskReply", + "type": "object" + }, + "AskReply:validation": { + "additionalProperties": true, + "description": "Returned by ``POST /ask/{verification_id}``.\n\n``content`` is the assistant's reply text in a small markdown\nsubset:\n\n- ``**bold**`` and ``*italic*``\n- ``- `` or ``* `` bullet lists\n- Blank-line paragraph breaks; single newlines inside a paragraph\n mean line break\n\nThe model only produces these \u2014 no headings, no tables, no code\nblocks. Pass it through any markdown library or display it\nverbatim. See https://lenz.io/docs/quickstart#ask-reply-format.\n\nPre-1.0.2 the SDK declared a single ``reply`` field that never\nmatched the wire \u2014 the server has always returned\n``{role, content, created_at}``. 1.0.2 aligned the typed surface.", + "properties": { + "content": { + "default": "", + "title": "Content", + "type": "string" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "AskReply", + "type": "object" + }, + "AssessClaim:serialization": { + "additionalProperties": true, + "description": "Per-claim entry in an ``AssessResponse.claims`` list.\n\nLean shape by design \u2014 no model_votes, no panel identity. The\n``verification_url`` (when present) points at the full\n``ClaimDetailOut`` payload at ``GET /api/v1/verifications/{id}`` for\ncallers that want citations and the full audit trail.\n\nA row with ``verdict == \"Error\"`` could not be given a verdict. On a\nlist call it stays in position (one row per item sent), is not charged,\nand says why: ``error_code`` names the cause and ``hint`` is one\nsentence on what to send next. ``hint`` is the field to surface to a\nhuman \u2014 it is written per cause and stays correct as causes are added.\nA vague input is assessed on its most likely reading, which ``claim``\ncarries. A compound input is assessed on its main claim; the other\nclaims found in it are listed in ``identified_claims`` (also with a\n``hint``). These fields default empty so older servers that don't send\nthem still parse.", + "properties": { + "candidate_claims": { + "deprecated": true, + "items": { + "type": "string" + }, + "title": "Candidate Claims", + "type": "array" + }, + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "dissent": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Dissent" + }, + "error_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Error Code" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "identified_claims": { + "items": { + "type": "string" + }, + "title": "Identified Claims", + "type": "array" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + } + }, + "title": "AssessClaim", + "type": "object" + }, + "AssessClaim:validation": { + "additionalProperties": true, + "description": "Per-claim entry in an ``AssessResponse.claims`` list.\n\nLean shape by design \u2014 no model_votes, no panel identity. The\n``verification_url`` (when present) points at the full\n``ClaimDetailOut`` payload at ``GET /api/v1/verifications/{id}`` for\ncallers that want citations and the full audit trail.\n\nA row with ``verdict == \"Error\"`` could not be given a verdict. On a\nlist call it stays in position (one row per item sent), is not charged,\nand says why: ``error_code`` names the cause and ``hint`` is one\nsentence on what to send next. ``hint`` is the field to surface to a\nhuman \u2014 it is written per cause and stays correct as causes are added.\nA vague input is assessed on its most likely reading, which ``claim``\ncarries. A compound input is assessed on its main claim; the other\nclaims found in it are listed in ``identified_claims`` (also with a\n``hint``). These fields default empty so older servers that don't send\nthem still parse.", + "properties": { + "candidate_claims": { + "deprecated": true, + "items": { + "type": "string" + }, + "title": "Candidate Claims", + "type": "array" + }, + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "dissent": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Dissent" + }, + "error_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Error Code" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "identified_claims": { + "items": { + "type": "string" + }, + "title": "Identified Claims", + "type": "array" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + } + }, + "title": "AssessClaim", + "type": "object" + }, + "AssessResponse:serialization": { + "$defs": { + "AssessClaim": { + "additionalProperties": true, + "description": "Per-claim entry in an ``AssessResponse.claims`` list.\n\nLean shape by design \u2014 no model_votes, no panel identity. The\n``verification_url`` (when present) points at the full\n``ClaimDetailOut`` payload at ``GET /api/v1/verifications/{id}`` for\ncallers that want citations and the full audit trail.\n\nA row with ``verdict == \"Error\"`` could not be given a verdict. On a\nlist call it stays in position (one row per item sent), is not charged,\nand says why: ``error_code`` names the cause and ``hint`` is one\nsentence on what to send next. ``hint`` is the field to surface to a\nhuman \u2014 it is written per cause and stays correct as causes are added.\nA vague input is assessed on its most likely reading, which ``claim``\ncarries. A compound input is assessed on its main claim; the other\nclaims found in it are listed in ``identified_claims`` (also with a\n``hint``). These fields default empty so older servers that don't send\nthem still parse.", + "properties": { + "candidate_claims": { + "deprecated": true, + "items": { + "type": "string" + }, + "title": "Candidate Claims", + "type": "array" + }, + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "dissent": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Dissent" + }, + "error_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Error Code" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "identified_claims": { + "items": { + "type": "string" + }, + "title": "Identified Claims", + "type": "array" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + } + }, + "title": "AssessClaim", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Output of ``POST /assess``.\n\nSingle form (``assess(claim=...)``): ``claims`` is one entry per claim\nfound in the input \u2014 up to 20, at 1 credit each. A text that makes more\nclaims than one call checks gets its most check-worthy 20 checked and the\nrest listed in ``more_claims``, unchecked and free: send them back with\n``assess(claims=...)``, 20 a call, to check them. ``error`` is set when\nthe input holds no checkable claim.\n\nList form (``assess(claims=[...])``): exactly one entry per item sent,\nin the order sent. An item that could not be given a verdict is an\n``\"Error\"`` row in position (see ``AssessClaim``), never a missing one;\nthe top-level ``error`` stays ``None``.\n\nWhen ``claims`` is empty (single form), ``error_code`` is ``'no_claim'``:\nthe input holds no checkable claim (a vague input is assessed on its\nmost likely reading instead). It defaults empty, so older servers that\ndon't send it degrade to the plain ``error`` message.", + "properties": { + "candidate_claims": { + "deprecated": true, + "items": { + "type": "string" + }, + "title": "Candidate Claims", + "type": "array" + }, + "claims": { + "items": { + "$ref": "#/$defs/AssessClaim" + }, + "title": "Claims", + "type": "array" + }, + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Error" + }, + "error_code": { + "default": "", + "title": "Error Code", + "type": "string" + }, + "more_claims": { + "items": { + "type": "string" + }, + "title": "More Claims", + "type": "array" + } + }, + "title": "AssessResponse", + "type": "object" + }, + "AssessResponse:validation": { + "$defs": { + "AssessClaim": { + "additionalProperties": true, + "description": "Per-claim entry in an ``AssessResponse.claims`` list.\n\nLean shape by design \u2014 no model_votes, no panel identity. The\n``verification_url`` (when present) points at the full\n``ClaimDetailOut`` payload at ``GET /api/v1/verifications/{id}`` for\ncallers that want citations and the full audit trail.\n\nA row with ``verdict == \"Error\"`` could not be given a verdict. On a\nlist call it stays in position (one row per item sent), is not charged,\nand says why: ``error_code`` names the cause and ``hint`` is one\nsentence on what to send next. ``hint`` is the field to surface to a\nhuman \u2014 it is written per cause and stays correct as causes are added.\nA vague input is assessed on its most likely reading, which ``claim``\ncarries. A compound input is assessed on its main claim; the other\nclaims found in it are listed in ``identified_claims`` (also with a\n``hint``). These fields default empty so older servers that don't send\nthem still parse.", + "properties": { + "candidate_claims": { + "deprecated": true, + "items": { + "type": "string" + }, + "title": "Candidate Claims", + "type": "array" + }, + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "dissent": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Dissent" + }, + "error_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Error Code" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "identified_claims": { + "items": { + "type": "string" + }, + "title": "Identified Claims", + "type": "array" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + } + }, + "title": "AssessClaim", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Output of ``POST /assess``.\n\nSingle form (``assess(claim=...)``): ``claims`` is one entry per claim\nfound in the input \u2014 up to 20, at 1 credit each. A text that makes more\nclaims than one call checks gets its most check-worthy 20 checked and the\nrest listed in ``more_claims``, unchecked and free: send them back with\n``assess(claims=...)``, 20 a call, to check them. ``error`` is set when\nthe input holds no checkable claim.\n\nList form (``assess(claims=[...])``): exactly one entry per item sent,\nin the order sent. An item that could not be given a verdict is an\n``\"Error\"`` row in position (see ``AssessClaim``), never a missing one;\nthe top-level ``error`` stays ``None``.\n\nWhen ``claims`` is empty (single form), ``error_code`` is ``'no_claim'``:\nthe input holds no checkable claim (a vague input is assessed on its\nmost likely reading instead). It defaults empty, so older servers that\ndon't send it degrade to the plain ``error`` message.", + "properties": { + "candidate_claims": { + "deprecated": true, + "items": { + "type": "string" + }, + "title": "Candidate Claims", + "type": "array" + }, + "claims": { + "items": { + "$ref": "#/$defs/AssessClaim" + }, + "title": "Claims", + "type": "array" + }, + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Error" + }, + "error_code": { + "default": "", + "title": "Error Code", + "type": "string" + }, + "more_claims": { + "items": { + "type": "string" + }, + "title": "More Claims", + "type": "array" + } + }, + "title": "AssessResponse", + "type": "object" + }, + "Assessment:serialization": { + "additionalProperties": true, + "description": "One reviewer's structured assessment.\n\nCurrent verifications carry three reviewers, ``Reviewer A`` to\n``Reviewer C``, all running the same checks over the evidence, plus\n``Reviewer D`` and ``Reviewer E`` when those three disagree. Their\n``focus_area`` reads ``\"Sources, evidence fit and wording\"``, and\n``warnings`` holds the source issues, evidence gaps and precision issues\nthat reviewer found, in one list.\n\nOlder verifications carry specialist panelists instead, one warning\ncategory each: logical fallacies (Logic Examiner), precision issues\n(Precision Analyst), weakest sources (Source Auditor) and, before\n2026-06, missing context (Context Analyst).\n\n``panelist_name`` is a display value, not a stable key \u2014 don't branch\non it. ``score`` is a reviewer-level 1-10 sub-score, distinct from the\ntop-level ``lenz_score`` on a ``Verification``.", + "properties": { + "focus_area": { + "default": "", + "title": "Focus Area", + "type": "string" + }, + "panelist_name": { + "default": "", + "title": "Panelist Name", + "type": "string" + }, + "reasoning": { + "default": "", + "title": "Reasoning", + "type": "string" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Score" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Assessment", + "type": "object" + }, + "Assessment:validation": { + "additionalProperties": true, + "description": "One reviewer's structured assessment.\n\nCurrent verifications carry three reviewers, ``Reviewer A`` to\n``Reviewer C``, all running the same checks over the evidence, plus\n``Reviewer D`` and ``Reviewer E`` when those three disagree. Their\n``focus_area`` reads ``\"Sources, evidence fit and wording\"``, and\n``warnings`` holds the source issues, evidence gaps and precision issues\nthat reviewer found, in one list.\n\nOlder verifications carry specialist panelists instead, one warning\ncategory each: logical fallacies (Logic Examiner), precision issues\n(Precision Analyst), weakest sources (Source Auditor) and, before\n2026-06, missing context (Context Analyst).\n\n``panelist_name`` is a display value, not a stable key \u2014 don't branch\non it. ``score`` is a reviewer-level 1-10 sub-score, distinct from the\ntop-level ``lenz_score`` on a ``Verification``.", + "properties": { + "focus_area": { + "default": "", + "title": "Focus Area", + "type": "string" + }, + "panelist_name": { + "default": "", + "title": "Panelist Name", + "type": "string" + }, + "reasoning": { + "default": "", + "title": "Reasoning", + "type": "string" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Score" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Assessment", + "type": "object" + }, + "Audit:serialization": { + "$defs": { + "Assessment": { + "additionalProperties": true, + "description": "One reviewer's structured assessment.\n\nCurrent verifications carry three reviewers, ``Reviewer A`` to\n``Reviewer C``, all running the same checks over the evidence, plus\n``Reviewer D`` and ``Reviewer E`` when those three disagree. Their\n``focus_area`` reads ``\"Sources, evidence fit and wording\"``, and\n``warnings`` holds the source issues, evidence gaps and precision issues\nthat reviewer found, in one list.\n\nOlder verifications carry specialist panelists instead, one warning\ncategory each: logical fallacies (Logic Examiner), precision issues\n(Precision Analyst), weakest sources (Source Auditor) and, before\n2026-06, missing context (Context Analyst).\n\n``panelist_name`` is a display value, not a stable key \u2014 don't branch\non it. ``score`` is a reviewer-level 1-10 sub-score, distinct from the\ntop-level ``lenz_score`` on a ``Verification``.", + "properties": { + "focus_area": { + "default": "", + "title": "Focus Area", + "type": "string" + }, + "panelist_name": { + "default": "", + "title": "Panelist Name", + "type": "string" + }, + "reasoning": { + "default": "", + "title": "Reasoning", + "type": "string" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Score" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Assessment", + "type": "object" + }, + "DebateSide": { + "additionalProperties": true, + "description": "One side of the adversarial debate transcript.", + "properties": { + "argument": { + "default": "", + "title": "Argument", + "type": "string" + }, + "rebuttal": { + "default": "", + "title": "Rebuttal", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "DebateSide", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Nested explainability block \u2014 for callers who want the panel's work.", + "properties": { + "adjudication_summary": { + "default": "", + "title": "Adjudication Summary", + "type": "string" + }, + "assessments": { + "items": { + "$ref": "#/$defs/Assessment" + }, + "title": "Assessments", + "type": "array" + }, + "debate_con": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "debate_pro": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "panel_agreement": { + "default": "", + "title": "Panel Agreement", + "type": "string" + } + }, + "title": "Audit", + "type": "object" + }, + "Audit:validation": { + "$defs": { + "Assessment": { + "additionalProperties": true, + "description": "One reviewer's structured assessment.\n\nCurrent verifications carry three reviewers, ``Reviewer A`` to\n``Reviewer C``, all running the same checks over the evidence, plus\n``Reviewer D`` and ``Reviewer E`` when those three disagree. Their\n``focus_area`` reads ``\"Sources, evidence fit and wording\"``, and\n``warnings`` holds the source issues, evidence gaps and precision issues\nthat reviewer found, in one list.\n\nOlder verifications carry specialist panelists instead, one warning\ncategory each: logical fallacies (Logic Examiner), precision issues\n(Precision Analyst), weakest sources (Source Auditor) and, before\n2026-06, missing context (Context Analyst).\n\n``panelist_name`` is a display value, not a stable key \u2014 don't branch\non it. ``score`` is a reviewer-level 1-10 sub-score, distinct from the\ntop-level ``lenz_score`` on a ``Verification``.", + "properties": { + "focus_area": { + "default": "", + "title": "Focus Area", + "type": "string" + }, + "panelist_name": { + "default": "", + "title": "Panelist Name", + "type": "string" + }, + "reasoning": { + "default": "", + "title": "Reasoning", + "type": "string" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Score" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Assessment", + "type": "object" + }, + "DebateSide": { + "additionalProperties": true, + "description": "One side of the adversarial debate transcript.", + "properties": { + "argument": { + "default": "", + "title": "Argument", + "type": "string" + }, + "rebuttal": { + "default": "", + "title": "Rebuttal", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "DebateSide", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Nested explainability block \u2014 for callers who want the panel's work.", + "properties": { + "adjudication_summary": { + "default": "", + "title": "Adjudication Summary", + "type": "string" + }, + "assessments": { + "items": { + "$ref": "#/$defs/Assessment" + }, + "title": "Assessments", + "type": "array" + }, + "debate_con": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "debate_pro": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "panel_agreement": { + "default": "", + "title": "Panel Agreement", + "type": "string" + } + }, + "title": "Audit", + "type": "object" + }, + "BatchAccepted:serialization": { + "$defs": { + "TaskAccepted": { + "additionalProperties": true, + "description": "Returned by ``POST /verify`` and per item of ``POST /verify/batch``.", + "properties": { + "claim_text": { + "default": "", + "title": "Claim Text", + "type": "string" + }, + "task_id": { + "default": "", + "title": "Task Id", + "type": "string" + } + }, + "title": "TaskAccepted", + "type": "object" + } + }, + "additionalProperties": true, + "properties": { + "batch_id": { + "default": "", + "title": "Batch Id", + "type": "string" + }, + "items": { + "items": { + "$ref": "#/$defs/TaskAccepted" + }, + "title": "Items", + "type": "array" + } + }, + "title": "BatchAccepted", + "type": "object" + }, + "BatchAccepted:validation": { + "$defs": { + "TaskAccepted": { + "additionalProperties": true, + "description": "Returned by ``POST /verify`` and per item of ``POST /verify/batch``.", + "properties": { + "claim_text": { + "default": "", + "title": "Claim Text", + "type": "string" + }, + "task_id": { + "default": "", + "title": "Task Id", + "type": "string" + } + }, + "title": "TaskAccepted", + "type": "object" + } + }, + "additionalProperties": true, + "properties": { + "batch_id": { + "default": "", + "title": "Batch Id", + "type": "string" + }, + "items": { + "items": { + "$ref": "#/$defs/TaskAccepted" + }, + "title": "Items", + "type": "array" + } + }, + "title": "BatchAccepted", + "type": "object" + }, + "BatchItemResult:serialization": { + "$defs": { + "Assessment": { + "additionalProperties": true, + "description": "One reviewer's structured assessment.\n\nCurrent verifications carry three reviewers, ``Reviewer A`` to\n``Reviewer C``, all running the same checks over the evidence, plus\n``Reviewer D`` and ``Reviewer E`` when those three disagree. Their\n``focus_area`` reads ``\"Sources, evidence fit and wording\"``, and\n``warnings`` holds the source issues, evidence gaps and precision issues\nthat reviewer found, in one list.\n\nOlder verifications carry specialist panelists instead, one warning\ncategory each: logical fallacies (Logic Examiner), precision issues\n(Precision Analyst), weakest sources (Source Auditor) and, before\n2026-06, missing context (Context Analyst).\n\n``panelist_name`` is a display value, not a stable key \u2014 don't branch\non it. ``score`` is a reviewer-level 1-10 sub-score, distinct from the\ntop-level ``lenz_score`` on a ``Verification``.", + "properties": { + "focus_area": { + "default": "", + "title": "Focus Area", + "type": "string" + }, + "panelist_name": { + "default": "", + "title": "Panelist Name", + "type": "string" + }, + "reasoning": { + "default": "", + "title": "Reasoning", + "type": "string" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Score" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Assessment", + "type": "object" + }, + "Audit": { + "additionalProperties": true, + "description": "Nested explainability block \u2014 for callers who want the panel's work.", + "properties": { + "adjudication_summary": { + "default": "", + "title": "Adjudication Summary", + "type": "string" + }, + "assessments": { + "items": { + "$ref": "#/$defs/Assessment" + }, + "title": "Assessments", + "type": "array" + }, + "debate_con": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "debate_pro": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "panel_agreement": { + "default": "", + "title": "Panel Agreement", + "type": "string" + } + }, + "title": "Audit", + "type": "object" + }, + "CandidateClaim": { + "additionalProperties": true, + "description": "One of multiple distinct claims framing found in the submitted text.", + "properties": { + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "CandidateClaim", + "type": "object" + }, + "Coverage": { + "additionalProperties": true, + "description": "Whether this verdict carries Lenz's warranty, for YOUR account.\n\nPresent only when covered verification is enabled on the account's plan;\n``None`` otherwise. It describes the pair (your account, this analysis),\nnot the analysis alone \u2014 two accounts can hold two certificates over one\ncached verdict, so the block you see is never another customer's.\n\n``reasons`` is empty exactly when ``status`` is not ``\"uncovered\"``.\n\nThe money fields are three, not two: ``currency`` is ISO 4217 and the\namounts are integers in **major units** \u2014 ``cap=10000`` means ten\nthousand, not a hundred. They are contract figures, not amounts a payment\nprocessor charges. Read ``currency``; do not assume EUR.", + "properties": { + "aggregate": { + "default": 0, + "title": "Aggregate", + "type": "integer" + }, + "as_of": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "As Of" + }, + "cap": { + "default": 0, + "title": "Cap", + "type": "integer" + }, + "certificate_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Certificate Id" + }, + "certificate_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Certificate Url" + }, + "currency": { + "default": "", + "title": "Currency", + "type": "string" + }, + "reasons": { + "items": { + "type": "string" + }, + "title": "Reasons", + "type": "array" + }, + "status": { + "default": "uncovered", + "title": "Status", + "type": "string" + }, + "terms_version": { + "default": "", + "title": "Terms Version", + "type": "string" + } + }, + "title": "Coverage", + "type": "object" + }, + "DebateSide": { + "additionalProperties": true, + "description": "One side of the adversarial debate transcript.", + "properties": { + "argument": { + "default": "", + "title": "Argument", + "type": "string" + }, + "rebuttal": { + "default": "", + "title": "Rebuttal", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "DebateSide", + "type": "object" + }, + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + }, + "Progress": { + "additionalProperties": true, + "description": "Where a running verification has got to. Advisory \u2014 never results.\n\n``step`` is one of ``starting`` / ``framing`` / ``research`` / ``debate``\n/ ``adjudication`` / ``conclusion``. ``index`` is the 1-based stage\nposition (0 while ``starting``) out of ``total``; read ``total`` off the\nresponse rather than hard-coding it. ``poll_after_seconds`` is how long\nto wait before looking again \u2014 :meth:`Lenz.verify_and_wait` honours it\nfor you. ``elapsed_seconds`` is how long the run has been going, a\nmeasurement rather than an estimate of what is left.\n\n``index`` is stage POSITION, not elapsed work: the stages are uneven, so\na bar driven by it sits on ``research`` for roughly half the run.\n\n``step`` stays a plain ``str``, not a ``Literal`` \u2014 an SDK that\nhard-rejects a stage name the server adds later is worse than one that\npasses it through.\n\nThis was a plain ``dict`` up to 2.10.0. The mapping methods below keep\n``p[\"step\"]``, ``\"step\" in p``, ``p.keys()`` and ``dict(p)`` working on a\n2.x minor; they are deprecated and go in 3.0.0. Use attributes.", + "properties": { + "elapsed_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Elapsed Seconds" + }, + "index": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Index" + }, + "poll_after_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Poll After Seconds" + }, + "step": { + "default": "", + "title": "Step", + "type": "string" + }, + "total": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Total" + } + }, + "title": "Progress", + "type": "object" + }, + "SimilarVerification": { + "additionalProperties": true, + "description": "An existing public verification that semantically resembles the submitted text.\n\nSame vocabulary as ``Verification`` \u2014 flat ``verdict`` / ``confidence`` /\n``lenz_score`` at top level, no nested ``Verdict`` object.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "distance": { + "default": 0.0, + "title": "Distance", + "type": "number" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "SimilarVerification", + "type": "object" + }, + "Source": { + "additionalProperties": true, + "description": "A single citation backing a verification.", + "properties": { + "date": { + "default": "", + "title": "Date", + "type": "string" + }, + "snippet": { + "default": "", + "title": "Snippet", + "type": "string" + }, + "source_name": { + "default": "", + "title": "Source Name", + "type": "string" + }, + "title": { + "default": "", + "title": "Title", + "type": "string" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + } + }, + "title": "Source", + "type": "object" + }, + "TaskStatus": { + "additionalProperties": true, + "description": "Returned by ``GET /verify/status/{task_id}``.", + "properties": { + "candidates": { + "deprecated": true, + "items": { + "type": "string" + }, + "title": "Candidates", + "type": "array" + }, + "claims": { + "items": { + "$ref": "#/$defs/CandidateClaim" + }, + "title": "Claims", + "type": "array" + }, + "docs_url": { + "default": "", + "title": "Docs Url", + "type": "string" + }, + "error": { + "default": "", + "title": "Error", + "type": "string" + }, + "failure_class": { + "default": "", + "title": "Failure Class", + "type": "string" + }, + "failure_detail": { + "default": "", + "title": "Failure Detail", + "type": "string" + }, + "failure_reason": { + "default": "", + "title": "Failure Reason", + "type": "string" + }, + "hint": { + "default": "", + "title": "Hint", + "type": "string" + }, + "progress": { + "$ref": "#/$defs/Progress" + }, + "reason": { + "default": "", + "title": "Reason", + "type": "string" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/Verification" + }, + { + "type": "null" + } + ], + "default": null + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + }, + "similar_claims": { + "deprecated": true, + "items": { + "$ref": "#/$defs/SimilarVerification" + }, + "title": "Similar Claims", + "type": "array" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "task_id": { + "default": "", + "title": "Task Id", + "type": "string" + } + }, + "title": "TaskStatus", + "type": "object" + }, + "Verification": { + "additionalProperties": true, + "description": "Full verification report \u2014 returned by ``verify_and_wait``,\n``verifications.get``, the ``/verify/status/{task_id}`` polling\nendpoint, and the webhook payload.\n\nThe verdict block is FLAT at top level (was nested ``Verdict`` object\npre-unify). ``created_at`` + ``modified_at`` are the only timestamp\nfields on the API surface \u2014 editorial ``published_at`` is internal-only.\n\n1.1.0: dropped ``url`` and ``visibility``. API claims are private by\ndefault and referenced by ``verification_id`` only. Cache-hit on\nanother customer's claim is transparent \u2014 the customer always sees\ntheir own ``verification_id``, never another customer's.\n\nLater: ``visibility`` returns \u2014 'private' | 'unlisted' | 'public'. It\nechoes what you set on submit ('private'/'unlisted' are settable;\n'public' can only be read, for listed claims). ``url`` stays dropped.", + "properties": { + "audit": { + "$ref": "#/$defs/Audit" + }, + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "coverage": { + "anyOf": [ + { + "$ref": "#/$defs/Coverage" + }, + { + "type": "null" + } + ], + "default": null + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "depth": { + "default": "", + "title": "Depth", + "type": "string" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "presumed_intent": { + "default": "", + "title": "Presumed Intent", + "type": "string" + }, + "sources": { + "items": { + "$ref": "#/$defs/Source" + }, + "title": "Sources", + "type": "array" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + }, + "visibility": { + "default": "", + "title": "Visibility", + "type": "string" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Verification", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Per-item outcome from :meth:`Lenz.verify_batch_and_wait`.\n\nA client-side composition type \u2014 NOT a wire shape (the server never emits\nit, so it has no contract fixture). One entry per task that\n``POST /verify/batch`` returned, in input order.\n\n``status`` is a client-side rollup:\n\n- ``completed`` \u2014 ``verification`` is set (and ``status_detail`` carries the raw poll).\n- ``needs_input`` \u2014 paused for caller input; inspect ``status_detail`` (reason / claims).\n- ``failed`` \u2014 terminal failure (or completed-without-result); ``status_detail`` carries the diagnostic.\n A verification removed by its account's retention period (HTTP 410) is ``failed``, ``status_detail`` ``None``.\n- ``timeout`` \u2014 the deadline elapsed before this task reached a terminal state; ``status_detail`` is ``None``.", + "properties": { + "claim_text": { + "default": "", + "title": "Claim Text", + "type": "string" + }, + "status": { + "enum": [ + "completed", + "needs_input", + "failed", + "timeout" + ], + "title": "Status", + "type": "string" + }, + "status_detail": { + "anyOf": [ + { + "$ref": "#/$defs/TaskStatus" + }, + { + "type": "null" + } + ], + "default": null + }, + "task_id": { + "default": "", + "title": "Task Id", + "type": "string" + }, + "verification": { + "anyOf": [ + { + "$ref": "#/$defs/Verification" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "status" + ], + "title": "BatchItemResult", + "type": "object" + }, + "BatchItemResult:validation": { + "$defs": { + "Assessment": { + "additionalProperties": true, + "description": "One reviewer's structured assessment.\n\nCurrent verifications carry three reviewers, ``Reviewer A`` to\n``Reviewer C``, all running the same checks over the evidence, plus\n``Reviewer D`` and ``Reviewer E`` when those three disagree. Their\n``focus_area`` reads ``\"Sources, evidence fit and wording\"``, and\n``warnings`` holds the source issues, evidence gaps and precision issues\nthat reviewer found, in one list.\n\nOlder verifications carry specialist panelists instead, one warning\ncategory each: logical fallacies (Logic Examiner), precision issues\n(Precision Analyst), weakest sources (Source Auditor) and, before\n2026-06, missing context (Context Analyst).\n\n``panelist_name`` is a display value, not a stable key \u2014 don't branch\non it. ``score`` is a reviewer-level 1-10 sub-score, distinct from the\ntop-level ``lenz_score`` on a ``Verification``.", + "properties": { + "focus_area": { + "default": "", + "title": "Focus Area", + "type": "string" + }, + "panelist_name": { + "default": "", + "title": "Panelist Name", + "type": "string" + }, + "reasoning": { + "default": "", + "title": "Reasoning", + "type": "string" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Score" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Assessment", + "type": "object" + }, + "Audit": { + "additionalProperties": true, + "description": "Nested explainability block \u2014 for callers who want the panel's work.", + "properties": { + "adjudication_summary": { + "default": "", + "title": "Adjudication Summary", + "type": "string" + }, + "assessments": { + "items": { + "$ref": "#/$defs/Assessment" + }, + "title": "Assessments", + "type": "array" + }, + "debate_con": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "debate_pro": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "panel_agreement": { + "default": "", + "title": "Panel Agreement", + "type": "string" + } + }, + "title": "Audit", + "type": "object" + }, + "CandidateClaim": { + "additionalProperties": true, + "description": "One of multiple distinct claims framing found in the submitted text.", + "properties": { + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "CandidateClaim", + "type": "object" + }, + "Coverage": { + "additionalProperties": true, + "description": "Whether this verdict carries Lenz's warranty, for YOUR account.\n\nPresent only when covered verification is enabled on the account's plan;\n``None`` otherwise. It describes the pair (your account, this analysis),\nnot the analysis alone \u2014 two accounts can hold two certificates over one\ncached verdict, so the block you see is never another customer's.\n\n``reasons`` is empty exactly when ``status`` is not ``\"uncovered\"``.\n\nThe money fields are three, not two: ``currency`` is ISO 4217 and the\namounts are integers in **major units** \u2014 ``cap=10000`` means ten\nthousand, not a hundred. They are contract figures, not amounts a payment\nprocessor charges. Read ``currency``; do not assume EUR.", + "properties": { + "aggregate": { + "default": 0, + "title": "Aggregate", + "type": "integer" + }, + "as_of": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "As Of" + }, + "cap": { + "default": 0, + "title": "Cap", + "type": "integer" + }, + "certificate_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Certificate Id" + }, + "certificate_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Certificate Url" + }, + "currency": { + "default": "", + "title": "Currency", + "type": "string" + }, + "reasons": { + "items": { + "type": "string" + }, + "title": "Reasons", + "type": "array" + }, + "status": { + "default": "uncovered", + "title": "Status", + "type": "string" + }, + "terms_version": { + "default": "", + "title": "Terms Version", + "type": "string" + } + }, + "title": "Coverage", + "type": "object" + }, + "DebateSide": { + "additionalProperties": true, + "description": "One side of the adversarial debate transcript.", + "properties": { + "argument": { + "default": "", + "title": "Argument", + "type": "string" + }, + "rebuttal": { + "default": "", + "title": "Rebuttal", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "DebateSide", + "type": "object" + }, + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + }, + "Progress": { + "additionalProperties": true, + "description": "Where a running verification has got to. Advisory \u2014 never results.\n\n``step`` is one of ``starting`` / ``framing`` / ``research`` / ``debate``\n/ ``adjudication`` / ``conclusion``. ``index`` is the 1-based stage\nposition (0 while ``starting``) out of ``total``; read ``total`` off the\nresponse rather than hard-coding it. ``poll_after_seconds`` is how long\nto wait before looking again \u2014 :meth:`Lenz.verify_and_wait` honours it\nfor you. ``elapsed_seconds`` is how long the run has been going, a\nmeasurement rather than an estimate of what is left.\n\n``index`` is stage POSITION, not elapsed work: the stages are uneven, so\na bar driven by it sits on ``research`` for roughly half the run.\n\n``step`` stays a plain ``str``, not a ``Literal`` \u2014 an SDK that\nhard-rejects a stage name the server adds later is worse than one that\npasses it through.\n\nThis was a plain ``dict`` up to 2.10.0. The mapping methods below keep\n``p[\"step\"]``, ``\"step\" in p``, ``p.keys()`` and ``dict(p)`` working on a\n2.x minor; they are deprecated and go in 3.0.0. Use attributes.", + "properties": { + "elapsed_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Elapsed Seconds" + }, + "index": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Index" + }, + "poll_after_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Poll After Seconds" + }, + "step": { + "default": "", + "title": "Step", + "type": "string" + }, + "total": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Total" + } + }, + "title": "Progress", + "type": "object" + }, + "SimilarVerification": { + "additionalProperties": true, + "description": "An existing public verification that semantically resembles the submitted text.\n\nSame vocabulary as ``Verification`` \u2014 flat ``verdict`` / ``confidence`` /\n``lenz_score`` at top level, no nested ``Verdict`` object.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "distance": { + "default": 0.0, + "title": "Distance", + "type": "number" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "SimilarVerification", + "type": "object" + }, + "Source": { + "additionalProperties": true, + "description": "A single citation backing a verification.", + "properties": { + "date": { + "default": "", + "title": "Date", + "type": "string" + }, + "snippet": { + "default": "", + "title": "Snippet", + "type": "string" + }, + "source_name": { + "default": "", + "title": "Source Name", + "type": "string" + }, + "title": { + "default": "", + "title": "Title", + "type": "string" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + } + }, + "title": "Source", + "type": "object" + }, + "TaskStatus": { + "additionalProperties": true, + "description": "Returned by ``GET /verify/status/{task_id}``.", + "properties": { + "candidates": { + "deprecated": true, + "items": { + "type": "string" + }, + "title": "Candidates", + "type": "array" + }, + "claims": { + "items": { + "$ref": "#/$defs/CandidateClaim" + }, + "title": "Claims", + "type": "array" + }, + "docs_url": { + "default": "", + "title": "Docs Url", + "type": "string" + }, + "error": { + "default": "", + "title": "Error", + "type": "string" + }, + "failure_class": { + "default": "", + "title": "Failure Class", + "type": "string" + }, + "failure_detail": { + "default": "", + "title": "Failure Detail", + "type": "string" + }, + "failure_reason": { + "default": "", + "title": "Failure Reason", + "type": "string" + }, + "hint": { + "default": "", + "title": "Hint", + "type": "string" + }, + "progress": { + "$ref": "#/$defs/Progress" + }, + "reason": { + "default": "", + "title": "Reason", + "type": "string" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/Verification" + }, + { + "type": "null" + } + ], + "default": null + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + }, + "similar_claims": { + "deprecated": true, + "items": { + "$ref": "#/$defs/SimilarVerification" + }, + "title": "Similar Claims", + "type": "array" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "task_id": { + "default": "", + "title": "Task Id", + "type": "string" + } + }, + "title": "TaskStatus", + "type": "object" + }, + "Verification": { + "additionalProperties": true, + "description": "Full verification report \u2014 returned by ``verify_and_wait``,\n``verifications.get``, the ``/verify/status/{task_id}`` polling\nendpoint, and the webhook payload.\n\nThe verdict block is FLAT at top level (was nested ``Verdict`` object\npre-unify). ``created_at`` + ``modified_at`` are the only timestamp\nfields on the API surface \u2014 editorial ``published_at`` is internal-only.\n\n1.1.0: dropped ``url`` and ``visibility``. API claims are private by\ndefault and referenced by ``verification_id`` only. Cache-hit on\nanother customer's claim is transparent \u2014 the customer always sees\ntheir own ``verification_id``, never another customer's.\n\nLater: ``visibility`` returns \u2014 'private' | 'unlisted' | 'public'. It\nechoes what you set on submit ('private'/'unlisted' are settable;\n'public' can only be read, for listed claims). ``url`` stays dropped.", + "properties": { + "audit": { + "$ref": "#/$defs/Audit" + }, + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "coverage": { + "anyOf": [ + { + "$ref": "#/$defs/Coverage" + }, + { + "type": "null" + } + ], + "default": null + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "depth": { + "default": "", + "title": "Depth", + "type": "string" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "presumed_intent": { + "default": "", + "title": "Presumed Intent", + "type": "string" + }, + "sources": { + "items": { + "$ref": "#/$defs/Source" + }, + "title": "Sources", + "type": "array" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + }, + "visibility": { + "default": "", + "title": "Visibility", + "type": "string" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Verification", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Per-item outcome from :meth:`Lenz.verify_batch_and_wait`.\n\nA client-side composition type \u2014 NOT a wire shape (the server never emits\nit, so it has no contract fixture). One entry per task that\n``POST /verify/batch`` returned, in input order.\n\n``status`` is a client-side rollup:\n\n- ``completed`` \u2014 ``verification`` is set (and ``status_detail`` carries the raw poll).\n- ``needs_input`` \u2014 paused for caller input; inspect ``status_detail`` (reason / claims).\n- ``failed`` \u2014 terminal failure (or completed-without-result); ``status_detail`` carries the diagnostic.\n A verification removed by its account's retention period (HTTP 410) is ``failed``, ``status_detail`` ``None``.\n- ``timeout`` \u2014 the deadline elapsed before this task reached a terminal state; ``status_detail`` is ``None``.", + "properties": { + "claim_text": { + "default": "", + "title": "Claim Text", + "type": "string" + }, + "status": { + "enum": [ + "completed", + "needs_input", + "failed", + "timeout" + ], + "title": "Status", + "type": "string" + }, + "status_detail": { + "anyOf": [ + { + "$ref": "#/$defs/TaskStatus" + }, + { + "type": "null" + } + ], + "default": null + }, + "task_id": { + "default": "", + "title": "Task Id", + "type": "string" + }, + "verification": { + "anyOf": [ + { + "$ref": "#/$defs/Verification" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "required": [ + "status" + ], + "title": "BatchItemResult", + "type": "object" + }, + "CandidateClaim:serialization": { + "additionalProperties": true, + "description": "One of multiple distinct claims framing found in the submitted text.", + "properties": { + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "CandidateClaim", + "type": "object" + }, + "CandidateClaim:validation": { + "additionalProperties": true, + "description": "One of multiple distinct claims framing found in the submitted text.", + "properties": { + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "CandidateClaim", + "type": "object" + }, + "Citecheck:serialization": { + "$defs": { + "CitecheckPolicy": { + "additionalProperties": true, + "description": "``max_citations``: how many citations are checked (for pairs, the\nnumber of pairs: every pair is checked).", + "properties": { + "max_citations": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max Citations" + } + }, + "title": "CitecheckPolicy", + "type": "object" + }, + "CitecheckSummary": { + "additionalProperties": true, + "description": "Counts over the check, as on a review's ``summary``. ``citations_found``\nis the citations in the text, or the pairs sent; ``None`` until read.", + "properties": { + "citation_checks": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationCheckCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_issues": { + "default": 0, + "title": "Citation Issues", + "type": "integer" + }, + "citation_limit": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit" + }, + "citation_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit Reached" + }, + "citations_found": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Found" + }, + "citations_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Selected" + } + }, + "title": "CitecheckSummary", + "type": "object" + }, + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewCitation": { + "additionalProperties": true, + "description": "One citation of the draft (a URL or a DOI where the draft uses it), in\nthe draft's order. Only on a review that asked for the citation check.\n\n``reference`` is the citation as the draft writes it; ``statement`` the\ndraft's sentence it is attached to, with link syntax reduced to its\nwords; ``quotes`` the words the draft quotes from this source.\n``position`` locates ``statement`` in the text as sent (its ``text`` is\n``None``: the row carries the ``statement``). ``result`` is\n``None`` until the check has ended, and on a failed row with nothing\nestablished.", + "properties": { + "check": { + "$ref": "#/$defs/ReviewCitationCheck" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationResult" + }, + { + "type": "null" + } + ], + "default": null + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitation", + "type": "object" + }, + "ReviewCitationCheck": { + "additionalProperties": true, + "description": "A citation's check. ``status`` is progress, as on ``assessment``:\n``pending`` | ``running`` | ``completed`` | ``failed``.\n\n- ``page_read``: ``full``, ``partial``, ``not_found`` or ``none``.\n- ``source_url``: where the text was actually read from (after\n redirects, or a free copy of a paper). ``source_version``, for a DOI:\n ``published``, ``accepted`` or ``submitted``.\n- ``support``: ``supported``, ``partly_supported``, ``contradicted``,\n ``not_in_source`` or ``unchecked``. ``snippet`` is the verified passage\n of the source it rests on; ``rationale`` is a reviewer's note, not a\n checked source.\n- ``quote``: ``matched``, ``not_in_source`` or ``unchecked``; ``None``\n when the draft quoted nothing from this source. ``missing_quote`` is\n the quoted excerpt the quote check did not find; ``None`` unless\n ``quote`` is ``not_in_source``.\n- ``doi_registered``, ``metadata`` (``consistent``, ``mismatch`` or\n ``unchecked``), ``metadata_differences`` and ``registered``: set for a\n DOI only.\n- ``unchecked_reason`` and ``hint``: why the finding is ``unchecked`` and\n what to do next. The reasons are an open set, e.g. ``no_text``,\n ``partial_text``, ``login_required``, ``unsupported_site``,\n ``no_statement``, ``invalid_url``, ``other_version``, ``inconclusive``,\n ``ambiguous_reference``.\n- ``failure``: on a ``failed`` check.", + "properties": { + "doi_registered": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi Registered" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "metadata": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Metadata" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Language" + }, + "page_published_date": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Published Date" + }, + "page_read": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Read" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Quote" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "registered": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationRecord" + }, + { + "type": "null" + } + ], + "default": null + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Url" + }, + "source_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Version" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "support": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Support" + }, + "unchecked_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Unchecked Reason" + } + }, + "title": "ReviewCitationCheck", + "type": "object" + }, + "ReviewCitationCheckCounts": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationFailure": { + "additionalProperties": true, + "description": "A citation whose check failed with nothing established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + } + }, + "title": "ReviewCitationFailure", + "type": "object" + }, + "ReviewCitationIssue": { + "additionalProperties": true, + "description": "A citation whose finding is an issue (see ``ReviewCitationResult``);\nmost serious first, then in the draft's order.\n\n``snippet`` and ``rationale`` are set only when ``source`` is\n``support``. On ``quote_not_in_source``, ``missing_quote`` is the quoted\nexcerpt that was not found. On ``metadata_mismatch``,\n``metadata_differences`` says what differs. ``failure`` is set when another part of the check failed after\nthe finding was established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitationIssue", + "type": "object" + }, + "ReviewCitationRecord": { + "additionalProperties": true, + "description": "A DOI's record in the registry.", + "properties": { + "authors": { + "items": { + "type": "string" + }, + "title": "Authors", + "type": "array" + }, + "journal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Journal" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Title" + }, + "year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Year" + } + }, + "title": "ReviewCitationRecord", + "type": "object" + }, + "ReviewCitationResult": { + "additionalProperties": true, + "description": "The one answer to read for a citation, derived from its ``check``.\n\n``finding``, most serious first: ``doi_not_found``, ``page_not_found``,\n``contradicted``, ``quote_not_in_source``, ``not_in_source``,\n``partly_supported``, ``metadata_mismatch`` (each an issue), then\n``supported`` and ``unchecked``. ``source`` says which check the finding\ncame from: ``doi``, ``page``, ``support``, ``quote`` or ``metadata``;\n``None`` on ``unchecked``.", + "properties": { + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + } + }, + "title": "ReviewCitationResult", + "type": "object" + }, + "ReviewCredits": { + "additionalProperties": true, + "description": "``charged`` is the net credits the review cost the account, its\ncitation checks included. It is final once no deep check or citation\ncheck is running: read it at ``completed``.", + "properties": { + "charged": { + "default": 0, + "title": "Charged", + "type": "integer" + } + }, + "title": "ReviewCredits", + "type": "object" + }, + "ReviewMoreCitation": { + "additionalProperties": true, + "description": "A citation found in the draft past the ones this review checked:\nfound but not checked. Send it in a later request to check it.\n``sentence`` is the draft's sentence around it.", + "properties": { + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Sentence" + } + }, + "title": "ReviewMoreCitation", + "type": "object" + } + }, + "additionalProperties": true, + "description": "``GET /citechecks/{citecheck_id}``: a citation check as it stands.\n\n``status``: ``queued`` \u2192 ``checking`` \u2192 ``completed``, or ``failed``.\n``outcome`` is ``None`` until it ends, then ``clean``, ``issues_found``,\n``incomplete`` (a citation could not be checked for a reason of ours) or\n``unchecked``. ``citations``, ``citation_issues`` and ``citation_failures``\nare the review's rows. ``more_citations`` lists the citations of the text\npast the ones checked; ``None`` until the text is read, ``[]`` for pairs.", + "properties": { + "citation_failures": { + "items": { + "$ref": "#/$defs/ReviewCitationFailure" + }, + "title": "Citation Failures", + "type": "array" + }, + "citation_issues": { + "items": { + "$ref": "#/$defs/ReviewCitationIssue" + }, + "title": "Citation Issues", + "type": "array" + }, + "citations": { + "items": { + "$ref": "#/$defs/ReviewCitation" + }, + "title": "Citations", + "type": "array" + }, + "citecheck_id": { + "default": "", + "title": "Citecheck Id", + "type": "string" + }, + "completed_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Completed At" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "credits": { + "$ref": "#/$defs/ReviewCredits" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "more_citations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ReviewMoreCitation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Citations" + }, + "outcome": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Outcome" + }, + "policy": { + "$ref": "#/$defs/CitecheckPolicy" + }, + "poll_after_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Poll After Seconds" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "summary": { + "$ref": "#/$defs/CitecheckSummary" + } + }, + "title": "Citecheck", + "type": "object" + }, + "Citecheck:validation": { + "$defs": { + "CitecheckPolicy": { + "additionalProperties": true, + "description": "``max_citations``: how many citations are checked (for pairs, the\nnumber of pairs: every pair is checked).", + "properties": { + "max_citations": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max Citations" + } + }, + "title": "CitecheckPolicy", + "type": "object" + }, + "CitecheckSummary": { + "additionalProperties": true, + "description": "Counts over the check, as on a review's ``summary``. ``citations_found``\nis the citations in the text, or the pairs sent; ``None`` until read.", + "properties": { + "citation_checks": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationCheckCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_issues": { + "default": 0, + "title": "Citation Issues", + "type": "integer" + }, + "citation_limit": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit" + }, + "citation_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit Reached" + }, + "citations_found": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Found" + }, + "citations_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Selected" + } + }, + "title": "CitecheckSummary", + "type": "object" + }, + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewCitation": { + "additionalProperties": true, + "description": "One citation of the draft (a URL or a DOI where the draft uses it), in\nthe draft's order. Only on a review that asked for the citation check.\n\n``reference`` is the citation as the draft writes it; ``statement`` the\ndraft's sentence it is attached to, with link syntax reduced to its\nwords; ``quotes`` the words the draft quotes from this source.\n``position`` locates ``statement`` in the text as sent (its ``text`` is\n``None``: the row carries the ``statement``). ``result`` is\n``None`` until the check has ended, and on a failed row with nothing\nestablished.", + "properties": { + "check": { + "$ref": "#/$defs/ReviewCitationCheck" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationResult" + }, + { + "type": "null" + } + ], + "default": null + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitation", + "type": "object" + }, + "ReviewCitationCheck": { + "additionalProperties": true, + "description": "A citation's check. ``status`` is progress, as on ``assessment``:\n``pending`` | ``running`` | ``completed`` | ``failed``.\n\n- ``page_read``: ``full``, ``partial``, ``not_found`` or ``none``.\n- ``source_url``: where the text was actually read from (after\n redirects, or a free copy of a paper). ``source_version``, for a DOI:\n ``published``, ``accepted`` or ``submitted``.\n- ``support``: ``supported``, ``partly_supported``, ``contradicted``,\n ``not_in_source`` or ``unchecked``. ``snippet`` is the verified passage\n of the source it rests on; ``rationale`` is a reviewer's note, not a\n checked source.\n- ``quote``: ``matched``, ``not_in_source`` or ``unchecked``; ``None``\n when the draft quoted nothing from this source. ``missing_quote`` is\n the quoted excerpt the quote check did not find; ``None`` unless\n ``quote`` is ``not_in_source``.\n- ``doi_registered``, ``metadata`` (``consistent``, ``mismatch`` or\n ``unchecked``), ``metadata_differences`` and ``registered``: set for a\n DOI only.\n- ``unchecked_reason`` and ``hint``: why the finding is ``unchecked`` and\n what to do next. The reasons are an open set, e.g. ``no_text``,\n ``partial_text``, ``login_required``, ``unsupported_site``,\n ``no_statement``, ``invalid_url``, ``other_version``, ``inconclusive``,\n ``ambiguous_reference``.\n- ``failure``: on a ``failed`` check.", + "properties": { + "doi_registered": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi Registered" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "metadata": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Metadata" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Language" + }, + "page_published_date": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Published Date" + }, + "page_read": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Read" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Quote" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "registered": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationRecord" + }, + { + "type": "null" + } + ], + "default": null + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Url" + }, + "source_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Version" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "support": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Support" + }, + "unchecked_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Unchecked Reason" + } + }, + "title": "ReviewCitationCheck", + "type": "object" + }, + "ReviewCitationCheckCounts": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationFailure": { + "additionalProperties": true, + "description": "A citation whose check failed with nothing established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + } + }, + "title": "ReviewCitationFailure", + "type": "object" + }, + "ReviewCitationIssue": { + "additionalProperties": true, + "description": "A citation whose finding is an issue (see ``ReviewCitationResult``);\nmost serious first, then in the draft's order.\n\n``snippet`` and ``rationale`` are set only when ``source`` is\n``support``. On ``quote_not_in_source``, ``missing_quote`` is the quoted\nexcerpt that was not found. On ``metadata_mismatch``,\n``metadata_differences`` says what differs. ``failure`` is set when another part of the check failed after\nthe finding was established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitationIssue", + "type": "object" + }, + "ReviewCitationRecord": { + "additionalProperties": true, + "description": "A DOI's record in the registry.", + "properties": { + "authors": { + "items": { + "type": "string" + }, + "title": "Authors", + "type": "array" + }, + "journal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Journal" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Title" + }, + "year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Year" + } + }, + "title": "ReviewCitationRecord", + "type": "object" + }, + "ReviewCitationResult": { + "additionalProperties": true, + "description": "The one answer to read for a citation, derived from its ``check``.\n\n``finding``, most serious first: ``doi_not_found``, ``page_not_found``,\n``contradicted``, ``quote_not_in_source``, ``not_in_source``,\n``partly_supported``, ``metadata_mismatch`` (each an issue), then\n``supported`` and ``unchecked``. ``source`` says which check the finding\ncame from: ``doi``, ``page``, ``support``, ``quote`` or ``metadata``;\n``None`` on ``unchecked``.", + "properties": { + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + } + }, + "title": "ReviewCitationResult", + "type": "object" + }, + "ReviewCredits": { + "additionalProperties": true, + "description": "``charged`` is the net credits the review cost the account, its\ncitation checks included. It is final once no deep check or citation\ncheck is running: read it at ``completed``.", + "properties": { + "charged": { + "default": 0, + "title": "Charged", + "type": "integer" + } + }, + "title": "ReviewCredits", + "type": "object" + }, + "ReviewMoreCitation": { + "additionalProperties": true, + "description": "A citation found in the draft past the ones this review checked:\nfound but not checked. Send it in a later request to check it.\n``sentence`` is the draft's sentence around it.", + "properties": { + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Sentence" + } + }, + "title": "ReviewMoreCitation", + "type": "object" + } + }, + "additionalProperties": true, + "description": "``GET /citechecks/{citecheck_id}``: a citation check as it stands.\n\n``status``: ``queued`` \u2192 ``checking`` \u2192 ``completed``, or ``failed``.\n``outcome`` is ``None`` until it ends, then ``clean``, ``issues_found``,\n``incomplete`` (a citation could not be checked for a reason of ours) or\n``unchecked``. ``citations``, ``citation_issues`` and ``citation_failures``\nare the review's rows. ``more_citations`` lists the citations of the text\npast the ones checked; ``None`` until the text is read, ``[]`` for pairs.", + "properties": { + "citation_failures": { + "items": { + "$ref": "#/$defs/ReviewCitationFailure" + }, + "title": "Citation Failures", + "type": "array" + }, + "citation_issues": { + "items": { + "$ref": "#/$defs/ReviewCitationIssue" + }, + "title": "Citation Issues", + "type": "array" + }, + "citations": { + "items": { + "$ref": "#/$defs/ReviewCitation" + }, + "title": "Citations", + "type": "array" + }, + "citecheck_id": { + "default": "", + "title": "Citecheck Id", + "type": "string" + }, + "completed_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Completed At" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "credits": { + "$ref": "#/$defs/ReviewCredits" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "more_citations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ReviewMoreCitation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Citations" + }, + "outcome": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Outcome" + }, + "policy": { + "$ref": "#/$defs/CitecheckPolicy" + }, + "poll_after_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Poll After Seconds" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "summary": { + "$ref": "#/$defs/CitecheckSummary" + } + }, + "title": "Citecheck", + "type": "object" + }, + "CitecheckPolicy:serialization": { + "additionalProperties": true, + "description": "``max_citations``: how many citations are checked (for pairs, the\nnumber of pairs: every pair is checked).", + "properties": { + "max_citations": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max Citations" + } + }, + "title": "CitecheckPolicy", + "type": "object" + }, + "CitecheckPolicy:validation": { + "additionalProperties": true, + "description": "``max_citations``: how many citations are checked (for pairs, the\nnumber of pairs: every pair is checked).", + "properties": { + "max_citations": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max Citations" + } + }, + "title": "CitecheckPolicy", + "type": "object" + }, + "CitecheckStarted:serialization": { + "additionalProperties": true, + "description": "Returned by ``POST /citecheck`` (HTTP 202). ``status`` is always\n``\"queued\"``: the receipt, not the current state.", + "properties": { + "citecheck_id": { + "default": "", + "title": "Citecheck Id", + "type": "string" + }, + "status": { + "default": "queued", + "title": "Status", + "type": "string" + } + }, + "title": "CitecheckStarted", + "type": "object" + }, + "CitecheckStarted:validation": { + "additionalProperties": true, + "description": "Returned by ``POST /citecheck`` (HTTP 202). ``status`` is always\n``\"queued\"``: the receipt, not the current state.", + "properties": { + "citecheck_id": { + "default": "", + "title": "Citecheck Id", + "type": "string" + }, + "status": { + "default": "queued", + "title": "Status", + "type": "string" + } + }, + "title": "CitecheckStarted", + "type": "object" + }, + "CitecheckSummary:serialization": { + "$defs": { + "ReviewCitationCheckCounts": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Counts over the check, as on a review's ``summary``. ``citations_found``\nis the citations in the text, or the pairs sent; ``None`` until read.", + "properties": { + "citation_checks": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationCheckCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_issues": { + "default": 0, + "title": "Citation Issues", + "type": "integer" + }, + "citation_limit": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit" + }, + "citation_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit Reached" + }, + "citations_found": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Found" + }, + "citations_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Selected" + } + }, + "title": "CitecheckSummary", + "type": "object" + }, + "CitecheckSummary:validation": { + "$defs": { + "ReviewCitationCheckCounts": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Counts over the check, as on a review's ``summary``. ``citations_found``\nis the citations in the text, or the pairs sent; ``None`` until read.", + "properties": { + "citation_checks": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationCheckCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_issues": { + "default": 0, + "title": "Citation Issues", + "type": "integer" + }, + "citation_limit": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit" + }, + "citation_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit Reached" + }, + "citations_found": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Found" + }, + "citations_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Selected" + } + }, + "title": "CitecheckSummary", + "type": "object" + }, + "ClaimLocation:serialization": { + "$defs": { + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Where the submitted text makes one claim.\n\n``claim`` is exactly as in the claim list it belongs to\n(``ExtractedClaims.claim`` / ``identified_claims``, or a review's\n``more_claims``). ``positions`` lists every place the text makes it, in\ntext order, at most 10. It is ``None`` only when that claim could not be\nplaced; on ``/extract`` every returned claim is placed.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + } + }, + "title": "ClaimLocation", + "type": "object" + }, + "ClaimLocation:validation": { + "$defs": { + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Where the submitted text makes one claim.\n\n``claim`` is exactly as in the claim list it belongs to\n(``ExtractedClaims.claim`` / ``identified_claims``, or a review's\n``more_claims``). ``positions`` lists every place the text makes it, in\ntext order, at most 10. It is ``None`` only when that claim could not be\nplaced; on ``/extract`` every returned claim is placed.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + } + }, + "title": "ClaimLocation", + "type": "object" + }, + "DebateSide:serialization": { + "additionalProperties": true, + "description": "One side of the adversarial debate transcript.", + "properties": { + "argument": { + "default": "", + "title": "Argument", + "type": "string" + }, + "rebuttal": { + "default": "", + "title": "Rebuttal", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "DebateSide", + "type": "object" + }, + "DebateSide:validation": { + "additionalProperties": true, + "description": "One side of the adversarial debate transcript.", + "properties": { + "argument": { + "default": "", + "title": "Argument", + "type": "string" + }, + "rebuttal": { + "default": "", + "title": "Rebuttal", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "DebateSide", + "type": "object" + }, + "EntityRef:serialization": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + }, + "EntityRef:validation": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + }, + "Escalation:serialization": { + "additionalProperties": true, + "description": "Why a claim was, or was not, deep-checked.\n\n``matched_rules`` lists the rules the quick check matched (``verdict``,\n``confidence``, both, or neither). ``disposition`` says what happened:\n``planned`` (deep-checked), ``not_selected`` (no rule matched), ``cap``\n(matched, but ``max_verifications`` was reached), ``credits`` (matched,\nbut the balance ran out) or ``account_cap`` (matched, but the account's\nallowance of concurrent deep checks was reached). To deep-check the\n``cap`` rows yourself, send their claims to ``verify_batch_and_wait``.", + "properties": { + "disposition": { + "default": "", + "title": "Disposition", + "type": "string" + }, + "matched_rules": { + "items": { + "type": "string" + }, + "title": "Matched Rules", + "type": "array" + } + }, + "title": "Escalation", + "type": "object" + }, + "Escalation:validation": { + "additionalProperties": true, + "description": "Why a claim was, or was not, deep-checked.\n\n``matched_rules`` lists the rules the quick check matched (``verdict``,\n``confidence``, both, or neither). ``disposition`` says what happened:\n``planned`` (deep-checked), ``not_selected`` (no rule matched), ``cap``\n(matched, but ``max_verifications`` was reached), ``credits`` (matched,\nbut the balance ran out) or ``account_cap`` (matched, but the account's\nallowance of concurrent deep checks was reached). To deep-check the\n``cap`` rows yourself, send their claims to ``verify_batch_and_wait``.", + "properties": { + "disposition": { + "default": "", + "title": "Disposition", + "type": "string" + }, + "matched_rules": { + "items": { + "type": "string" + }, + "title": "Matched Rules", + "type": "array" + } + }, + "title": "Escalation", + "type": "object" + }, + "EscalationPolicy:serialization": { + "additionalProperties": true, + "description": "Which quick-checked claims get a deep check, as the review RESOLVED it.\n\nA claim is deep-checked when its quick verdict is in ``verdicts`` OR its\nconfidence band is in ``confidence``, up to ``max_verifications`` of them,\nat ``depth``. ``max_assessments`` is how many of the draft's claims, most\ncheck-worthy first, got a quick verdict.", + "properties": { + "confidence": { + "items": { + "type": "string" + }, + "title": "Confidence", + "type": "array" + }, + "depth": { + "default": "standard", + "title": "Depth", + "type": "string" + }, + "max_assessments": { + "default": 20, + "title": "Max Assessments", + "type": "integer" + }, + "max_citations": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max Citations" + }, + "max_verifications": { + "default": 5, + "title": "Max Verifications", + "type": "integer" + }, + "suggest_edits": { + "default": false, + "title": "Suggest Edits", + "type": "boolean" + }, + "verdicts": { + "items": { + "type": "string" + }, + "title": "Verdicts", + "type": "array" + } + }, + "title": "EscalationPolicy", + "type": "object" + }, + "EscalationPolicy:validation": { + "additionalProperties": true, + "description": "Which quick-checked claims get a deep check, as the review RESOLVED it.\n\nA claim is deep-checked when its quick verdict is in ``verdicts`` OR its\nconfidence band is in ``confidence``, up to ``max_verifications`` of them,\nat ``depth``. ``max_assessments`` is how many of the draft's claims, most\ncheck-worthy first, got a quick verdict.", + "properties": { + "confidence": { + "items": { + "type": "string" + }, + "title": "Confidence", + "type": "array" + }, + "depth": { + "default": "standard", + "title": "Depth", + "type": "string" + }, + "max_assessments": { + "default": 20, + "title": "Max Assessments", + "type": "integer" + }, + "max_citations": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max Citations" + }, + "max_verifications": { + "default": 5, + "title": "Max Verifications", + "type": "integer" + }, + "suggest_edits": { + "default": false, + "title": "Suggest Edits", + "type": "boolean" + }, + "verdicts": { + "items": { + "type": "string" + }, + "title": "Verdicts", + "type": "array" + } + }, + "title": "EscalationPolicy", + "type": "object" + }, + "ExtractedClaims:serialization": { + "$defs": { + "ClaimLocation": { + "additionalProperties": true, + "description": "Where the submitted text makes one claim.\n\n``claim`` is exactly as in the claim list it belongs to\n(``ExtractedClaims.claim`` / ``identified_claims``, or a review's\n``more_claims``). ``positions`` lists every place the text makes it, in\ntext order, at most 10. It is ``None`` only when that claim could not be\nplaced; on ``/extract`` every returned claim is placed.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + } + }, + "title": "ClaimLocation", + "type": "object" + }, + "ExtractedEntity": { + "additionalProperties": true, + "description": "An entity surfaced by ``/extract``. ``type`` is the framing category\n(``person`` | ``org`` | ``place`` | ``topic``).", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "type": { + "default": "", + "title": "Type", + "type": "string" + } + }, + "title": "ExtractedEntity", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Output of ``POST /extract``.\n\n``status`` is one of ``ExtractStatus``: ``ready``, ``not_a_claim``, or \u2014\nwhen a ``focus`` was given and no claim fell within it \u2014 ``no_match``.\n``no_match`` is a successful answer, not an error: ``identified_claims``\nis empty and the unfocused list is never substituted for it.\n\n``locations`` is set only on a call made with ``locate=True``: one\n``ClaimLocation`` per returned claim, in the order of\n``identified_claims`` (one entry for a single ``claim``). It is ``[]``\nwhen every claim was left out (``status`` is then ``\"not_a_claim\"``),\nand ``None`` when ``locate`` was not set, when the extraction found no\nclaims, or when the\nclaims could not be located (the list is then returned unfiltered).\nOlder servers omit the key; it parses as ``None``.", + "properties": { + "candidate_claims": { + "deprecated": true, + "items": { + "type": "string" + }, + "title": "Candidate Claims", + "type": "array" + }, + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "identified_claims": { + "items": { + "type": "string" + }, + "title": "Identified Claims", + "type": "array" + }, + "key_entities": { + "items": { + "$ref": "#/$defs/ExtractedEntity" + }, + "title": "Key Entities", + "type": "array" + }, + "locations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ClaimLocation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Locations" + }, + "original_input": { + "default": "", + "title": "Original Input", + "type": "string" + }, + "presumed_intent": { + "default": "", + "title": "Presumed Intent", + "type": "string" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + } + }, + "title": "ExtractedClaims", + "type": "object" + }, + "ExtractedClaims:validation": { + "$defs": { + "ClaimLocation": { + "additionalProperties": true, + "description": "Where the submitted text makes one claim.\n\n``claim`` is exactly as in the claim list it belongs to\n(``ExtractedClaims.claim`` / ``identified_claims``, or a review's\n``more_claims``). ``positions`` lists every place the text makes it, in\ntext order, at most 10. It is ``None`` only when that claim could not be\nplaced; on ``/extract`` every returned claim is placed.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + } + }, + "title": "ClaimLocation", + "type": "object" + }, + "ExtractedEntity": { + "additionalProperties": true, + "description": "An entity surfaced by ``/extract``. ``type`` is the framing category\n(``person`` | ``org`` | ``place`` | ``topic``).", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "type": { + "default": "", + "title": "Type", + "type": "string" + } + }, + "title": "ExtractedEntity", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Output of ``POST /extract``.\n\n``status`` is one of ``ExtractStatus``: ``ready``, ``not_a_claim``, or \u2014\nwhen a ``focus`` was given and no claim fell within it \u2014 ``no_match``.\n``no_match`` is a successful answer, not an error: ``identified_claims``\nis empty and the unfocused list is never substituted for it.\n\n``locations`` is set only on a call made with ``locate=True``: one\n``ClaimLocation`` per returned claim, in the order of\n``identified_claims`` (one entry for a single ``claim``). It is ``[]``\nwhen every claim was left out (``status`` is then ``\"not_a_claim\"``),\nand ``None`` when ``locate`` was not set, when the extraction found no\nclaims, or when the\nclaims could not be located (the list is then returned unfiltered).\nOlder servers omit the key; it parses as ``None``.", + "properties": { + "candidate_claims": { + "deprecated": true, + "items": { + "type": "string" + }, + "title": "Candidate Claims", + "type": "array" + }, + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "identified_claims": { + "items": { + "type": "string" + }, + "title": "Identified Claims", + "type": "array" + }, + "key_entities": { + "items": { + "$ref": "#/$defs/ExtractedEntity" + }, + "title": "Key Entities", + "type": "array" + }, + "locations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ClaimLocation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Locations" + }, + "original_input": { + "default": "", + "title": "Original Input", + "type": "string" + }, + "presumed_intent": { + "default": "", + "title": "Presumed Intent", + "type": "string" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + } + }, + "title": "ExtractedClaims", + "type": "object" + }, + "ExtractedEntity:serialization": { + "additionalProperties": true, + "description": "An entity surfaced by ``/extract``. ``type`` is the framing category\n(``person`` | ``org`` | ``place`` | ``topic``).", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "type": { + "default": "", + "title": "Type", + "type": "string" + } + }, + "title": "ExtractedEntity", + "type": "object" + }, + "ExtractedEntity:validation": { + "additionalProperties": true, + "description": "An entity surfaced by ``/extract``. ``type`` is the framing category\n(``person`` | ``org`` | ``place`` | ``topic``).", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "type": { + "default": "", + "title": "Type", + "type": "string" + } + }, + "title": "ExtractedEntity", + "type": "object" + }, + "FailureBlock:serialization": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "FailureBlock:validation": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "LibraryItem:serialization": { + "$defs": { + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Same shape as VerificationListItem on the public Library list.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "LibraryItem", + "type": "object" + }, + "LibraryItem:validation": { + "$defs": { + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Same shape as VerificationListItem on the public Library list.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "LibraryItem", + "type": "object" + }, + "LibraryList:serialization": { + "$defs": { + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + }, + "LibraryItem": { + "additionalProperties": true, + "description": "Same shape as VerificationListItem on the public Library list.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "LibraryItem", + "type": "object" + } + }, + "additionalProperties": true, + "properties": { + "items": { + "items": { + "$ref": "#/$defs/LibraryItem" + }, + "title": "Items", + "type": "array" + }, + "page": { + "default": 1, + "title": "Page", + "type": "integer" + }, + "page_size": { + "default": 20, + "title": "Page Size", + "type": "integer" + }, + "total": { + "default": 0, + "title": "Total", + "type": "integer" + } + }, + "title": "LibraryList", + "type": "object" + }, + "LibraryList:validation": { + "$defs": { + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + }, + "LibraryItem": { + "additionalProperties": true, + "description": "Same shape as VerificationListItem on the public Library list.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "LibraryItem", + "type": "object" + } + }, + "additionalProperties": true, + "properties": { + "items": { + "items": { + "$ref": "#/$defs/LibraryItem" + }, + "title": "Items", + "type": "array" + }, + "page": { + "default": 1, + "title": "Page", + "type": "integer" + }, + "page_size": { + "default": 20, + "title": "Page Size", + "type": "integer" + }, + "total": { + "default": 0, + "title": "Total", + "type": "integer" + } + }, + "title": "LibraryList", + "type": "object" + }, + "Position:serialization": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "Position:validation": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "RelatedVerifications:serialization": { + "$defs": { + "SimilarVerification": { + "additionalProperties": true, + "description": "An existing public verification that semantically resembles the submitted text.\n\nSame vocabulary as ``Verification`` \u2014 flat ``verdict`` / ``confidence`` /\n``lenz_score`` at top level, no nested ``Verdict`` object.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "distance": { + "default": 0.0, + "title": "Distance", + "type": "number" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "SimilarVerification", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Wrapper for ``GET /verifications/{id}/related``.", + "properties": { + "items": { + "items": { + "$ref": "#/$defs/SimilarVerification" + }, + "title": "Items", + "type": "array" + } + }, + "title": "RelatedVerifications", + "type": "object" + }, + "RelatedVerifications:validation": { + "$defs": { + "SimilarVerification": { + "additionalProperties": true, + "description": "An existing public verification that semantically resembles the submitted text.\n\nSame vocabulary as ``Verification`` \u2014 flat ``verdict`` / ``confidence`` /\n``lenz_score`` at top level, no nested ``Verdict`` object.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "distance": { + "default": 0.0, + "title": "Distance", + "type": "number" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "SimilarVerification", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Wrapper for ``GET /verifications/{id}/related``.", + "properties": { + "items": { + "items": { + "$ref": "#/$defs/SimilarVerification" + }, + "title": "Items", + "type": "array" + } + }, + "title": "RelatedVerifications", + "type": "object" + }, + "ReviewAssessment:serialization": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A claim's quick check. ``status``: ``pending`` | ``running`` |\n``completed`` | ``failed``. On ``completed`` the fields mean what they\nmean on an ``/assess`` row; on ``failed`` see ``error_code`` (an open\nset, as on ``/assess``), ``hint`` and ``failure``.", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "dissent": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Dissent" + }, + "error_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Error Code" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "identified_claims": { + "items": { + "type": "string" + }, + "title": "Identified Claims", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verdict" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + } + }, + "title": "ReviewAssessment", + "type": "object" + }, + "ReviewAssessment:validation": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A claim's quick check. ``status``: ``pending`` | ``running`` |\n``completed`` | ``failed``. On ``completed`` the fields mean what they\nmean on an ``/assess`` row; on ``failed`` see ``error_code`` (an open\nset, as on ``/assess``), ``hint`` and ``failure``.", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "dissent": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Dissent" + }, + "error_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Error Code" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "identified_claims": { + "items": { + "type": "string" + }, + "title": "Identified Claims", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verdict" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + } + }, + "title": "ReviewAssessment", + "type": "object" + }, + "ReviewAssessmentCounts:serialization": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + } + }, + "title": "ReviewAssessmentCounts", + "type": "object" + }, + "ReviewAssessmentCounts:validation": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + } + }, + "title": "ReviewAssessmentCounts", + "type": "object" + }, + "ReviewCitation:serialization": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewCitationCheck": { + "additionalProperties": true, + "description": "A citation's check. ``status`` is progress, as on ``assessment``:\n``pending`` | ``running`` | ``completed`` | ``failed``.\n\n- ``page_read``: ``full``, ``partial``, ``not_found`` or ``none``.\n- ``source_url``: where the text was actually read from (after\n redirects, or a free copy of a paper). ``source_version``, for a DOI:\n ``published``, ``accepted`` or ``submitted``.\n- ``support``: ``supported``, ``partly_supported``, ``contradicted``,\n ``not_in_source`` or ``unchecked``. ``snippet`` is the verified passage\n of the source it rests on; ``rationale`` is a reviewer's note, not a\n checked source.\n- ``quote``: ``matched``, ``not_in_source`` or ``unchecked``; ``None``\n when the draft quoted nothing from this source. ``missing_quote`` is\n the quoted excerpt the quote check did not find; ``None`` unless\n ``quote`` is ``not_in_source``.\n- ``doi_registered``, ``metadata`` (``consistent``, ``mismatch`` or\n ``unchecked``), ``metadata_differences`` and ``registered``: set for a\n DOI only.\n- ``unchecked_reason`` and ``hint``: why the finding is ``unchecked`` and\n what to do next. The reasons are an open set, e.g. ``no_text``,\n ``partial_text``, ``login_required``, ``unsupported_site``,\n ``no_statement``, ``invalid_url``, ``other_version``, ``inconclusive``,\n ``ambiguous_reference``.\n- ``failure``: on a ``failed`` check.", + "properties": { + "doi_registered": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi Registered" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "metadata": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Metadata" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Language" + }, + "page_published_date": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Published Date" + }, + "page_read": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Read" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Quote" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "registered": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationRecord" + }, + { + "type": "null" + } + ], + "default": null + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Url" + }, + "source_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Version" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "support": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Support" + }, + "unchecked_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Unchecked Reason" + } + }, + "title": "ReviewCitationCheck", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationRecord": { + "additionalProperties": true, + "description": "A DOI's record in the registry.", + "properties": { + "authors": { + "items": { + "type": "string" + }, + "title": "Authors", + "type": "array" + }, + "journal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Journal" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Title" + }, + "year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Year" + } + }, + "title": "ReviewCitationRecord", + "type": "object" + }, + "ReviewCitationResult": { + "additionalProperties": true, + "description": "The one answer to read for a citation, derived from its ``check``.\n\n``finding``, most serious first: ``doi_not_found``, ``page_not_found``,\n``contradicted``, ``quote_not_in_source``, ``not_in_source``,\n``partly_supported``, ``metadata_mismatch`` (each an issue), then\n``supported`` and ``unchecked``. ``source`` says which check the finding\ncame from: ``doi``, ``page``, ``support``, ``quote`` or ``metadata``;\n``None`` on ``unchecked``.", + "properties": { + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + } + }, + "title": "ReviewCitationResult", + "type": "object" + } + }, + "additionalProperties": true, + "description": "One citation of the draft (a URL or a DOI where the draft uses it), in\nthe draft's order. Only on a review that asked for the citation check.\n\n``reference`` is the citation as the draft writes it; ``statement`` the\ndraft's sentence it is attached to, with link syntax reduced to its\nwords; ``quotes`` the words the draft quotes from this source.\n``position`` locates ``statement`` in the text as sent (its ``text`` is\n``None``: the row carries the ``statement``). ``result`` is\n``None`` until the check has ended, and on a failed row with nothing\nestablished.", + "properties": { + "check": { + "$ref": "#/$defs/ReviewCitationCheck" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationResult" + }, + { + "type": "null" + } + ], + "default": null + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitation", + "type": "object" + }, + "ReviewCitation:validation": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewCitationCheck": { + "additionalProperties": true, + "description": "A citation's check. ``status`` is progress, as on ``assessment``:\n``pending`` | ``running`` | ``completed`` | ``failed``.\n\n- ``page_read``: ``full``, ``partial``, ``not_found`` or ``none``.\n- ``source_url``: where the text was actually read from (after\n redirects, or a free copy of a paper). ``source_version``, for a DOI:\n ``published``, ``accepted`` or ``submitted``.\n- ``support``: ``supported``, ``partly_supported``, ``contradicted``,\n ``not_in_source`` or ``unchecked``. ``snippet`` is the verified passage\n of the source it rests on; ``rationale`` is a reviewer's note, not a\n checked source.\n- ``quote``: ``matched``, ``not_in_source`` or ``unchecked``; ``None``\n when the draft quoted nothing from this source. ``missing_quote`` is\n the quoted excerpt the quote check did not find; ``None`` unless\n ``quote`` is ``not_in_source``.\n- ``doi_registered``, ``metadata`` (``consistent``, ``mismatch`` or\n ``unchecked``), ``metadata_differences`` and ``registered``: set for a\n DOI only.\n- ``unchecked_reason`` and ``hint``: why the finding is ``unchecked`` and\n what to do next. The reasons are an open set, e.g. ``no_text``,\n ``partial_text``, ``login_required``, ``unsupported_site``,\n ``no_statement``, ``invalid_url``, ``other_version``, ``inconclusive``,\n ``ambiguous_reference``.\n- ``failure``: on a ``failed`` check.", + "properties": { + "doi_registered": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi Registered" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "metadata": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Metadata" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Language" + }, + "page_published_date": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Published Date" + }, + "page_read": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Read" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Quote" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "registered": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationRecord" + }, + { + "type": "null" + } + ], + "default": null + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Url" + }, + "source_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Version" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "support": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Support" + }, + "unchecked_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Unchecked Reason" + } + }, + "title": "ReviewCitationCheck", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationRecord": { + "additionalProperties": true, + "description": "A DOI's record in the registry.", + "properties": { + "authors": { + "items": { + "type": "string" + }, + "title": "Authors", + "type": "array" + }, + "journal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Journal" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Title" + }, + "year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Year" + } + }, + "title": "ReviewCitationRecord", + "type": "object" + }, + "ReviewCitationResult": { + "additionalProperties": true, + "description": "The one answer to read for a citation, derived from its ``check``.\n\n``finding``, most serious first: ``doi_not_found``, ``page_not_found``,\n``contradicted``, ``quote_not_in_source``, ``not_in_source``,\n``partly_supported``, ``metadata_mismatch`` (each an issue), then\n``supported`` and ``unchecked``. ``source`` says which check the finding\ncame from: ``doi``, ``page``, ``support``, ``quote`` or ``metadata``;\n``None`` on ``unchecked``.", + "properties": { + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + } + }, + "title": "ReviewCitationResult", + "type": "object" + } + }, + "additionalProperties": true, + "description": "One citation of the draft (a URL or a DOI where the draft uses it), in\nthe draft's order. Only on a review that asked for the citation check.\n\n``reference`` is the citation as the draft writes it; ``statement`` the\ndraft's sentence it is attached to, with link syntax reduced to its\nwords; ``quotes`` the words the draft quotes from this source.\n``position`` locates ``statement`` in the text as sent (its ``text`` is\n``None``: the row carries the ``statement``). ``result`` is\n``None`` until the check has ended, and on a failed row with nothing\nestablished.", + "properties": { + "check": { + "$ref": "#/$defs/ReviewCitationCheck" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationResult" + }, + { + "type": "null" + } + ], + "default": null + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitation", + "type": "object" + }, + "ReviewCitationCheck:serialization": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationRecord": { + "additionalProperties": true, + "description": "A DOI's record in the registry.", + "properties": { + "authors": { + "items": { + "type": "string" + }, + "title": "Authors", + "type": "array" + }, + "journal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Journal" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Title" + }, + "year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Year" + } + }, + "title": "ReviewCitationRecord", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A citation's check. ``status`` is progress, as on ``assessment``:\n``pending`` | ``running`` | ``completed`` | ``failed``.\n\n- ``page_read``: ``full``, ``partial``, ``not_found`` or ``none``.\n- ``source_url``: where the text was actually read from (after\n redirects, or a free copy of a paper). ``source_version``, for a DOI:\n ``published``, ``accepted`` or ``submitted``.\n- ``support``: ``supported``, ``partly_supported``, ``contradicted``,\n ``not_in_source`` or ``unchecked``. ``snippet`` is the verified passage\n of the source it rests on; ``rationale`` is a reviewer's note, not a\n checked source.\n- ``quote``: ``matched``, ``not_in_source`` or ``unchecked``; ``None``\n when the draft quoted nothing from this source. ``missing_quote`` is\n the quoted excerpt the quote check did not find; ``None`` unless\n ``quote`` is ``not_in_source``.\n- ``doi_registered``, ``metadata`` (``consistent``, ``mismatch`` or\n ``unchecked``), ``metadata_differences`` and ``registered``: set for a\n DOI only.\n- ``unchecked_reason`` and ``hint``: why the finding is ``unchecked`` and\n what to do next. The reasons are an open set, e.g. ``no_text``,\n ``partial_text``, ``login_required``, ``unsupported_site``,\n ``no_statement``, ``invalid_url``, ``other_version``, ``inconclusive``,\n ``ambiguous_reference``.\n- ``failure``: on a ``failed`` check.", + "properties": { + "doi_registered": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi Registered" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "metadata": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Metadata" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Language" + }, + "page_published_date": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Published Date" + }, + "page_read": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Read" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Quote" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "registered": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationRecord" + }, + { + "type": "null" + } + ], + "default": null + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Url" + }, + "source_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Version" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "support": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Support" + }, + "unchecked_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Unchecked Reason" + } + }, + "title": "ReviewCitationCheck", + "type": "object" + }, + "ReviewCitationCheck:validation": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationRecord": { + "additionalProperties": true, + "description": "A DOI's record in the registry.", + "properties": { + "authors": { + "items": { + "type": "string" + }, + "title": "Authors", + "type": "array" + }, + "journal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Journal" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Title" + }, + "year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Year" + } + }, + "title": "ReviewCitationRecord", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A citation's check. ``status`` is progress, as on ``assessment``:\n``pending`` | ``running`` | ``completed`` | ``failed``.\n\n- ``page_read``: ``full``, ``partial``, ``not_found`` or ``none``.\n- ``source_url``: where the text was actually read from (after\n redirects, or a free copy of a paper). ``source_version``, for a DOI:\n ``published``, ``accepted`` or ``submitted``.\n- ``support``: ``supported``, ``partly_supported``, ``contradicted``,\n ``not_in_source`` or ``unchecked``. ``snippet`` is the verified passage\n of the source it rests on; ``rationale`` is a reviewer's note, not a\n checked source.\n- ``quote``: ``matched``, ``not_in_source`` or ``unchecked``; ``None``\n when the draft quoted nothing from this source. ``missing_quote`` is\n the quoted excerpt the quote check did not find; ``None`` unless\n ``quote`` is ``not_in_source``.\n- ``doi_registered``, ``metadata`` (``consistent``, ``mismatch`` or\n ``unchecked``), ``metadata_differences`` and ``registered``: set for a\n DOI only.\n- ``unchecked_reason`` and ``hint``: why the finding is ``unchecked`` and\n what to do next. The reasons are an open set, e.g. ``no_text``,\n ``partial_text``, ``login_required``, ``unsupported_site``,\n ``no_statement``, ``invalid_url``, ``other_version``, ``inconclusive``,\n ``ambiguous_reference``.\n- ``failure``: on a ``failed`` check.", + "properties": { + "doi_registered": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi Registered" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "metadata": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Metadata" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Language" + }, + "page_published_date": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Published Date" + }, + "page_read": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Read" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Quote" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "registered": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationRecord" + }, + { + "type": "null" + } + ], + "default": null + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Url" + }, + "source_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Version" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "support": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Support" + }, + "unchecked_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Unchecked Reason" + } + }, + "title": "ReviewCitationCheck", + "type": "object" + }, + "ReviewCitationCheckCounts:serialization": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + }, + "ReviewCitationCheckCounts:validation": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + }, + "ReviewCitationDifference:serialization": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationDifference:validation": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationFailure:serialization": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A citation whose check failed with nothing established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + } + }, + "title": "ReviewCitationFailure", + "type": "object" + }, + "ReviewCitationFailure:validation": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A citation whose check failed with nothing established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + } + }, + "title": "ReviewCitationFailure", + "type": "object" + }, + "ReviewCitationIssue:serialization": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A citation whose finding is an issue (see ``ReviewCitationResult``);\nmost serious first, then in the draft's order.\n\n``snippet`` and ``rationale`` are set only when ``source`` is\n``support``. On ``quote_not_in_source``, ``missing_quote`` is the quoted\nexcerpt that was not found. On ``metadata_mismatch``,\n``metadata_differences`` says what differs. ``failure`` is set when another part of the check failed after\nthe finding was established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitationIssue", + "type": "object" + }, + "ReviewCitationIssue:validation": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A citation whose finding is an issue (see ``ReviewCitationResult``);\nmost serious first, then in the draft's order.\n\n``snippet`` and ``rationale`` are set only when ``source`` is\n``support``. On ``quote_not_in_source``, ``missing_quote`` is the quoted\nexcerpt that was not found. On ``metadata_mismatch``,\n``metadata_differences`` says what differs. ``failure`` is set when another part of the check failed after\nthe finding was established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitationIssue", + "type": "object" + }, + "ReviewCitationRecord:serialization": { + "additionalProperties": true, + "description": "A DOI's record in the registry.", + "properties": { + "authors": { + "items": { + "type": "string" + }, + "title": "Authors", + "type": "array" + }, + "journal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Journal" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Title" + }, + "year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Year" + } + }, + "title": "ReviewCitationRecord", + "type": "object" + }, + "ReviewCitationRecord:validation": { + "additionalProperties": true, + "description": "A DOI's record in the registry.", + "properties": { + "authors": { + "items": { + "type": "string" + }, + "title": "Authors", + "type": "array" + }, + "journal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Journal" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Title" + }, + "year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Year" + } + }, + "title": "ReviewCitationRecord", + "type": "object" + }, + "ReviewCitationResult:serialization": { + "additionalProperties": true, + "description": "The one answer to read for a citation, derived from its ``check``.\n\n``finding``, most serious first: ``doi_not_found``, ``page_not_found``,\n``contradicted``, ``quote_not_in_source``, ``not_in_source``,\n``partly_supported``, ``metadata_mismatch`` (each an issue), then\n``supported`` and ``unchecked``. ``source`` says which check the finding\ncame from: ``doi``, ``page``, ``support``, ``quote`` or ``metadata``;\n``None`` on ``unchecked``.", + "properties": { + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + } + }, + "title": "ReviewCitationResult", + "type": "object" + }, + "ReviewCitationResult:validation": { + "additionalProperties": true, + "description": "The one answer to read for a citation, derived from its ``check``.\n\n``finding``, most serious first: ``doi_not_found``, ``page_not_found``,\n``contradicted``, ``quote_not_in_source``, ``not_in_source``,\n``partly_supported``, ``metadata_mismatch`` (each an issue), then\n``supported`` and ``unchecked``. ``source`` says which check the finding\ncame from: ``doi``, ``page``, ``support``, ``quote`` or ``metadata``;\n``None`` on ``unchecked``.", + "properties": { + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + } + }, + "title": "ReviewCitationResult", + "type": "object" + }, + "ReviewClaim:serialization": { + "$defs": { + "Escalation": { + "additionalProperties": true, + "description": "Why a claim was, or was not, deep-checked.\n\n``matched_rules`` lists the rules the quick check matched (``verdict``,\n``confidence``, both, or neither). ``disposition`` says what happened:\n``planned`` (deep-checked), ``not_selected`` (no rule matched), ``cap``\n(matched, but ``max_verifications`` was reached), ``credits`` (matched,\nbut the balance ran out) or ``account_cap`` (matched, but the account's\nallowance of concurrent deep checks was reached). To deep-check the\n``cap`` rows yourself, send their claims to ``verify_batch_and_wait``.", + "properties": { + "disposition": { + "default": "", + "title": "Disposition", + "type": "string" + }, + "matched_rules": { + "items": { + "type": "string" + }, + "title": "Matched Rules", + "type": "array" + } + }, + "title": "Escalation", + "type": "object" + }, + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewAssessment": { + "additionalProperties": true, + "description": "A claim's quick check. ``status``: ``pending`` | ``running`` |\n``completed`` | ``failed``. On ``completed`` the fields mean what they\nmean on an ``/assess`` row; on ``failed`` see ``error_code`` (an open\nset, as on ``/assess``), ``hint`` and ``failure``.", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "dissent": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Dissent" + }, + "error_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Error Code" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "identified_claims": { + "items": { + "type": "string" + }, + "title": "Identified Claims", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verdict" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + } + }, + "title": "ReviewAssessment", + "type": "object" + }, + "ReviewEntity": { + "additionalProperties": true, + "description": "An entity the deep check found in the claim. ``qid`` is its Wikidata\nid when resolved. Either may be ``None``.", + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Name" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "ReviewEntity", + "type": "object" + }, + "ReviewResult": { + "additionalProperties": true, + "description": "The one answer to read for a claim: the deep check's verdict when it\ncompleted, else the quick check's. ``source`` says which\n(``assessment`` or ``verification``).", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + } + }, + "title": "ReviewResult", + "type": "object" + }, + "ReviewVerification": { + "additionalProperties": true, + "description": "A claim's deep check. ``status``: ``processing`` | ``completed`` |\n``failed``; while ``processing`` only ``status``, ``content_status`` and\nthe ids are set. ``content_status`` is ``purged`` once the verification\nwas deleted or removed by its account's retention period: the verdict and\nids stay, the text fields and links are ``None``.\n\n``visibility`` and ``depth`` are what the verification actually has: a\nverdict served from an earlier check keeps its own visibility and may be\n``standard`` for a ``low`` request. Sources are on the verification\nitself: ``client.verifications.get(verification_id)``, or ``url``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "content_status": { + "default": "available", + "title": "Content Status", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "depth": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Depth" + }, + "domain": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Domain" + }, + "entities": { + "items": { + "$ref": "#/$defs/ReviewEntity" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Executive Summary" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Language" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "task_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Task Id" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verdict" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "visibility": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Visibility" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "ReviewVerification", + "type": "object" + }, + "SuggestedEdit": { + "additionalProperties": true, + "description": "One replacement in the draft: the span ``start``..``end`` of the\n``text`` you sent (Unicode code points, ``end`` exclusive, as in\n``Position``), ``text`` exactly that slice, and ``replacement`` what takes\nits place (``\"\"`` deletes it). ``position`` is the index of the claim\nrow's ``positions`` entry the edit sits in, for grouping by passage.\n\nCompare ``text`` with your draft before you apply an edit, so a draft that\nchanged since is never edited in the wrong place.", + "properties": { + "end": { + "default": 0, + "title": "End", + "type": "integer" + }, + "position": { + "default": 0, + "title": "Position", + "type": "integer" + }, + "replacement": { + "default": "", + "title": "Replacement", + "type": "string" + }, + "start": { + "default": 0, + "title": "Start", + "type": "integer" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "SuggestedEdit", + "type": "object" + }, + "SuggestedEdits": { + "additionalProperties": true, + "description": "The smallest edits to the draft that make it say what the claim's\n``suggested_rewrite`` says (the deep check's, or the quick check's on a\nclaim that stayed on the quick verdict), in the draft's own language\n(``review(..., suggest_edits=True)``).\n\n``status`` is ``\"pending\"`` while they are computed (``edits`` is\n``None``; keep polling) and ``\"completed\"`` once settled, which includes\nsettling on none (``edits == []``: no edit could be made safely, or it\ncould not be computed). They are not themselves verified:\nreview them before you publish.", + "properties": { + "edits": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/SuggestedEdit" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Edits" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + } + }, + "title": "SuggestedEdits", + "type": "object" + } + }, + "additionalProperties": true, + "description": "One claim of the draft, in the order the draft's claims were read.\n\n``result`` is ``None`` until the quick check completes, and on a failed\none. ``escalation`` is ``None`` until then too. ``verification`` is set\nonce a deep check was planned for the claim.\n\n``positions`` lists every place the draft makes the claim, in text\norder, at most 10 (see ``Position``). ``start`` / ``end`` index the\n``text`` you sent in Unicode code points (``text[start:end]`` in Python;\n``end`` exclusive), the same coordinates as a citation's ``position``.\nFor a URL draft, ``start`` and ``end`` are ``None`` and ``text`` carries\nthe passage. ``positions`` is ``None`` when the claims could not be\nlocated, or once a zero-retention draft is gone (and from servers that\npredate the field).", + "properties": { + "assessment": { + "$ref": "#/$defs/ReviewAssessment" + }, + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "escalation": { + "anyOf": [ + { + "$ref": "#/$defs/Escalation" + }, + { + "type": "null" + } + ], + "default": null + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewResult" + }, + { + "type": "null" + } + ], + "default": null + }, + "suggested_edits": { + "anyOf": [ + { + "$ref": "#/$defs/SuggestedEdits" + }, + { + "type": "null" + } + ], + "default": null + }, + "verification": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewVerification" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "title": "ReviewClaim", + "type": "object" + }, + "ReviewClaim:validation": { + "$defs": { + "Escalation": { + "additionalProperties": true, + "description": "Why a claim was, or was not, deep-checked.\n\n``matched_rules`` lists the rules the quick check matched (``verdict``,\n``confidence``, both, or neither). ``disposition`` says what happened:\n``planned`` (deep-checked), ``not_selected`` (no rule matched), ``cap``\n(matched, but ``max_verifications`` was reached), ``credits`` (matched,\nbut the balance ran out) or ``account_cap`` (matched, but the account's\nallowance of concurrent deep checks was reached). To deep-check the\n``cap`` rows yourself, send their claims to ``verify_batch_and_wait``.", + "properties": { + "disposition": { + "default": "", + "title": "Disposition", + "type": "string" + }, + "matched_rules": { + "items": { + "type": "string" + }, + "title": "Matched Rules", + "type": "array" + } + }, + "title": "Escalation", + "type": "object" + }, + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewAssessment": { + "additionalProperties": true, + "description": "A claim's quick check. ``status``: ``pending`` | ``running`` |\n``completed`` | ``failed``. On ``completed`` the fields mean what they\nmean on an ``/assess`` row; on ``failed`` see ``error_code`` (an open\nset, as on ``/assess``), ``hint`` and ``failure``.", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "dissent": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Dissent" + }, + "error_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Error Code" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "identified_claims": { + "items": { + "type": "string" + }, + "title": "Identified Claims", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verdict" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + } + }, + "title": "ReviewAssessment", + "type": "object" + }, + "ReviewEntity": { + "additionalProperties": true, + "description": "An entity the deep check found in the claim. ``qid`` is its Wikidata\nid when resolved. Either may be ``None``.", + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Name" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "ReviewEntity", + "type": "object" + }, + "ReviewResult": { + "additionalProperties": true, + "description": "The one answer to read for a claim: the deep check's verdict when it\ncompleted, else the quick check's. ``source`` says which\n(``assessment`` or ``verification``).", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + } + }, + "title": "ReviewResult", + "type": "object" + }, + "ReviewVerification": { + "additionalProperties": true, + "description": "A claim's deep check. ``status``: ``processing`` | ``completed`` |\n``failed``; while ``processing`` only ``status``, ``content_status`` and\nthe ids are set. ``content_status`` is ``purged`` once the verification\nwas deleted or removed by its account's retention period: the verdict and\nids stay, the text fields and links are ``None``.\n\n``visibility`` and ``depth`` are what the verification actually has: a\nverdict served from an earlier check keeps its own visibility and may be\n``standard`` for a ``low`` request. Sources are on the verification\nitself: ``client.verifications.get(verification_id)``, or ``url``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "content_status": { + "default": "available", + "title": "Content Status", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "depth": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Depth" + }, + "domain": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Domain" + }, + "entities": { + "items": { + "$ref": "#/$defs/ReviewEntity" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Executive Summary" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Language" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "task_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Task Id" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verdict" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "visibility": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Visibility" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "ReviewVerification", + "type": "object" + }, + "SuggestedEdit": { + "additionalProperties": true, + "description": "One replacement in the draft: the span ``start``..``end`` of the\n``text`` you sent (Unicode code points, ``end`` exclusive, as in\n``Position``), ``text`` exactly that slice, and ``replacement`` what takes\nits place (``\"\"`` deletes it). ``position`` is the index of the claim\nrow's ``positions`` entry the edit sits in, for grouping by passage.\n\nCompare ``text`` with your draft before you apply an edit, so a draft that\nchanged since is never edited in the wrong place.", + "properties": { + "end": { + "default": 0, + "title": "End", + "type": "integer" + }, + "position": { + "default": 0, + "title": "Position", + "type": "integer" + }, + "replacement": { + "default": "", + "title": "Replacement", + "type": "string" + }, + "start": { + "default": 0, + "title": "Start", + "type": "integer" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "SuggestedEdit", + "type": "object" + }, + "SuggestedEdits": { + "additionalProperties": true, + "description": "The smallest edits to the draft that make it say what the claim's\n``suggested_rewrite`` says (the deep check's, or the quick check's on a\nclaim that stayed on the quick verdict), in the draft's own language\n(``review(..., suggest_edits=True)``).\n\n``status`` is ``\"pending\"`` while they are computed (``edits`` is\n``None``; keep polling) and ``\"completed\"`` once settled, which includes\nsettling on none (``edits == []``: no edit could be made safely, or it\ncould not be computed). They are not themselves verified:\nreview them before you publish.", + "properties": { + "edits": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/SuggestedEdit" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Edits" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + } + }, + "title": "SuggestedEdits", + "type": "object" + } + }, + "additionalProperties": true, + "description": "One claim of the draft, in the order the draft's claims were read.\n\n``result`` is ``None`` until the quick check completes, and on a failed\none. ``escalation`` is ``None`` until then too. ``verification`` is set\nonce a deep check was planned for the claim.\n\n``positions`` lists every place the draft makes the claim, in text\norder, at most 10 (see ``Position``). ``start`` / ``end`` index the\n``text`` you sent in Unicode code points (``text[start:end]`` in Python;\n``end`` exclusive), the same coordinates as a citation's ``position``.\nFor a URL draft, ``start`` and ``end`` are ``None`` and ``text`` carries\nthe passage. ``positions`` is ``None`` when the claims could not be\nlocated, or once a zero-retention draft is gone (and from servers that\npredate the field).", + "properties": { + "assessment": { + "$ref": "#/$defs/ReviewAssessment" + }, + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "escalation": { + "anyOf": [ + { + "$ref": "#/$defs/Escalation" + }, + { + "type": "null" + } + ], + "default": null + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewResult" + }, + { + "type": "null" + } + ], + "default": null + }, + "suggested_edits": { + "anyOf": [ + { + "$ref": "#/$defs/SuggestedEdits" + }, + { + "type": "null" + } + ], + "default": null + }, + "verification": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewVerification" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "title": "ReviewClaim", + "type": "object" + }, + "ReviewCredits:serialization": { + "additionalProperties": true, + "description": "``charged`` is the net credits the review cost the account, its\ncitation checks included. It is final once no deep check or citation\ncheck is running: read it at ``completed``.", + "properties": { + "charged": { + "default": 0, + "title": "Charged", + "type": "integer" + } + }, + "title": "ReviewCredits", + "type": "object" + }, + "ReviewCredits:validation": { + "additionalProperties": true, + "description": "``charged`` is the net credits the review cost the account, its\ncitation checks included. It is final once no deep check or citation\ncheck is running: read it at ``completed``.", + "properties": { + "charged": { + "default": 0, + "title": "Charged", + "type": "integer" + } + }, + "title": "ReviewCredits", + "type": "object" + }, + "ReviewEntity:serialization": { + "additionalProperties": true, + "description": "An entity the deep check found in the claim. ``qid`` is its Wikidata\nid when resolved. Either may be ``None``.", + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Name" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "ReviewEntity", + "type": "object" + }, + "ReviewEntity:validation": { + "additionalProperties": true, + "description": "An entity the deep check found in the claim. ``qid`` is its Wikidata\nid when resolved. Either may be ``None``.", + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Name" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "ReviewEntity", + "type": "object" + }, + "ReviewEnvelope:serialization": { + "$defs": { + "ClaimLocation": { + "additionalProperties": true, + "description": "Where the submitted text makes one claim.\n\n``claim`` is exactly as in the claim list it belongs to\n(``ExtractedClaims.claim`` / ``identified_claims``, or a review's\n``more_claims``). ``positions`` lists every place the text makes it, in\ntext order, at most 10. It is ``None`` only when that claim could not be\nplaced; on ``/extract`` every returned claim is placed.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + } + }, + "title": "ClaimLocation", + "type": "object" + }, + "Escalation": { + "additionalProperties": true, + "description": "Why a claim was, or was not, deep-checked.\n\n``matched_rules`` lists the rules the quick check matched (``verdict``,\n``confidence``, both, or neither). ``disposition`` says what happened:\n``planned`` (deep-checked), ``not_selected`` (no rule matched), ``cap``\n(matched, but ``max_verifications`` was reached), ``credits`` (matched,\nbut the balance ran out) or ``account_cap`` (matched, but the account's\nallowance of concurrent deep checks was reached). To deep-check the\n``cap`` rows yourself, send their claims to ``verify_batch_and_wait``.", + "properties": { + "disposition": { + "default": "", + "title": "Disposition", + "type": "string" + }, + "matched_rules": { + "items": { + "type": "string" + }, + "title": "Matched Rules", + "type": "array" + } + }, + "title": "Escalation", + "type": "object" + }, + "EscalationPolicy": { + "additionalProperties": true, + "description": "Which quick-checked claims get a deep check, as the review RESOLVED it.\n\nA claim is deep-checked when its quick verdict is in ``verdicts`` OR its\nconfidence band is in ``confidence``, up to ``max_verifications`` of them,\nat ``depth``. ``max_assessments`` is how many of the draft's claims, most\ncheck-worthy first, got a quick verdict.", + "properties": { + "confidence": { + "items": { + "type": "string" + }, + "title": "Confidence", + "type": "array" + }, + "depth": { + "default": "standard", + "title": "Depth", + "type": "string" + }, + "max_assessments": { + "default": 20, + "title": "Max Assessments", + "type": "integer" + }, + "max_citations": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max Citations" + }, + "max_verifications": { + "default": 5, + "title": "Max Verifications", + "type": "integer" + }, + "suggest_edits": { + "default": false, + "title": "Suggest Edits", + "type": "boolean" + }, + "verdicts": { + "items": { + "type": "string" + }, + "title": "Verdicts", + "type": "array" + } + }, + "title": "EscalationPolicy", + "type": "object" + }, + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewAssessmentCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + } + }, + "title": "ReviewAssessmentCounts", + "type": "object" + }, + "ReviewCitationCheckCounts": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationFailure": { + "additionalProperties": true, + "description": "A citation whose check failed with nothing established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + } + }, + "title": "ReviewCitationFailure", + "type": "object" + }, + "ReviewCitationIssue": { + "additionalProperties": true, + "description": "A citation whose finding is an issue (see ``ReviewCitationResult``);\nmost serious first, then in the draft's order.\n\n``snippet`` and ``rationale`` are set only when ``source`` is\n``support``. On ``quote_not_in_source``, ``missing_quote`` is the quoted\nexcerpt that was not found. On ``metadata_mismatch``,\n``metadata_differences`` says what differs. ``failure`` is set when another part of the check failed after\nthe finding was established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitationIssue", + "type": "object" + }, + "ReviewCredits": { + "additionalProperties": true, + "description": "``charged`` is the net credits the review cost the account, its\ncitation checks included. It is final once no deep check or citation\ncheck is running: read it at ``completed``.", + "properties": { + "charged": { + "default": 0, + "title": "Charged", + "type": "integer" + } + }, + "title": "ReviewCredits", + "type": "object" + }, + "ReviewFailure": { + "additionalProperties": true, + "description": "A claim outside the issues whose work failed. ``stage`` is\n``assessment`` or ``verification``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "stage": { + "default": "", + "title": "Stage", + "type": "string" + } + }, + "title": "ReviewFailure", + "type": "object" + }, + "ReviewIssue": { + "additionalProperties": true, + "description": "A claim whose final verdict is ``False``, ``Mostly False`` or ``Mixed``.\n\n``source`` says which check the verdict comes from: ``verification`` (a\ndeep check, with ``verification_id``, ``url`` and ``key_finding``) or\n``assessment`` (the quick check only; ``escalation`` says why it was not\ndeep-checked, and ``rationale`` is the reviewers' note).\n``verified_claim`` is the deep check's wording of the claim when it\ndiffers from ``claim``. ``failure`` is set when the claim's deep check\nfailed.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "escalation": { + "anyOf": [ + { + "$ref": "#/$defs/Escalation" + }, + { + "type": "null" + } + ], + "default": null + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "suggested_edits": { + "anyOf": [ + { + "$ref": "#/$defs/SuggestedEdits" + }, + { + "type": "null" + } + ], + "default": null + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Status" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "verified_claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verified Claim" + } + }, + "title": "ReviewIssue", + "type": "object" + }, + "ReviewMoreCitation": { + "additionalProperties": true, + "description": "A citation found in the draft past the ones this review checked:\nfound but not checked. Send it in a later request to check it.\n``sentence`` is the draft's sentence around it.", + "properties": { + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Sentence" + } + }, + "title": "ReviewMoreCitation", + "type": "object" + }, + "ReviewSummary": { + "additionalProperties": true, + "description": "Counts over the review. A count is ``None`` until what it counts is\nknown (``claims_selected`` before the draft has been read).\n\nThe ``citation*`` counts are ``None`` (``citation_issues`` 0) on a review\nthat did not ask for the citation check.", + "properties": { + "assessments": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewAssessmentCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_checks": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationCheckCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_issues": { + "default": 0, + "title": "Citation Issues", + "type": "integer" + }, + "citation_limit": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit" + }, + "citation_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit Reached" + }, + "citations_found": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Found" + }, + "citations_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Selected" + }, + "citations_skipped": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Skipped" + }, + "claim_limit": { + "default": 20, + "title": "Claim Limit", + "type": "integer" + }, + "claim_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim Limit Reached" + }, + "claims_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claims Selected" + }, + "input_truncated": { + "default": false, + "title": "Input Truncated", + "type": "boolean" + }, + "issues": { + "default": 0, + "title": "Issues", + "type": "integer" + }, + "verifications": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewVerificationCounts" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "title": "ReviewSummary", + "type": "object" + }, + "ReviewVerificationCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "planned": { + "default": 0, + "title": "Planned", + "type": "integer" + } + }, + "title": "ReviewVerificationCounts", + "type": "object" + }, + "SuggestedEdit": { + "additionalProperties": true, + "description": "One replacement in the draft: the span ``start``..``end`` of the\n``text`` you sent (Unicode code points, ``end`` exclusive, as in\n``Position``), ``text`` exactly that slice, and ``replacement`` what takes\nits place (``\"\"`` deletes it). ``position`` is the index of the claim\nrow's ``positions`` entry the edit sits in, for grouping by passage.\n\nCompare ``text`` with your draft before you apply an edit, so a draft that\nchanged since is never edited in the wrong place.", + "properties": { + "end": { + "default": 0, + "title": "End", + "type": "integer" + }, + "position": { + "default": 0, + "title": "Position", + "type": "integer" + }, + "replacement": { + "default": "", + "title": "Replacement", + "type": "string" + }, + "start": { + "default": 0, + "title": "Start", + "type": "integer" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "SuggestedEdit", + "type": "object" + }, + "SuggestedEdits": { + "additionalProperties": true, + "description": "The smallest edits to the draft that make it say what the claim's\n``suggested_rewrite`` says (the deep check's, or the quick check's on a\nclaim that stayed on the quick verdict), in the draft's own language\n(``review(..., suggest_edits=True)``).\n\n``status`` is ``\"pending\"`` while they are computed (``edits`` is\n``None``; keep polling) and ``\"completed\"`` once settled, which includes\nsettling on none (``edits == []``: no edit could be made safely, or it\ncould not be computed). They are not themselves verified:\nreview them before you publish.", + "properties": { + "edits": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/SuggestedEdit" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Edits" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + } + }, + "title": "SuggestedEdits", + "type": "object" + } + }, + "additionalProperties": true, + "description": "What both views of ``GET /reviews/{review_id}`` carry.\n\n``status`` is the lifecycle: ``queued`` \u2192 ``assessing`` \u2192 ``verifying``\n\u2192 ``completed``, or ``failed``. ``outcome`` is ``None`` until the review\nends, then one of ``clean`` (every selected claim checked, no issue),\n``issues_found``, ``incomplete`` (some work failed) or ``unchecked`` (it\nfailed before any claim was checked; ``failure`` says why).\n\nOn a review that asked for the citation check, a citation issue makes\n``outcome`` ``issues_found`` too (``issues`` may then be empty: the rows\nare in ``citation_issues``), and a failed citation check makes it\n``incomplete``. ``status`` reads ``verifying`` while deep checks or\ncitation checks are running.\n\n``issues`` and ``failures`` can change until ``completed``.\n``poll_after_seconds`` is how long to wait before reading again; ``None``\nonce the review has ended.", + "properties": { + "citation_failures": { + "items": { + "$ref": "#/$defs/ReviewCitationFailure" + }, + "title": "Citation Failures", + "type": "array" + }, + "citation_issues": { + "items": { + "$ref": "#/$defs/ReviewCitationIssue" + }, + "title": "Citation Issues", + "type": "array" + }, + "completed_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Completed At" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "credits": { + "$ref": "#/$defs/ReviewCredits" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "failures": { + "items": { + "$ref": "#/$defs/ReviewFailure" + }, + "title": "Failures", + "type": "array" + }, + "issues": { + "items": { + "$ref": "#/$defs/ReviewIssue" + }, + "title": "Issues", + "type": "array" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "more_citations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ReviewMoreCitation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Citations" + }, + "more_claim_locations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ClaimLocation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Claim Locations" + }, + "more_claims": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Claims" + }, + "outcome": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Outcome" + }, + "policy": { + "$ref": "#/$defs/EscalationPolicy" + }, + "poll_after_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Poll After Seconds" + }, + "review_id": { + "default": "", + "title": "Review Id", + "type": "string" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "summary": { + "$ref": "#/$defs/ReviewSummary" + }, + "view": { + "default": "", + "title": "View", + "type": "string" + } + }, + "title": "ReviewEnvelope", + "type": "object" + }, + "ReviewEnvelope:validation": { + "$defs": { + "ClaimLocation": { + "additionalProperties": true, + "description": "Where the submitted text makes one claim.\n\n``claim`` is exactly as in the claim list it belongs to\n(``ExtractedClaims.claim`` / ``identified_claims``, or a review's\n``more_claims``). ``positions`` lists every place the text makes it, in\ntext order, at most 10. It is ``None`` only when that claim could not be\nplaced; on ``/extract`` every returned claim is placed.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + } + }, + "title": "ClaimLocation", + "type": "object" + }, + "Escalation": { + "additionalProperties": true, + "description": "Why a claim was, or was not, deep-checked.\n\n``matched_rules`` lists the rules the quick check matched (``verdict``,\n``confidence``, both, or neither). ``disposition`` says what happened:\n``planned`` (deep-checked), ``not_selected`` (no rule matched), ``cap``\n(matched, but ``max_verifications`` was reached), ``credits`` (matched,\nbut the balance ran out) or ``account_cap`` (matched, but the account's\nallowance of concurrent deep checks was reached). To deep-check the\n``cap`` rows yourself, send their claims to ``verify_batch_and_wait``.", + "properties": { + "disposition": { + "default": "", + "title": "Disposition", + "type": "string" + }, + "matched_rules": { + "items": { + "type": "string" + }, + "title": "Matched Rules", + "type": "array" + } + }, + "title": "Escalation", + "type": "object" + }, + "EscalationPolicy": { + "additionalProperties": true, + "description": "Which quick-checked claims get a deep check, as the review RESOLVED it.\n\nA claim is deep-checked when its quick verdict is in ``verdicts`` OR its\nconfidence band is in ``confidence``, up to ``max_verifications`` of them,\nat ``depth``. ``max_assessments`` is how many of the draft's claims, most\ncheck-worthy first, got a quick verdict.", + "properties": { + "confidence": { + "items": { + "type": "string" + }, + "title": "Confidence", + "type": "array" + }, + "depth": { + "default": "standard", + "title": "Depth", + "type": "string" + }, + "max_assessments": { + "default": 20, + "title": "Max Assessments", + "type": "integer" + }, + "max_citations": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max Citations" + }, + "max_verifications": { + "default": 5, + "title": "Max Verifications", + "type": "integer" + }, + "suggest_edits": { + "default": false, + "title": "Suggest Edits", + "type": "boolean" + }, + "verdicts": { + "items": { + "type": "string" + }, + "title": "Verdicts", + "type": "array" + } + }, + "title": "EscalationPolicy", + "type": "object" + }, + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewAssessmentCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + } + }, + "title": "ReviewAssessmentCounts", + "type": "object" + }, + "ReviewCitationCheckCounts": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationFailure": { + "additionalProperties": true, + "description": "A citation whose check failed with nothing established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + } + }, + "title": "ReviewCitationFailure", + "type": "object" + }, + "ReviewCitationIssue": { + "additionalProperties": true, + "description": "A citation whose finding is an issue (see ``ReviewCitationResult``);\nmost serious first, then in the draft's order.\n\n``snippet`` and ``rationale`` are set only when ``source`` is\n``support``. On ``quote_not_in_source``, ``missing_quote`` is the quoted\nexcerpt that was not found. On ``metadata_mismatch``,\n``metadata_differences`` says what differs. ``failure`` is set when another part of the check failed after\nthe finding was established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitationIssue", + "type": "object" + }, + "ReviewCredits": { + "additionalProperties": true, + "description": "``charged`` is the net credits the review cost the account, its\ncitation checks included. It is final once no deep check or citation\ncheck is running: read it at ``completed``.", + "properties": { + "charged": { + "default": 0, + "title": "Charged", + "type": "integer" + } + }, + "title": "ReviewCredits", + "type": "object" + }, + "ReviewFailure": { + "additionalProperties": true, + "description": "A claim outside the issues whose work failed. ``stage`` is\n``assessment`` or ``verification``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "stage": { + "default": "", + "title": "Stage", + "type": "string" + } + }, + "title": "ReviewFailure", + "type": "object" + }, + "ReviewIssue": { + "additionalProperties": true, + "description": "A claim whose final verdict is ``False``, ``Mostly False`` or ``Mixed``.\n\n``source`` says which check the verdict comes from: ``verification`` (a\ndeep check, with ``verification_id``, ``url`` and ``key_finding``) or\n``assessment`` (the quick check only; ``escalation`` says why it was not\ndeep-checked, and ``rationale`` is the reviewers' note).\n``verified_claim`` is the deep check's wording of the claim when it\ndiffers from ``claim``. ``failure`` is set when the claim's deep check\nfailed.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "escalation": { + "anyOf": [ + { + "$ref": "#/$defs/Escalation" + }, + { + "type": "null" + } + ], + "default": null + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "suggested_edits": { + "anyOf": [ + { + "$ref": "#/$defs/SuggestedEdits" + }, + { + "type": "null" + } + ], + "default": null + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Status" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "verified_claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verified Claim" + } + }, + "title": "ReviewIssue", + "type": "object" + }, + "ReviewMoreCitation": { + "additionalProperties": true, + "description": "A citation found in the draft past the ones this review checked:\nfound but not checked. Send it in a later request to check it.\n``sentence`` is the draft's sentence around it.", + "properties": { + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Sentence" + } + }, + "title": "ReviewMoreCitation", + "type": "object" + }, + "ReviewSummary": { + "additionalProperties": true, + "description": "Counts over the review. A count is ``None`` until what it counts is\nknown (``claims_selected`` before the draft has been read).\n\nThe ``citation*`` counts are ``None`` (``citation_issues`` 0) on a review\nthat did not ask for the citation check.", + "properties": { + "assessments": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewAssessmentCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_checks": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationCheckCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_issues": { + "default": 0, + "title": "Citation Issues", + "type": "integer" + }, + "citation_limit": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit" + }, + "citation_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit Reached" + }, + "citations_found": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Found" + }, + "citations_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Selected" + }, + "citations_skipped": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Skipped" + }, + "claim_limit": { + "default": 20, + "title": "Claim Limit", + "type": "integer" + }, + "claim_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim Limit Reached" + }, + "claims_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claims Selected" + }, + "input_truncated": { + "default": false, + "title": "Input Truncated", + "type": "boolean" + }, + "issues": { + "default": 0, + "title": "Issues", + "type": "integer" + }, + "verifications": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewVerificationCounts" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "title": "ReviewSummary", + "type": "object" + }, + "ReviewVerificationCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "planned": { + "default": 0, + "title": "Planned", + "type": "integer" + } + }, + "title": "ReviewVerificationCounts", + "type": "object" + }, + "SuggestedEdit": { + "additionalProperties": true, + "description": "One replacement in the draft: the span ``start``..``end`` of the\n``text`` you sent (Unicode code points, ``end`` exclusive, as in\n``Position``), ``text`` exactly that slice, and ``replacement`` what takes\nits place (``\"\"`` deletes it). ``position`` is the index of the claim\nrow's ``positions`` entry the edit sits in, for grouping by passage.\n\nCompare ``text`` with your draft before you apply an edit, so a draft that\nchanged since is never edited in the wrong place.", + "properties": { + "end": { + "default": 0, + "title": "End", + "type": "integer" + }, + "position": { + "default": 0, + "title": "Position", + "type": "integer" + }, + "replacement": { + "default": "", + "title": "Replacement", + "type": "string" + }, + "start": { + "default": 0, + "title": "Start", + "type": "integer" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "SuggestedEdit", + "type": "object" + }, + "SuggestedEdits": { + "additionalProperties": true, + "description": "The smallest edits to the draft that make it say what the claim's\n``suggested_rewrite`` says (the deep check's, or the quick check's on a\nclaim that stayed on the quick verdict), in the draft's own language\n(``review(..., suggest_edits=True)``).\n\n``status`` is ``\"pending\"`` while they are computed (``edits`` is\n``None``; keep polling) and ``\"completed\"`` once settled, which includes\nsettling on none (``edits == []``: no edit could be made safely, or it\ncould not be computed). They are not themselves verified:\nreview them before you publish.", + "properties": { + "edits": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/SuggestedEdit" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Edits" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + } + }, + "title": "SuggestedEdits", + "type": "object" + } + }, + "additionalProperties": true, + "description": "What both views of ``GET /reviews/{review_id}`` carry.\n\n``status`` is the lifecycle: ``queued`` \u2192 ``assessing`` \u2192 ``verifying``\n\u2192 ``completed``, or ``failed``. ``outcome`` is ``None`` until the review\nends, then one of ``clean`` (every selected claim checked, no issue),\n``issues_found``, ``incomplete`` (some work failed) or ``unchecked`` (it\nfailed before any claim was checked; ``failure`` says why).\n\nOn a review that asked for the citation check, a citation issue makes\n``outcome`` ``issues_found`` too (``issues`` may then be empty: the rows\nare in ``citation_issues``), and a failed citation check makes it\n``incomplete``. ``status`` reads ``verifying`` while deep checks or\ncitation checks are running.\n\n``issues`` and ``failures`` can change until ``completed``.\n``poll_after_seconds`` is how long to wait before reading again; ``None``\nonce the review has ended.", + "properties": { + "citation_failures": { + "items": { + "$ref": "#/$defs/ReviewCitationFailure" + }, + "title": "Citation Failures", + "type": "array" + }, + "citation_issues": { + "items": { + "$ref": "#/$defs/ReviewCitationIssue" + }, + "title": "Citation Issues", + "type": "array" + }, + "completed_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Completed At" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "credits": { + "$ref": "#/$defs/ReviewCredits" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "failures": { + "items": { + "$ref": "#/$defs/ReviewFailure" + }, + "title": "Failures", + "type": "array" + }, + "issues": { + "items": { + "$ref": "#/$defs/ReviewIssue" + }, + "title": "Issues", + "type": "array" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "more_citations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ReviewMoreCitation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Citations" + }, + "more_claim_locations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ClaimLocation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Claim Locations" + }, + "more_claims": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Claims" + }, + "outcome": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Outcome" + }, + "policy": { + "$ref": "#/$defs/EscalationPolicy" + }, + "poll_after_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Poll After Seconds" + }, + "review_id": { + "default": "", + "title": "Review Id", + "type": "string" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "summary": { + "$ref": "#/$defs/ReviewSummary" + }, + "view": { + "default": "", + "title": "View", + "type": "string" + } + }, + "title": "ReviewEnvelope", + "type": "object" + }, + "ReviewFailure:serialization": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A claim outside the issues whose work failed. ``stage`` is\n``assessment`` or ``verification``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "stage": { + "default": "", + "title": "Stage", + "type": "string" + } + }, + "title": "ReviewFailure", + "type": "object" + }, + "ReviewFailure:validation": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A claim outside the issues whose work failed. ``stage`` is\n``assessment`` or ``verification``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "stage": { + "default": "", + "title": "Stage", + "type": "string" + } + }, + "title": "ReviewFailure", + "type": "object" + }, + "ReviewFull:serialization": { + "$defs": { + "ClaimLocation": { + "additionalProperties": true, + "description": "Where the submitted text makes one claim.\n\n``claim`` is exactly as in the claim list it belongs to\n(``ExtractedClaims.claim`` / ``identified_claims``, or a review's\n``more_claims``). ``positions`` lists every place the text makes it, in\ntext order, at most 10. It is ``None`` only when that claim could not be\nplaced; on ``/extract`` every returned claim is placed.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + } + }, + "title": "ClaimLocation", + "type": "object" + }, + "Escalation": { + "additionalProperties": true, + "description": "Why a claim was, or was not, deep-checked.\n\n``matched_rules`` lists the rules the quick check matched (``verdict``,\n``confidence``, both, or neither). ``disposition`` says what happened:\n``planned`` (deep-checked), ``not_selected`` (no rule matched), ``cap``\n(matched, but ``max_verifications`` was reached), ``credits`` (matched,\nbut the balance ran out) or ``account_cap`` (matched, but the account's\nallowance of concurrent deep checks was reached). To deep-check the\n``cap`` rows yourself, send their claims to ``verify_batch_and_wait``.", + "properties": { + "disposition": { + "default": "", + "title": "Disposition", + "type": "string" + }, + "matched_rules": { + "items": { + "type": "string" + }, + "title": "Matched Rules", + "type": "array" + } + }, + "title": "Escalation", + "type": "object" + }, + "EscalationPolicy": { + "additionalProperties": true, + "description": "Which quick-checked claims get a deep check, as the review RESOLVED it.\n\nA claim is deep-checked when its quick verdict is in ``verdicts`` OR its\nconfidence band is in ``confidence``, up to ``max_verifications`` of them,\nat ``depth``. ``max_assessments`` is how many of the draft's claims, most\ncheck-worthy first, got a quick verdict.", + "properties": { + "confidence": { + "items": { + "type": "string" + }, + "title": "Confidence", + "type": "array" + }, + "depth": { + "default": "standard", + "title": "Depth", + "type": "string" + }, + "max_assessments": { + "default": 20, + "title": "Max Assessments", + "type": "integer" + }, + "max_citations": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max Citations" + }, + "max_verifications": { + "default": 5, + "title": "Max Verifications", + "type": "integer" + }, + "suggest_edits": { + "default": false, + "title": "Suggest Edits", + "type": "boolean" + }, + "verdicts": { + "items": { + "type": "string" + }, + "title": "Verdicts", + "type": "array" + } + }, + "title": "EscalationPolicy", + "type": "object" + }, + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewAssessment": { + "additionalProperties": true, + "description": "A claim's quick check. ``status``: ``pending`` | ``running`` |\n``completed`` | ``failed``. On ``completed`` the fields mean what they\nmean on an ``/assess`` row; on ``failed`` see ``error_code`` (an open\nset, as on ``/assess``), ``hint`` and ``failure``.", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "dissent": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Dissent" + }, + "error_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Error Code" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "identified_claims": { + "items": { + "type": "string" + }, + "title": "Identified Claims", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verdict" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + } + }, + "title": "ReviewAssessment", + "type": "object" + }, + "ReviewAssessmentCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + } + }, + "title": "ReviewAssessmentCounts", + "type": "object" + }, + "ReviewCitation": { + "additionalProperties": true, + "description": "One citation of the draft (a URL or a DOI where the draft uses it), in\nthe draft's order. Only on a review that asked for the citation check.\n\n``reference`` is the citation as the draft writes it; ``statement`` the\ndraft's sentence it is attached to, with link syntax reduced to its\nwords; ``quotes`` the words the draft quotes from this source.\n``position`` locates ``statement`` in the text as sent (its ``text`` is\n``None``: the row carries the ``statement``). ``result`` is\n``None`` until the check has ended, and on a failed row with nothing\nestablished.", + "properties": { + "check": { + "$ref": "#/$defs/ReviewCitationCheck" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationResult" + }, + { + "type": "null" + } + ], + "default": null + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitation", + "type": "object" + }, + "ReviewCitationCheck": { + "additionalProperties": true, + "description": "A citation's check. ``status`` is progress, as on ``assessment``:\n``pending`` | ``running`` | ``completed`` | ``failed``.\n\n- ``page_read``: ``full``, ``partial``, ``not_found`` or ``none``.\n- ``source_url``: where the text was actually read from (after\n redirects, or a free copy of a paper). ``source_version``, for a DOI:\n ``published``, ``accepted`` or ``submitted``.\n- ``support``: ``supported``, ``partly_supported``, ``contradicted``,\n ``not_in_source`` or ``unchecked``. ``snippet`` is the verified passage\n of the source it rests on; ``rationale`` is a reviewer's note, not a\n checked source.\n- ``quote``: ``matched``, ``not_in_source`` or ``unchecked``; ``None``\n when the draft quoted nothing from this source. ``missing_quote`` is\n the quoted excerpt the quote check did not find; ``None`` unless\n ``quote`` is ``not_in_source``.\n- ``doi_registered``, ``metadata`` (``consistent``, ``mismatch`` or\n ``unchecked``), ``metadata_differences`` and ``registered``: set for a\n DOI only.\n- ``unchecked_reason`` and ``hint``: why the finding is ``unchecked`` and\n what to do next. The reasons are an open set, e.g. ``no_text``,\n ``partial_text``, ``login_required``, ``unsupported_site``,\n ``no_statement``, ``invalid_url``, ``other_version``, ``inconclusive``,\n ``ambiguous_reference``.\n- ``failure``: on a ``failed`` check.", + "properties": { + "doi_registered": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi Registered" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "metadata": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Metadata" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Language" + }, + "page_published_date": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Published Date" + }, + "page_read": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Read" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Quote" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "registered": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationRecord" + }, + { + "type": "null" + } + ], + "default": null + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Url" + }, + "source_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Version" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "support": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Support" + }, + "unchecked_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Unchecked Reason" + } + }, + "title": "ReviewCitationCheck", + "type": "object" + }, + "ReviewCitationCheckCounts": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationFailure": { + "additionalProperties": true, + "description": "A citation whose check failed with nothing established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + } + }, + "title": "ReviewCitationFailure", + "type": "object" + }, + "ReviewCitationIssue": { + "additionalProperties": true, + "description": "A citation whose finding is an issue (see ``ReviewCitationResult``);\nmost serious first, then in the draft's order.\n\n``snippet`` and ``rationale`` are set only when ``source`` is\n``support``. On ``quote_not_in_source``, ``missing_quote`` is the quoted\nexcerpt that was not found. On ``metadata_mismatch``,\n``metadata_differences`` says what differs. ``failure`` is set when another part of the check failed after\nthe finding was established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitationIssue", + "type": "object" + }, + "ReviewCitationRecord": { + "additionalProperties": true, + "description": "A DOI's record in the registry.", + "properties": { + "authors": { + "items": { + "type": "string" + }, + "title": "Authors", + "type": "array" + }, + "journal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Journal" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Title" + }, + "year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Year" + } + }, + "title": "ReviewCitationRecord", + "type": "object" + }, + "ReviewCitationResult": { + "additionalProperties": true, + "description": "The one answer to read for a citation, derived from its ``check``.\n\n``finding``, most serious first: ``doi_not_found``, ``page_not_found``,\n``contradicted``, ``quote_not_in_source``, ``not_in_source``,\n``partly_supported``, ``metadata_mismatch`` (each an issue), then\n``supported`` and ``unchecked``. ``source`` says which check the finding\ncame from: ``doi``, ``page``, ``support``, ``quote`` or ``metadata``;\n``None`` on ``unchecked``.", + "properties": { + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + } + }, + "title": "ReviewCitationResult", + "type": "object" + }, + "ReviewClaim": { + "additionalProperties": true, + "description": "One claim of the draft, in the order the draft's claims were read.\n\n``result`` is ``None`` until the quick check completes, and on a failed\none. ``escalation`` is ``None`` until then too. ``verification`` is set\nonce a deep check was planned for the claim.\n\n``positions`` lists every place the draft makes the claim, in text\norder, at most 10 (see ``Position``). ``start`` / ``end`` index the\n``text`` you sent in Unicode code points (``text[start:end]`` in Python;\n``end`` exclusive), the same coordinates as a citation's ``position``.\nFor a URL draft, ``start`` and ``end`` are ``None`` and ``text`` carries\nthe passage. ``positions`` is ``None`` when the claims could not be\nlocated, or once a zero-retention draft is gone (and from servers that\npredate the field).", + "properties": { + "assessment": { + "$ref": "#/$defs/ReviewAssessment" + }, + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "escalation": { + "anyOf": [ + { + "$ref": "#/$defs/Escalation" + }, + { + "type": "null" + } + ], + "default": null + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewResult" + }, + { + "type": "null" + } + ], + "default": null + }, + "suggested_edits": { + "anyOf": [ + { + "$ref": "#/$defs/SuggestedEdits" + }, + { + "type": "null" + } + ], + "default": null + }, + "verification": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewVerification" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "title": "ReviewClaim", + "type": "object" + }, + "ReviewCredits": { + "additionalProperties": true, + "description": "``charged`` is the net credits the review cost the account, its\ncitation checks included. It is final once no deep check or citation\ncheck is running: read it at ``completed``.", + "properties": { + "charged": { + "default": 0, + "title": "Charged", + "type": "integer" + } + }, + "title": "ReviewCredits", + "type": "object" + }, + "ReviewEntity": { + "additionalProperties": true, + "description": "An entity the deep check found in the claim. ``qid`` is its Wikidata\nid when resolved. Either may be ``None``.", + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Name" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "ReviewEntity", + "type": "object" + }, + "ReviewFailure": { + "additionalProperties": true, + "description": "A claim outside the issues whose work failed. ``stage`` is\n``assessment`` or ``verification``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "stage": { + "default": "", + "title": "Stage", + "type": "string" + } + }, + "title": "ReviewFailure", + "type": "object" + }, + "ReviewIssue": { + "additionalProperties": true, + "description": "A claim whose final verdict is ``False``, ``Mostly False`` or ``Mixed``.\n\n``source`` says which check the verdict comes from: ``verification`` (a\ndeep check, with ``verification_id``, ``url`` and ``key_finding``) or\n``assessment`` (the quick check only; ``escalation`` says why it was not\ndeep-checked, and ``rationale`` is the reviewers' note).\n``verified_claim`` is the deep check's wording of the claim when it\ndiffers from ``claim``. ``failure`` is set when the claim's deep check\nfailed.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "escalation": { + "anyOf": [ + { + "$ref": "#/$defs/Escalation" + }, + { + "type": "null" + } + ], + "default": null + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "suggested_edits": { + "anyOf": [ + { + "$ref": "#/$defs/SuggestedEdits" + }, + { + "type": "null" + } + ], + "default": null + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Status" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "verified_claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verified Claim" + } + }, + "title": "ReviewIssue", + "type": "object" + }, + "ReviewMoreCitation": { + "additionalProperties": true, + "description": "A citation found in the draft past the ones this review checked:\nfound but not checked. Send it in a later request to check it.\n``sentence`` is the draft's sentence around it.", + "properties": { + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Sentence" + } + }, + "title": "ReviewMoreCitation", + "type": "object" + }, + "ReviewResult": { + "additionalProperties": true, + "description": "The one answer to read for a claim: the deep check's verdict when it\ncompleted, else the quick check's. ``source`` says which\n(``assessment`` or ``verification``).", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + } + }, + "title": "ReviewResult", + "type": "object" + }, + "ReviewSummary": { + "additionalProperties": true, + "description": "Counts over the review. A count is ``None`` until what it counts is\nknown (``claims_selected`` before the draft has been read).\n\nThe ``citation*`` counts are ``None`` (``citation_issues`` 0) on a review\nthat did not ask for the citation check.", + "properties": { + "assessments": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewAssessmentCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_checks": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationCheckCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_issues": { + "default": 0, + "title": "Citation Issues", + "type": "integer" + }, + "citation_limit": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit" + }, + "citation_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit Reached" + }, + "citations_found": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Found" + }, + "citations_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Selected" + }, + "citations_skipped": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Skipped" + }, + "claim_limit": { + "default": 20, + "title": "Claim Limit", + "type": "integer" + }, + "claim_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim Limit Reached" + }, + "claims_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claims Selected" + }, + "input_truncated": { + "default": false, + "title": "Input Truncated", + "type": "boolean" + }, + "issues": { + "default": 0, + "title": "Issues", + "type": "integer" + }, + "verifications": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewVerificationCounts" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "title": "ReviewSummary", + "type": "object" + }, + "ReviewVerification": { + "additionalProperties": true, + "description": "A claim's deep check. ``status``: ``processing`` | ``completed`` |\n``failed``; while ``processing`` only ``status``, ``content_status`` and\nthe ids are set. ``content_status`` is ``purged`` once the verification\nwas deleted or removed by its account's retention period: the verdict and\nids stay, the text fields and links are ``None``.\n\n``visibility`` and ``depth`` are what the verification actually has: a\nverdict served from an earlier check keeps its own visibility and may be\n``standard`` for a ``low`` request. Sources are on the verification\nitself: ``client.verifications.get(verification_id)``, or ``url``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "content_status": { + "default": "available", + "title": "Content Status", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "depth": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Depth" + }, + "domain": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Domain" + }, + "entities": { + "items": { + "$ref": "#/$defs/ReviewEntity" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Executive Summary" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Language" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "task_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Task Id" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verdict" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "visibility": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Visibility" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "ReviewVerification", + "type": "object" + }, + "ReviewVerificationCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "planned": { + "default": 0, + "title": "Planned", + "type": "integer" + } + }, + "title": "ReviewVerificationCounts", + "type": "object" + }, + "SuggestedEdit": { + "additionalProperties": true, + "description": "One replacement in the draft: the span ``start``..``end`` of the\n``text`` you sent (Unicode code points, ``end`` exclusive, as in\n``Position``), ``text`` exactly that slice, and ``replacement`` what takes\nits place (``\"\"`` deletes it). ``position`` is the index of the claim\nrow's ``positions`` entry the edit sits in, for grouping by passage.\n\nCompare ``text`` with your draft before you apply an edit, so a draft that\nchanged since is never edited in the wrong place.", + "properties": { + "end": { + "default": 0, + "title": "End", + "type": "integer" + }, + "position": { + "default": 0, + "title": "Position", + "type": "integer" + }, + "replacement": { + "default": "", + "title": "Replacement", + "type": "string" + }, + "start": { + "default": 0, + "title": "Start", + "type": "integer" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "SuggestedEdit", + "type": "object" + }, + "SuggestedEdits": { + "additionalProperties": true, + "description": "The smallest edits to the draft that make it say what the claim's\n``suggested_rewrite`` says (the deep check's, or the quick check's on a\nclaim that stayed on the quick verdict), in the draft's own language\n(``review(..., suggest_edits=True)``).\n\n``status`` is ``\"pending\"`` while they are computed (``edits`` is\n``None``; keep polling) and ``\"completed\"`` once settled, which includes\nsettling on none (``edits == []``: no edit could be made safely, or it\ncould not be computed). They are not themselves verified:\nreview them before you publish.", + "properties": { + "edits": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/SuggestedEdit" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Edits" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + } + }, + "title": "SuggestedEdits", + "type": "object" + } + }, + "additionalProperties": true, + "description": "``GET /reviews/{review_id}``: the envelope plus every claim.", + "properties": { + "citation_failures": { + "items": { + "$ref": "#/$defs/ReviewCitationFailure" + }, + "title": "Citation Failures", + "type": "array" + }, + "citation_issues": { + "items": { + "$ref": "#/$defs/ReviewCitationIssue" + }, + "title": "Citation Issues", + "type": "array" + }, + "citations": { + "items": { + "$ref": "#/$defs/ReviewCitation" + }, + "title": "Citations", + "type": "array" + }, + "claims": { + "items": { + "$ref": "#/$defs/ReviewClaim" + }, + "title": "Claims", + "type": "array" + }, + "completed_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Completed At" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "credits": { + "$ref": "#/$defs/ReviewCredits" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "failures": { + "items": { + "$ref": "#/$defs/ReviewFailure" + }, + "title": "Failures", + "type": "array" + }, + "issues": { + "items": { + "$ref": "#/$defs/ReviewIssue" + }, + "title": "Issues", + "type": "array" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "more_citations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ReviewMoreCitation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Citations" + }, + "more_claim_locations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ClaimLocation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Claim Locations" + }, + "more_claims": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Claims" + }, + "outcome": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Outcome" + }, + "policy": { + "$ref": "#/$defs/EscalationPolicy" + }, + "poll_after_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Poll After Seconds" + }, + "review_id": { + "default": "", + "title": "Review Id", + "type": "string" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "summary": { + "$ref": "#/$defs/ReviewSummary" + }, + "view": { + "default": "full", + "title": "View", + "type": "string" + } + }, + "title": "ReviewFull", + "type": "object" + }, + "ReviewFull:validation": { + "$defs": { + "ClaimLocation": { + "additionalProperties": true, + "description": "Where the submitted text makes one claim.\n\n``claim`` is exactly as in the claim list it belongs to\n(``ExtractedClaims.claim`` / ``identified_claims``, or a review's\n``more_claims``). ``positions`` lists every place the text makes it, in\ntext order, at most 10. It is ``None`` only when that claim could not be\nplaced; on ``/extract`` every returned claim is placed.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + } + }, + "title": "ClaimLocation", + "type": "object" + }, + "Escalation": { + "additionalProperties": true, + "description": "Why a claim was, or was not, deep-checked.\n\n``matched_rules`` lists the rules the quick check matched (``verdict``,\n``confidence``, both, or neither). ``disposition`` says what happened:\n``planned`` (deep-checked), ``not_selected`` (no rule matched), ``cap``\n(matched, but ``max_verifications`` was reached), ``credits`` (matched,\nbut the balance ran out) or ``account_cap`` (matched, but the account's\nallowance of concurrent deep checks was reached). To deep-check the\n``cap`` rows yourself, send their claims to ``verify_batch_and_wait``.", + "properties": { + "disposition": { + "default": "", + "title": "Disposition", + "type": "string" + }, + "matched_rules": { + "items": { + "type": "string" + }, + "title": "Matched Rules", + "type": "array" + } + }, + "title": "Escalation", + "type": "object" + }, + "EscalationPolicy": { + "additionalProperties": true, + "description": "Which quick-checked claims get a deep check, as the review RESOLVED it.\n\nA claim is deep-checked when its quick verdict is in ``verdicts`` OR its\nconfidence band is in ``confidence``, up to ``max_verifications`` of them,\nat ``depth``. ``max_assessments`` is how many of the draft's claims, most\ncheck-worthy first, got a quick verdict.", + "properties": { + "confidence": { + "items": { + "type": "string" + }, + "title": "Confidence", + "type": "array" + }, + "depth": { + "default": "standard", + "title": "Depth", + "type": "string" + }, + "max_assessments": { + "default": 20, + "title": "Max Assessments", + "type": "integer" + }, + "max_citations": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max Citations" + }, + "max_verifications": { + "default": 5, + "title": "Max Verifications", + "type": "integer" + }, + "suggest_edits": { + "default": false, + "title": "Suggest Edits", + "type": "boolean" + }, + "verdicts": { + "items": { + "type": "string" + }, + "title": "Verdicts", + "type": "array" + } + }, + "title": "EscalationPolicy", + "type": "object" + }, + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewAssessment": { + "additionalProperties": true, + "description": "A claim's quick check. ``status``: ``pending`` | ``running`` |\n``completed`` | ``failed``. On ``completed`` the fields mean what they\nmean on an ``/assess`` row; on ``failed`` see ``error_code`` (an open\nset, as on ``/assess``), ``hint`` and ``failure``.", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "dissent": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Dissent" + }, + "error_code": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Error Code" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "identified_claims": { + "items": { + "type": "string" + }, + "title": "Identified Claims", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verdict" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + } + }, + "title": "ReviewAssessment", + "type": "object" + }, + "ReviewAssessmentCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + } + }, + "title": "ReviewAssessmentCounts", + "type": "object" + }, + "ReviewCitation": { + "additionalProperties": true, + "description": "One citation of the draft (a URL or a DOI where the draft uses it), in\nthe draft's order. Only on a review that asked for the citation check.\n\n``reference`` is the citation as the draft writes it; ``statement`` the\ndraft's sentence it is attached to, with link syntax reduced to its\nwords; ``quotes`` the words the draft quotes from this source.\n``position`` locates ``statement`` in the text as sent (its ``text`` is\n``None``: the row carries the ``statement``). ``result`` is\n``None`` until the check has ended, and on a failed row with nothing\nestablished.", + "properties": { + "check": { + "$ref": "#/$defs/ReviewCitationCheck" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationResult" + }, + { + "type": "null" + } + ], + "default": null + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitation", + "type": "object" + }, + "ReviewCitationCheck": { + "additionalProperties": true, + "description": "A citation's check. ``status`` is progress, as on ``assessment``:\n``pending`` | ``running`` | ``completed`` | ``failed``.\n\n- ``page_read``: ``full``, ``partial``, ``not_found`` or ``none``.\n- ``source_url``: where the text was actually read from (after\n redirects, or a free copy of a paper). ``source_version``, for a DOI:\n ``published``, ``accepted`` or ``submitted``.\n- ``support``: ``supported``, ``partly_supported``, ``contradicted``,\n ``not_in_source`` or ``unchecked``. ``snippet`` is the verified passage\n of the source it rests on; ``rationale`` is a reviewer's note, not a\n checked source.\n- ``quote``: ``matched``, ``not_in_source`` or ``unchecked``; ``None``\n when the draft quoted nothing from this source. ``missing_quote`` is\n the quoted excerpt the quote check did not find; ``None`` unless\n ``quote`` is ``not_in_source``.\n- ``doi_registered``, ``metadata`` (``consistent``, ``mismatch`` or\n ``unchecked``), ``metadata_differences`` and ``registered``: set for a\n DOI only.\n- ``unchecked_reason`` and ``hint``: why the finding is ``unchecked`` and\n what to do next. The reasons are an open set, e.g. ``no_text``,\n ``partial_text``, ``login_required``, ``unsupported_site``,\n ``no_statement``, ``invalid_url``, ``other_version``, ``inconclusive``,\n ``ambiguous_reference``.\n- ``failure``: on a ``failed`` check.", + "properties": { + "doi_registered": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi Registered" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "metadata": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Metadata" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Language" + }, + "page_published_date": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Published Date" + }, + "page_read": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Read" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Quote" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "registered": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationRecord" + }, + { + "type": "null" + } + ], + "default": null + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Url" + }, + "source_version": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source Version" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "support": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Support" + }, + "unchecked_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Unchecked Reason" + } + }, + "title": "ReviewCitationCheck", + "type": "object" + }, + "ReviewCitationCheckCounts": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationFailure": { + "additionalProperties": true, + "description": "A citation whose check failed with nothing established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + } + }, + "title": "ReviewCitationFailure", + "type": "object" + }, + "ReviewCitationIssue": { + "additionalProperties": true, + "description": "A citation whose finding is an issue (see ``ReviewCitationResult``);\nmost serious first, then in the draft's order.\n\n``snippet`` and ``rationale`` are set only when ``source`` is\n``support``. On ``quote_not_in_source``, ``missing_quote`` is the quoted\nexcerpt that was not found. On ``metadata_mismatch``,\n``metadata_differences`` says what differs. ``failure`` is set when another part of the check failed after\nthe finding was established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitationIssue", + "type": "object" + }, + "ReviewCitationRecord": { + "additionalProperties": true, + "description": "A DOI's record in the registry.", + "properties": { + "authors": { + "items": { + "type": "string" + }, + "title": "Authors", + "type": "array" + }, + "journal": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Journal" + }, + "title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Title" + }, + "year": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Year" + } + }, + "title": "ReviewCitationRecord", + "type": "object" + }, + "ReviewCitationResult": { + "additionalProperties": true, + "description": "The one answer to read for a citation, derived from its ``check``.\n\n``finding``, most serious first: ``doi_not_found``, ``page_not_found``,\n``contradicted``, ``quote_not_in_source``, ``not_in_source``,\n``partly_supported``, ``metadata_mismatch`` (each an issue), then\n``supported`` and ``unchecked``. ``source`` says which check the finding\ncame from: ``doi``, ``page``, ``support``, ``quote`` or ``metadata``;\n``None`` on ``unchecked``.", + "properties": { + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + } + }, + "title": "ReviewCitationResult", + "type": "object" + }, + "ReviewClaim": { + "additionalProperties": true, + "description": "One claim of the draft, in the order the draft's claims were read.\n\n``result`` is ``None`` until the quick check completes, and on a failed\none. ``escalation`` is ``None`` until then too. ``verification`` is set\nonce a deep check was planned for the claim.\n\n``positions`` lists every place the draft makes the claim, in text\norder, at most 10 (see ``Position``). ``start`` / ``end`` index the\n``text`` you sent in Unicode code points (``text[start:end]`` in Python;\n``end`` exclusive), the same coordinates as a citation's ``position``.\nFor a URL draft, ``start`` and ``end`` are ``None`` and ``text`` carries\nthe passage. ``positions`` is ``None`` when the claims could not be\nlocated, or once a zero-retention draft is gone (and from servers that\npredate the field).", + "properties": { + "assessment": { + "$ref": "#/$defs/ReviewAssessment" + }, + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "escalation": { + "anyOf": [ + { + "$ref": "#/$defs/Escalation" + }, + { + "type": "null" + } + ], + "default": null + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewResult" + }, + { + "type": "null" + } + ], + "default": null + }, + "suggested_edits": { + "anyOf": [ + { + "$ref": "#/$defs/SuggestedEdits" + }, + { + "type": "null" + } + ], + "default": null + }, + "verification": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewVerification" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "title": "ReviewClaim", + "type": "object" + }, + "ReviewCredits": { + "additionalProperties": true, + "description": "``charged`` is the net credits the review cost the account, its\ncitation checks included. It is final once no deep check or citation\ncheck is running: read it at ``completed``.", + "properties": { + "charged": { + "default": 0, + "title": "Charged", + "type": "integer" + } + }, + "title": "ReviewCredits", + "type": "object" + }, + "ReviewEntity": { + "additionalProperties": true, + "description": "An entity the deep check found in the claim. ``qid`` is its Wikidata\nid when resolved. Either may be ``None``.", + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Name" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "ReviewEntity", + "type": "object" + }, + "ReviewFailure": { + "additionalProperties": true, + "description": "A claim outside the issues whose work failed. ``stage`` is\n``assessment`` or ``verification``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "stage": { + "default": "", + "title": "Stage", + "type": "string" + } + }, + "title": "ReviewFailure", + "type": "object" + }, + "ReviewIssue": { + "additionalProperties": true, + "description": "A claim whose final verdict is ``False``, ``Mostly False`` or ``Mixed``.\n\n``source`` says which check the verdict comes from: ``verification`` (a\ndeep check, with ``verification_id``, ``url`` and ``key_finding``) or\n``assessment`` (the quick check only; ``escalation`` says why it was not\ndeep-checked, and ``rationale`` is the reviewers' note).\n``verified_claim`` is the deep check's wording of the claim when it\ndiffers from ``claim``. ``failure`` is set when the claim's deep check\nfailed.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "escalation": { + "anyOf": [ + { + "$ref": "#/$defs/Escalation" + }, + { + "type": "null" + } + ], + "default": null + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "suggested_edits": { + "anyOf": [ + { + "$ref": "#/$defs/SuggestedEdits" + }, + { + "type": "null" + } + ], + "default": null + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Status" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "verified_claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verified Claim" + } + }, + "title": "ReviewIssue", + "type": "object" + }, + "ReviewMoreCitation": { + "additionalProperties": true, + "description": "A citation found in the draft past the ones this review checked:\nfound but not checked. Send it in a later request to check it.\n``sentence`` is the draft's sentence around it.", + "properties": { + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Sentence" + } + }, + "title": "ReviewMoreCitation", + "type": "object" + }, + "ReviewResult": { + "additionalProperties": true, + "description": "The one answer to read for a claim: the deep check's verdict when it\ncompleted, else the quick check's. ``source`` says which\n(``assessment`` or ``verification``).", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + } + }, + "title": "ReviewResult", + "type": "object" + }, + "ReviewSummary": { + "additionalProperties": true, + "description": "Counts over the review. A count is ``None`` until what it counts is\nknown (``claims_selected`` before the draft has been read).\n\nThe ``citation*`` counts are ``None`` (``citation_issues`` 0) on a review\nthat did not ask for the citation check.", + "properties": { + "assessments": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewAssessmentCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_checks": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationCheckCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_issues": { + "default": 0, + "title": "Citation Issues", + "type": "integer" + }, + "citation_limit": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit" + }, + "citation_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit Reached" + }, + "citations_found": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Found" + }, + "citations_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Selected" + }, + "citations_skipped": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Skipped" + }, + "claim_limit": { + "default": 20, + "title": "Claim Limit", + "type": "integer" + }, + "claim_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim Limit Reached" + }, + "claims_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claims Selected" + }, + "input_truncated": { + "default": false, + "title": "Input Truncated", + "type": "boolean" + }, + "issues": { + "default": 0, + "title": "Issues", + "type": "integer" + }, + "verifications": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewVerificationCounts" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "title": "ReviewSummary", + "type": "object" + }, + "ReviewVerification": { + "additionalProperties": true, + "description": "A claim's deep check. ``status``: ``processing`` | ``completed`` |\n``failed``; while ``processing`` only ``status``, ``content_status`` and\nthe ids are set. ``content_status`` is ``purged`` once the verification\nwas deleted or removed by its account's retention period: the verdict and\nids stay, the text fields and links are ``None``.\n\n``visibility`` and ``depth`` are what the verification actually has: a\nverdict served from an earlier check keeps its own visibility and may be\n``standard`` for a ``low`` request. Sources are on the verification\nitself: ``client.verifications.get(verification_id)``, or ``url``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "content_status": { + "default": "available", + "title": "Content Status", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "depth": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Depth" + }, + "domain": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Domain" + }, + "entities": { + "items": { + "$ref": "#/$defs/ReviewEntity" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Executive Summary" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Language" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "task_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Task Id" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verdict" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "visibility": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Visibility" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "ReviewVerification", + "type": "object" + }, + "ReviewVerificationCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "planned": { + "default": 0, + "title": "Planned", + "type": "integer" + } + }, + "title": "ReviewVerificationCounts", + "type": "object" + }, + "SuggestedEdit": { + "additionalProperties": true, + "description": "One replacement in the draft: the span ``start``..``end`` of the\n``text`` you sent (Unicode code points, ``end`` exclusive, as in\n``Position``), ``text`` exactly that slice, and ``replacement`` what takes\nits place (``\"\"`` deletes it). ``position`` is the index of the claim\nrow's ``positions`` entry the edit sits in, for grouping by passage.\n\nCompare ``text`` with your draft before you apply an edit, so a draft that\nchanged since is never edited in the wrong place.", + "properties": { + "end": { + "default": 0, + "title": "End", + "type": "integer" + }, + "position": { + "default": 0, + "title": "Position", + "type": "integer" + }, + "replacement": { + "default": "", + "title": "Replacement", + "type": "string" + }, + "start": { + "default": 0, + "title": "Start", + "type": "integer" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "SuggestedEdit", + "type": "object" + }, + "SuggestedEdits": { + "additionalProperties": true, + "description": "The smallest edits to the draft that make it say what the claim's\n``suggested_rewrite`` says (the deep check's, or the quick check's on a\nclaim that stayed on the quick verdict), in the draft's own language\n(``review(..., suggest_edits=True)``).\n\n``status`` is ``\"pending\"`` while they are computed (``edits`` is\n``None``; keep polling) and ``\"completed\"`` once settled, which includes\nsettling on none (``edits == []``: no edit could be made safely, or it\ncould not be computed). They are not themselves verified:\nreview them before you publish.", + "properties": { + "edits": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/SuggestedEdit" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Edits" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + } + }, + "title": "SuggestedEdits", + "type": "object" + } + }, + "additionalProperties": true, + "description": "``GET /reviews/{review_id}``: the envelope plus every claim.", + "properties": { + "citation_failures": { + "items": { + "$ref": "#/$defs/ReviewCitationFailure" + }, + "title": "Citation Failures", + "type": "array" + }, + "citation_issues": { + "items": { + "$ref": "#/$defs/ReviewCitationIssue" + }, + "title": "Citation Issues", + "type": "array" + }, + "citations": { + "items": { + "$ref": "#/$defs/ReviewCitation" + }, + "title": "Citations", + "type": "array" + }, + "claims": { + "items": { + "$ref": "#/$defs/ReviewClaim" + }, + "title": "Claims", + "type": "array" + }, + "completed_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Completed At" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "credits": { + "$ref": "#/$defs/ReviewCredits" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "failures": { + "items": { + "$ref": "#/$defs/ReviewFailure" + }, + "title": "Failures", + "type": "array" + }, + "issues": { + "items": { + "$ref": "#/$defs/ReviewIssue" + }, + "title": "Issues", + "type": "array" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "more_citations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ReviewMoreCitation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Citations" + }, + "more_claim_locations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ClaimLocation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Claim Locations" + }, + "more_claims": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Claims" + }, + "outcome": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Outcome" + }, + "policy": { + "$ref": "#/$defs/EscalationPolicy" + }, + "poll_after_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Poll After Seconds" + }, + "review_id": { + "default": "", + "title": "Review Id", + "type": "string" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "summary": { + "$ref": "#/$defs/ReviewSummary" + }, + "view": { + "default": "full", + "title": "View", + "type": "string" + } + }, + "title": "ReviewFull", + "type": "object" + }, + "ReviewIssue:serialization": { + "$defs": { + "Escalation": { + "additionalProperties": true, + "description": "Why a claim was, or was not, deep-checked.\n\n``matched_rules`` lists the rules the quick check matched (``verdict``,\n``confidence``, both, or neither). ``disposition`` says what happened:\n``planned`` (deep-checked), ``not_selected`` (no rule matched), ``cap``\n(matched, but ``max_verifications`` was reached), ``credits`` (matched,\nbut the balance ran out) or ``account_cap`` (matched, but the account's\nallowance of concurrent deep checks was reached). To deep-check the\n``cap`` rows yourself, send their claims to ``verify_batch_and_wait``.", + "properties": { + "disposition": { + "default": "", + "title": "Disposition", + "type": "string" + }, + "matched_rules": { + "items": { + "type": "string" + }, + "title": "Matched Rules", + "type": "array" + } + }, + "title": "Escalation", + "type": "object" + }, + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "SuggestedEdit": { + "additionalProperties": true, + "description": "One replacement in the draft: the span ``start``..``end`` of the\n``text`` you sent (Unicode code points, ``end`` exclusive, as in\n``Position``), ``text`` exactly that slice, and ``replacement`` what takes\nits place (``\"\"`` deletes it). ``position`` is the index of the claim\nrow's ``positions`` entry the edit sits in, for grouping by passage.\n\nCompare ``text`` with your draft before you apply an edit, so a draft that\nchanged since is never edited in the wrong place.", + "properties": { + "end": { + "default": 0, + "title": "End", + "type": "integer" + }, + "position": { + "default": 0, + "title": "Position", + "type": "integer" + }, + "replacement": { + "default": "", + "title": "Replacement", + "type": "string" + }, + "start": { + "default": 0, + "title": "Start", + "type": "integer" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "SuggestedEdit", + "type": "object" + }, + "SuggestedEdits": { + "additionalProperties": true, + "description": "The smallest edits to the draft that make it say what the claim's\n``suggested_rewrite`` says (the deep check's, or the quick check's on a\nclaim that stayed on the quick verdict), in the draft's own language\n(``review(..., suggest_edits=True)``).\n\n``status`` is ``\"pending\"`` while they are computed (``edits`` is\n``None``; keep polling) and ``\"completed\"`` once settled, which includes\nsettling on none (``edits == []``: no edit could be made safely, or it\ncould not be computed). They are not themselves verified:\nreview them before you publish.", + "properties": { + "edits": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/SuggestedEdit" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Edits" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + } + }, + "title": "SuggestedEdits", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A claim whose final verdict is ``False``, ``Mostly False`` or ``Mixed``.\n\n``source`` says which check the verdict comes from: ``verification`` (a\ndeep check, with ``verification_id``, ``url`` and ``key_finding``) or\n``assessment`` (the quick check only; ``escalation`` says why it was not\ndeep-checked, and ``rationale`` is the reviewers' note).\n``verified_claim`` is the deep check's wording of the claim when it\ndiffers from ``claim``. ``failure`` is set when the claim's deep check\nfailed.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "escalation": { + "anyOf": [ + { + "$ref": "#/$defs/Escalation" + }, + { + "type": "null" + } + ], + "default": null + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "suggested_edits": { + "anyOf": [ + { + "$ref": "#/$defs/SuggestedEdits" + }, + { + "type": "null" + } + ], + "default": null + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Status" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "verified_claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verified Claim" + } + }, + "title": "ReviewIssue", + "type": "object" + }, + "ReviewIssue:validation": { + "$defs": { + "Escalation": { + "additionalProperties": true, + "description": "Why a claim was, or was not, deep-checked.\n\n``matched_rules`` lists the rules the quick check matched (``verdict``,\n``confidence``, both, or neither). ``disposition`` says what happened:\n``planned`` (deep-checked), ``not_selected`` (no rule matched), ``cap``\n(matched, but ``max_verifications`` was reached), ``credits`` (matched,\nbut the balance ran out) or ``account_cap`` (matched, but the account's\nallowance of concurrent deep checks was reached). To deep-check the\n``cap`` rows yourself, send their claims to ``verify_batch_and_wait``.", + "properties": { + "disposition": { + "default": "", + "title": "Disposition", + "type": "string" + }, + "matched_rules": { + "items": { + "type": "string" + }, + "title": "Matched Rules", + "type": "array" + } + }, + "title": "Escalation", + "type": "object" + }, + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "SuggestedEdit": { + "additionalProperties": true, + "description": "One replacement in the draft: the span ``start``..``end`` of the\n``text`` you sent (Unicode code points, ``end`` exclusive, as in\n``Position``), ``text`` exactly that slice, and ``replacement`` what takes\nits place (``\"\"`` deletes it). ``position`` is the index of the claim\nrow's ``positions`` entry the edit sits in, for grouping by passage.\n\nCompare ``text`` with your draft before you apply an edit, so a draft that\nchanged since is never edited in the wrong place.", + "properties": { + "end": { + "default": 0, + "title": "End", + "type": "integer" + }, + "position": { + "default": 0, + "title": "Position", + "type": "integer" + }, + "replacement": { + "default": "", + "title": "Replacement", + "type": "string" + }, + "start": { + "default": 0, + "title": "Start", + "type": "integer" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "SuggestedEdit", + "type": "object" + }, + "SuggestedEdits": { + "additionalProperties": true, + "description": "The smallest edits to the draft that make it say what the claim's\n``suggested_rewrite`` says (the deep check's, or the quick check's on a\nclaim that stayed on the quick verdict), in the draft's own language\n(``review(..., suggest_edits=True)``).\n\n``status`` is ``\"pending\"`` while they are computed (``edits`` is\n``None``; keep polling) and ``\"completed\"`` once settled, which includes\nsettling on none (``edits == []``: no edit could be made safely, or it\ncould not be computed). They are not themselves verified:\nreview them before you publish.", + "properties": { + "edits": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/SuggestedEdit" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Edits" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + } + }, + "title": "SuggestedEdits", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A claim whose final verdict is ``False``, ``Mostly False`` or ``Mixed``.\n\n``source`` says which check the verdict comes from: ``verification`` (a\ndeep check, with ``verification_id``, ``url`` and ``key_finding``) or\n``assessment`` (the quick check only; ``escalation`` says why it was not\ndeep-checked, and ``rationale`` is the reviewers' note).\n``verified_claim`` is the deep check's wording of the claim when it\ndiffers from ``claim``. ``failure`` is set when the claim's deep check\nfailed.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "escalation": { + "anyOf": [ + { + "$ref": "#/$defs/Escalation" + }, + { + "type": "null" + } + ], + "default": null + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "suggested_edits": { + "anyOf": [ + { + "$ref": "#/$defs/SuggestedEdits" + }, + { + "type": "null" + } + ], + "default": null + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Status" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "verified_claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verified Claim" + } + }, + "title": "ReviewIssue", + "type": "object" + }, + "ReviewIssues:serialization": { + "$defs": { + "ClaimLocation": { + "additionalProperties": true, + "description": "Where the submitted text makes one claim.\n\n``claim`` is exactly as in the claim list it belongs to\n(``ExtractedClaims.claim`` / ``identified_claims``, or a review's\n``more_claims``). ``positions`` lists every place the text makes it, in\ntext order, at most 10. It is ``None`` only when that claim could not be\nplaced; on ``/extract`` every returned claim is placed.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + } + }, + "title": "ClaimLocation", + "type": "object" + }, + "Escalation": { + "additionalProperties": true, + "description": "Why a claim was, or was not, deep-checked.\n\n``matched_rules`` lists the rules the quick check matched (``verdict``,\n``confidence``, both, or neither). ``disposition`` says what happened:\n``planned`` (deep-checked), ``not_selected`` (no rule matched), ``cap``\n(matched, but ``max_verifications`` was reached), ``credits`` (matched,\nbut the balance ran out) or ``account_cap`` (matched, but the account's\nallowance of concurrent deep checks was reached). To deep-check the\n``cap`` rows yourself, send their claims to ``verify_batch_and_wait``.", + "properties": { + "disposition": { + "default": "", + "title": "Disposition", + "type": "string" + }, + "matched_rules": { + "items": { + "type": "string" + }, + "title": "Matched Rules", + "type": "array" + } + }, + "title": "Escalation", + "type": "object" + }, + "EscalationPolicy": { + "additionalProperties": true, + "description": "Which quick-checked claims get a deep check, as the review RESOLVED it.\n\nA claim is deep-checked when its quick verdict is in ``verdicts`` OR its\nconfidence band is in ``confidence``, up to ``max_verifications`` of them,\nat ``depth``. ``max_assessments`` is how many of the draft's claims, most\ncheck-worthy first, got a quick verdict.", + "properties": { + "confidence": { + "items": { + "type": "string" + }, + "title": "Confidence", + "type": "array" + }, + "depth": { + "default": "standard", + "title": "Depth", + "type": "string" + }, + "max_assessments": { + "default": 20, + "title": "Max Assessments", + "type": "integer" + }, + "max_citations": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max Citations" + }, + "max_verifications": { + "default": 5, + "title": "Max Verifications", + "type": "integer" + }, + "suggest_edits": { + "default": false, + "title": "Suggest Edits", + "type": "boolean" + }, + "verdicts": { + "items": { + "type": "string" + }, + "title": "Verdicts", + "type": "array" + } + }, + "title": "EscalationPolicy", + "type": "object" + }, + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewAssessmentCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + } + }, + "title": "ReviewAssessmentCounts", + "type": "object" + }, + "ReviewCitationCheckCounts": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationFailure": { + "additionalProperties": true, + "description": "A citation whose check failed with nothing established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + } + }, + "title": "ReviewCitationFailure", + "type": "object" + }, + "ReviewCitationIssue": { + "additionalProperties": true, + "description": "A citation whose finding is an issue (see ``ReviewCitationResult``);\nmost serious first, then in the draft's order.\n\n``snippet`` and ``rationale`` are set only when ``source`` is\n``support``. On ``quote_not_in_source``, ``missing_quote`` is the quoted\nexcerpt that was not found. On ``metadata_mismatch``,\n``metadata_differences`` says what differs. ``failure`` is set when another part of the check failed after\nthe finding was established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitationIssue", + "type": "object" + }, + "ReviewCredits": { + "additionalProperties": true, + "description": "``charged`` is the net credits the review cost the account, its\ncitation checks included. It is final once no deep check or citation\ncheck is running: read it at ``completed``.", + "properties": { + "charged": { + "default": 0, + "title": "Charged", + "type": "integer" + } + }, + "title": "ReviewCredits", + "type": "object" + }, + "ReviewFailure": { + "additionalProperties": true, + "description": "A claim outside the issues whose work failed. ``stage`` is\n``assessment`` or ``verification``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "stage": { + "default": "", + "title": "Stage", + "type": "string" + } + }, + "title": "ReviewFailure", + "type": "object" + }, + "ReviewIssue": { + "additionalProperties": true, + "description": "A claim whose final verdict is ``False``, ``Mostly False`` or ``Mixed``.\n\n``source`` says which check the verdict comes from: ``verification`` (a\ndeep check, with ``verification_id``, ``url`` and ``key_finding``) or\n``assessment`` (the quick check only; ``escalation`` says why it was not\ndeep-checked, and ``rationale`` is the reviewers' note).\n``verified_claim`` is the deep check's wording of the claim when it\ndiffers from ``claim``. ``failure`` is set when the claim's deep check\nfailed.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "escalation": { + "anyOf": [ + { + "$ref": "#/$defs/Escalation" + }, + { + "type": "null" + } + ], + "default": null + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "suggested_edits": { + "anyOf": [ + { + "$ref": "#/$defs/SuggestedEdits" + }, + { + "type": "null" + } + ], + "default": null + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Status" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "verified_claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verified Claim" + } + }, + "title": "ReviewIssue", + "type": "object" + }, + "ReviewMoreCitation": { + "additionalProperties": true, + "description": "A citation found in the draft past the ones this review checked:\nfound but not checked. Send it in a later request to check it.\n``sentence`` is the draft's sentence around it.", + "properties": { + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Sentence" + } + }, + "title": "ReviewMoreCitation", + "type": "object" + }, + "ReviewSummary": { + "additionalProperties": true, + "description": "Counts over the review. A count is ``None`` until what it counts is\nknown (``claims_selected`` before the draft has been read).\n\nThe ``citation*`` counts are ``None`` (``citation_issues`` 0) on a review\nthat did not ask for the citation check.", + "properties": { + "assessments": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewAssessmentCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_checks": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationCheckCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_issues": { + "default": 0, + "title": "Citation Issues", + "type": "integer" + }, + "citation_limit": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit" + }, + "citation_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit Reached" + }, + "citations_found": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Found" + }, + "citations_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Selected" + }, + "citations_skipped": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Skipped" + }, + "claim_limit": { + "default": 20, + "title": "Claim Limit", + "type": "integer" + }, + "claim_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim Limit Reached" + }, + "claims_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claims Selected" + }, + "input_truncated": { + "default": false, + "title": "Input Truncated", + "type": "boolean" + }, + "issues": { + "default": 0, + "title": "Issues", + "type": "integer" + }, + "verifications": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewVerificationCounts" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "title": "ReviewSummary", + "type": "object" + }, + "ReviewVerificationCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "planned": { + "default": 0, + "title": "Planned", + "type": "integer" + } + }, + "title": "ReviewVerificationCounts", + "type": "object" + }, + "SuggestedEdit": { + "additionalProperties": true, + "description": "One replacement in the draft: the span ``start``..``end`` of the\n``text`` you sent (Unicode code points, ``end`` exclusive, as in\n``Position``), ``text`` exactly that slice, and ``replacement`` what takes\nits place (``\"\"`` deletes it). ``position`` is the index of the claim\nrow's ``positions`` entry the edit sits in, for grouping by passage.\n\nCompare ``text`` with your draft before you apply an edit, so a draft that\nchanged since is never edited in the wrong place.", + "properties": { + "end": { + "default": 0, + "title": "End", + "type": "integer" + }, + "position": { + "default": 0, + "title": "Position", + "type": "integer" + }, + "replacement": { + "default": "", + "title": "Replacement", + "type": "string" + }, + "start": { + "default": 0, + "title": "Start", + "type": "integer" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "SuggestedEdit", + "type": "object" + }, + "SuggestedEdits": { + "additionalProperties": true, + "description": "The smallest edits to the draft that make it say what the claim's\n``suggested_rewrite`` says (the deep check's, or the quick check's on a\nclaim that stayed on the quick verdict), in the draft's own language\n(``review(..., suggest_edits=True)``).\n\n``status`` is ``\"pending\"`` while they are computed (``edits`` is\n``None``; keep polling) and ``\"completed\"`` once settled, which includes\nsettling on none (``edits == []``: no edit could be made safely, or it\ncould not be computed). They are not themselves verified:\nreview them before you publish.", + "properties": { + "edits": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/SuggestedEdit" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Edits" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + } + }, + "title": "SuggestedEdits", + "type": "object" + } + }, + "additionalProperties": true, + "description": "``GET /reviews/{review_id}?view=issues``: the envelope, no ``claims``.", + "properties": { + "citation_failures": { + "items": { + "$ref": "#/$defs/ReviewCitationFailure" + }, + "title": "Citation Failures", + "type": "array" + }, + "citation_issues": { + "items": { + "$ref": "#/$defs/ReviewCitationIssue" + }, + "title": "Citation Issues", + "type": "array" + }, + "completed_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Completed At" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "credits": { + "$ref": "#/$defs/ReviewCredits" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "failures": { + "items": { + "$ref": "#/$defs/ReviewFailure" + }, + "title": "Failures", + "type": "array" + }, + "issues": { + "items": { + "$ref": "#/$defs/ReviewIssue" + }, + "title": "Issues", + "type": "array" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "more_citations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ReviewMoreCitation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Citations" + }, + "more_claim_locations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ClaimLocation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Claim Locations" + }, + "more_claims": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Claims" + }, + "outcome": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Outcome" + }, + "policy": { + "$ref": "#/$defs/EscalationPolicy" + }, + "poll_after_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Poll After Seconds" + }, + "review_id": { + "default": "", + "title": "Review Id", + "type": "string" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "summary": { + "$ref": "#/$defs/ReviewSummary" + }, + "view": { + "default": "issues", + "title": "View", + "type": "string" + } + }, + "title": "ReviewIssues", + "type": "object" + }, + "ReviewIssues:validation": { + "$defs": { + "ClaimLocation": { + "additionalProperties": true, + "description": "Where the submitted text makes one claim.\n\n``claim`` is exactly as in the claim list it belongs to\n(``ExtractedClaims.claim`` / ``identified_claims``, or a review's\n``more_claims``). ``positions`` lists every place the text makes it, in\ntext order, at most 10. It is ``None`` only when that claim could not be\nplaced; on ``/extract`` every returned claim is placed.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "positions": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/Position" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Positions" + } + }, + "title": "ClaimLocation", + "type": "object" + }, + "Escalation": { + "additionalProperties": true, + "description": "Why a claim was, or was not, deep-checked.\n\n``matched_rules`` lists the rules the quick check matched (``verdict``,\n``confidence``, both, or neither). ``disposition`` says what happened:\n``planned`` (deep-checked), ``not_selected`` (no rule matched), ``cap``\n(matched, but ``max_verifications`` was reached), ``credits`` (matched,\nbut the balance ran out) or ``account_cap`` (matched, but the account's\nallowance of concurrent deep checks was reached). To deep-check the\n``cap`` rows yourself, send their claims to ``verify_batch_and_wait``.", + "properties": { + "disposition": { + "default": "", + "title": "Disposition", + "type": "string" + }, + "matched_rules": { + "items": { + "type": "string" + }, + "title": "Matched Rules", + "type": "array" + } + }, + "title": "Escalation", + "type": "object" + }, + "EscalationPolicy": { + "additionalProperties": true, + "description": "Which quick-checked claims get a deep check, as the review RESOLVED it.\n\nA claim is deep-checked when its quick verdict is in ``verdicts`` OR its\nconfidence band is in ``confidence``, up to ``max_verifications`` of them,\nat ``depth``. ``max_assessments`` is how many of the draft's claims, most\ncheck-worthy first, got a quick verdict.", + "properties": { + "confidence": { + "items": { + "type": "string" + }, + "title": "Confidence", + "type": "array" + }, + "depth": { + "default": "standard", + "title": "Depth", + "type": "string" + }, + "max_assessments": { + "default": 20, + "title": "Max Assessments", + "type": "integer" + }, + "max_citations": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Max Citations" + }, + "max_verifications": { + "default": 5, + "title": "Max Verifications", + "type": "integer" + }, + "suggest_edits": { + "default": false, + "title": "Suggest Edits", + "type": "boolean" + }, + "verdicts": { + "items": { + "type": "string" + }, + "title": "Verdicts", + "type": "array" + } + }, + "title": "EscalationPolicy", + "type": "object" + }, + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + }, + "ReviewAssessmentCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + } + }, + "title": "ReviewAssessmentCounts", + "type": "object" + }, + "ReviewCitationCheckCounts": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + }, + "ReviewCitationDifference": { + "additionalProperties": true, + "description": "One way the reference differs from the registry's record. ``field``\nis ``title``, ``authors``, ``year`` or ``journal``.", + "properties": { + "cited": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited" + }, + "field": { + "default": "", + "title": "Field", + "type": "string" + }, + "registered": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Registered" + } + }, + "title": "ReviewCitationDifference", + "type": "object" + }, + "ReviewCitationFailure": { + "additionalProperties": true, + "description": "A citation whose check failed with nothing established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + } + }, + "title": "ReviewCitationFailure", + "type": "object" + }, + "ReviewCitationIssue": { + "additionalProperties": true, + "description": "A citation whose finding is an issue (see ``ReviewCitationResult``);\nmost serious first, then in the draft's order.\n\n``snippet`` and ``rationale`` are set only when ``source`` is\n``support``. On ``quote_not_in_source``, ``missing_quote`` is the quoted\nexcerpt that was not found. On ``metadata_mismatch``,\n``metadata_differences`` says what differs. ``failure`` is set when another part of the check failed after\nthe finding was established.", + "properties": { + "citation_index": { + "default": 0, + "title": "Citation Index", + "type": "integer" + }, + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "finding": { + "default": "", + "title": "Finding", + "type": "string" + }, + "metadata_differences": { + "items": { + "$ref": "#/$defs/ReviewCitationDifference" + }, + "title": "Metadata Differences", + "type": "array" + }, + "missing_quote": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Missing Quote" + }, + "page_title": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Page Title" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "quotes": { + "items": { + "type": "string" + }, + "title": "Quotes", + "type": "array" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "snippet": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Snippet" + }, + "source": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Source" + }, + "statement": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Statement" + } + }, + "title": "ReviewCitationIssue", + "type": "object" + }, + "ReviewCredits": { + "additionalProperties": true, + "description": "``charged`` is the net credits the review cost the account, its\ncitation checks included. It is final once no deep check or citation\ncheck is running: read it at ``completed``.", + "properties": { + "charged": { + "default": 0, + "title": "Charged", + "type": "integer" + } + }, + "title": "ReviewCredits", + "type": "object" + }, + "ReviewFailure": { + "additionalProperties": true, + "description": "A claim outside the issues whose work failed. ``stage`` is\n``assessment`` or ``verification``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "stage": { + "default": "", + "title": "Stage", + "type": "string" + } + }, + "title": "ReviewFailure", + "type": "object" + }, + "ReviewIssue": { + "additionalProperties": true, + "description": "A claim whose final verdict is ``False``, ``Mostly False`` or ``Mixed``.\n\n``source`` says which check the verdict comes from: ``verification`` (a\ndeep check, with ``verification_id``, ``url`` and ``key_finding``) or\n``assessment`` (the quick check only; ``escalation`` says why it was not\ndeep-checked, and ``rationale`` is the reviewers' note).\n``verified_claim`` is the deep check's wording of the claim when it\ndiffers from ``claim``. ``failure`` is set when the claim's deep check\nfailed.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "claim_index": { + "default": 0, + "title": "Claim Index", + "type": "integer" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "escalation": { + "anyOf": [ + { + "$ref": "#/$defs/Escalation" + }, + { + "type": "null" + } + ], + "default": null + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "rationale": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Rationale" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "suggested_edits": { + "anyOf": [ + { + "$ref": "#/$defs/SuggestedEdits" + }, + { + "type": "null" + } + ], + "default": null + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_status": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Status" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "verified_claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verified Claim" + } + }, + "title": "ReviewIssue", + "type": "object" + }, + "ReviewMoreCitation": { + "additionalProperties": true, + "description": "A citation found in the draft past the ones this review checked:\nfound but not checked. Send it in a later request to check it.\n``sentence`` is the draft's sentence around it.", + "properties": { + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Sentence" + } + }, + "title": "ReviewMoreCitation", + "type": "object" + }, + "ReviewSummary": { + "additionalProperties": true, + "description": "Counts over the review. A count is ``None`` until what it counts is\nknown (``claims_selected`` before the draft has been read).\n\nThe ``citation*`` counts are ``None`` (``citation_issues`` 0) on a review\nthat did not ask for the citation check.", + "properties": { + "assessments": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewAssessmentCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_checks": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationCheckCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_issues": { + "default": 0, + "title": "Citation Issues", + "type": "integer" + }, + "citation_limit": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit" + }, + "citation_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit Reached" + }, + "citations_found": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Found" + }, + "citations_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Selected" + }, + "citations_skipped": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Skipped" + }, + "claim_limit": { + "default": 20, + "title": "Claim Limit", + "type": "integer" + }, + "claim_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim Limit Reached" + }, + "claims_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claims Selected" + }, + "input_truncated": { + "default": false, + "title": "Input Truncated", + "type": "boolean" + }, + "issues": { + "default": 0, + "title": "Issues", + "type": "integer" + }, + "verifications": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewVerificationCounts" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "title": "ReviewSummary", + "type": "object" + }, + "ReviewVerificationCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "planned": { + "default": 0, + "title": "Planned", + "type": "integer" + } + }, + "title": "ReviewVerificationCounts", + "type": "object" + }, + "SuggestedEdit": { + "additionalProperties": true, + "description": "One replacement in the draft: the span ``start``..``end`` of the\n``text`` you sent (Unicode code points, ``end`` exclusive, as in\n``Position``), ``text`` exactly that slice, and ``replacement`` what takes\nits place (``\"\"`` deletes it). ``position`` is the index of the claim\nrow's ``positions`` entry the edit sits in, for grouping by passage.\n\nCompare ``text`` with your draft before you apply an edit, so a draft that\nchanged since is never edited in the wrong place.", + "properties": { + "end": { + "default": 0, + "title": "End", + "type": "integer" + }, + "position": { + "default": 0, + "title": "Position", + "type": "integer" + }, + "replacement": { + "default": "", + "title": "Replacement", + "type": "string" + }, + "start": { + "default": 0, + "title": "Start", + "type": "integer" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "SuggestedEdit", + "type": "object" + }, + "SuggestedEdits": { + "additionalProperties": true, + "description": "The smallest edits to the draft that make it say what the claim's\n``suggested_rewrite`` says (the deep check's, or the quick check's on a\nclaim that stayed on the quick verdict), in the draft's own language\n(``review(..., suggest_edits=True)``).\n\n``status`` is ``\"pending\"`` while they are computed (``edits`` is\n``None``; keep polling) and ``\"completed\"`` once settled, which includes\nsettling on none (``edits == []``: no edit could be made safely, or it\ncould not be computed). They are not themselves verified:\nreview them before you publish.", + "properties": { + "edits": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/SuggestedEdit" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Edits" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + } + }, + "title": "SuggestedEdits", + "type": "object" + } + }, + "additionalProperties": true, + "description": "``GET /reviews/{review_id}?view=issues``: the envelope, no ``claims``.", + "properties": { + "citation_failures": { + "items": { + "$ref": "#/$defs/ReviewCitationFailure" + }, + "title": "Citation Failures", + "type": "array" + }, + "citation_issues": { + "items": { + "$ref": "#/$defs/ReviewCitationIssue" + }, + "title": "Citation Issues", + "type": "array" + }, + "completed_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Completed At" + }, + "created_at": { + "default": "", + "title": "Created At", + "type": "string" + }, + "credits": { + "$ref": "#/$defs/ReviewCredits" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "failures": { + "items": { + "$ref": "#/$defs/ReviewFailure" + }, + "title": "Failures", + "type": "array" + }, + "issues": { + "items": { + "$ref": "#/$defs/ReviewIssue" + }, + "title": "Issues", + "type": "array" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "more_citations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ReviewMoreCitation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Citations" + }, + "more_claim_locations": { + "anyOf": [ + { + "items": { + "$ref": "#/$defs/ClaimLocation" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Claim Locations" + }, + "more_claims": { + "anyOf": [ + { + "items": { + "type": "string" + }, + "type": "array" + }, + { + "type": "null" + } + ], + "default": null, + "title": "More Claims" + }, + "outcome": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Outcome" + }, + "policy": { + "$ref": "#/$defs/EscalationPolicy" + }, + "poll_after_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Poll After Seconds" + }, + "review_id": { + "default": "", + "title": "Review Id", + "type": "string" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "summary": { + "$ref": "#/$defs/ReviewSummary" + }, + "view": { + "default": "issues", + "title": "View", + "type": "string" + } + }, + "title": "ReviewIssues", + "type": "object" + }, + "ReviewMoreCitation:serialization": { + "$defs": { + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A citation found in the draft past the ones this review checked:\nfound but not checked. Send it in a later request to check it.\n``sentence`` is the draft's sentence around it.", + "properties": { + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Sentence" + } + }, + "title": "ReviewMoreCitation", + "type": "object" + }, + "ReviewMoreCitation:validation": { + "$defs": { + "Position": { + "additionalProperties": true, + "description": "One place in the text you sent: a claim's passage, or a citation's\nstatement.\n\n``start`` and ``end`` index the ``text`` you sent, in Unicode code\npoints (not UTF-16 units or bytes), half-open: ``text[start:end]`` is\nthe passage in Python, ``end`` exclusive. Both are ``None`` when the\ninput was a URL: the page is not returned, so there is nothing to index,\nand ``text`` carries the passage instead.\n\n``text`` is the passage as it appears in the text. It is ``None`` on a\ncitation's ``position``, whose row already carries the ``statement``.", + "properties": { + "end": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "End" + }, + "start": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Start" + }, + "text": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Text" + } + }, + "title": "Position", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A citation found in the draft past the ones this review checked:\nfound but not checked. Send it in a later request to check it.\n``sentence`` is the draft's sentence around it.", + "properties": { + "cited_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Cited Url" + }, + "doi": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Doi" + }, + "index": { + "default": 0, + "title": "Index", + "type": "integer" + }, + "position": { + "anyOf": [ + { + "$ref": "#/$defs/Position" + }, + { + "type": "null" + } + ], + "default": null + }, + "reference": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Reference" + }, + "sentence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Sentence" + } + }, + "title": "ReviewMoreCitation", + "type": "object" + }, + "ReviewResult:serialization": { + "additionalProperties": true, + "description": "The one answer to read for a claim: the deep check's verdict when it\ncompleted, else the quick check's. ``source`` says which\n(``assessment`` or ``verification``).", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + } + }, + "title": "ReviewResult", + "type": "object" + }, + "ReviewResult:validation": { + "additionalProperties": true, + "description": "The one answer to read for a claim: the deep check's verdict when it\ncompleted, else the quick check's. ``source`` says which\n(``assessment`` or ``verification``).", + "properties": { + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "is_issue": { + "default": false, + "title": "Is Issue", + "type": "boolean" + }, + "source": { + "default": "", + "title": "Source", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + } + }, + "title": "ReviewResult", + "type": "object" + }, + "ReviewStarted:serialization": { + "additionalProperties": true, + "description": "Returned by ``POST /review`` (HTTP 202).\n\n``status`` is always ``\"queued\"``: the acceptance receipt, not the current\nstate. Read the review with ``client.get_review(review_id)``.", + "properties": { + "review_id": { + "default": "", + "title": "Review Id", + "type": "string" + }, + "status": { + "default": "queued", + "title": "Status", + "type": "string" + } + }, + "title": "ReviewStarted", + "type": "object" + }, + "ReviewStarted:validation": { + "additionalProperties": true, + "description": "Returned by ``POST /review`` (HTTP 202).\n\n``status`` is always ``\"queued\"``: the acceptance receipt, not the current\nstate. Read the review with ``client.get_review(review_id)``.", + "properties": { + "review_id": { + "default": "", + "title": "Review Id", + "type": "string" + }, + "status": { + "default": "queued", + "title": "Status", + "type": "string" + } + }, + "title": "ReviewStarted", + "type": "object" + }, + "ReviewSummary:serialization": { + "$defs": { + "ReviewAssessmentCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + } + }, + "title": "ReviewAssessmentCounts", + "type": "object" + }, + "ReviewCitationCheckCounts": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + }, + "ReviewVerificationCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "planned": { + "default": 0, + "title": "Planned", + "type": "integer" + } + }, + "title": "ReviewVerificationCounts", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Counts over the review. A count is ``None`` until what it counts is\nknown (``claims_selected`` before the draft has been read).\n\nThe ``citation*`` counts are ``None`` (``citation_issues`` 0) on a review\nthat did not ask for the citation check.", + "properties": { + "assessments": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewAssessmentCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_checks": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationCheckCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_issues": { + "default": 0, + "title": "Citation Issues", + "type": "integer" + }, + "citation_limit": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit" + }, + "citation_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit Reached" + }, + "citations_found": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Found" + }, + "citations_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Selected" + }, + "citations_skipped": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Skipped" + }, + "claim_limit": { + "default": 20, + "title": "Claim Limit", + "type": "integer" + }, + "claim_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim Limit Reached" + }, + "claims_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claims Selected" + }, + "input_truncated": { + "default": false, + "title": "Input Truncated", + "type": "boolean" + }, + "issues": { + "default": 0, + "title": "Issues", + "type": "integer" + }, + "verifications": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewVerificationCounts" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "title": "ReviewSummary", + "type": "object" + }, + "ReviewSummary:validation": { + "$defs": { + "ReviewAssessmentCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + } + }, + "title": "ReviewAssessmentCounts", + "type": "object" + }, + "ReviewCitationCheckCounts": { + "additionalProperties": true, + "description": "Three disjoint counts over the citation rows. ``checked``: a finding\nother than ``unchecked``. ``unchecked``: could not be checked, for a\nreason of the page or the draft. ``failed``: no finding, for a reason of\nours. A row still running is in none of the three.", + "properties": { + "checked": { + "default": 0, + "title": "Checked", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "unchecked": { + "default": 0, + "title": "Unchecked", + "type": "integer" + } + }, + "title": "ReviewCitationCheckCounts", + "type": "object" + }, + "ReviewVerificationCounts": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "planned": { + "default": 0, + "title": "Planned", + "type": "integer" + } + }, + "title": "ReviewVerificationCounts", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Counts over the review. A count is ``None`` until what it counts is\nknown (``claims_selected`` before the draft has been read).\n\nThe ``citation*`` counts are ``None`` (``citation_issues`` 0) on a review\nthat did not ask for the citation check.", + "properties": { + "assessments": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewAssessmentCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_checks": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewCitationCheckCounts" + }, + { + "type": "null" + } + ], + "default": null + }, + "citation_issues": { + "default": 0, + "title": "Citation Issues", + "type": "integer" + }, + "citation_limit": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit" + }, + "citation_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citation Limit Reached" + }, + "citations_found": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Found" + }, + "citations_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Selected" + }, + "citations_skipped": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Citations Skipped" + }, + "claim_limit": { + "default": 20, + "title": "Claim Limit", + "type": "integer" + }, + "claim_limit_reached": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim Limit Reached" + }, + "claims_selected": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claims Selected" + }, + "input_truncated": { + "default": false, + "title": "Input Truncated", + "type": "boolean" + }, + "issues": { + "default": 0, + "title": "Issues", + "type": "integer" + }, + "verifications": { + "anyOf": [ + { + "$ref": "#/$defs/ReviewVerificationCounts" + }, + { + "type": "null" + } + ], + "default": null + } + }, + "title": "ReviewSummary", + "type": "object" + }, + "ReviewVerification:serialization": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "ReviewEntity": { + "additionalProperties": true, + "description": "An entity the deep check found in the claim. ``qid`` is its Wikidata\nid when resolved. Either may be ``None``.", + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Name" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "ReviewEntity", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A claim's deep check. ``status``: ``processing`` | ``completed`` |\n``failed``; while ``processing`` only ``status``, ``content_status`` and\nthe ids are set. ``content_status`` is ``purged`` once the verification\nwas deleted or removed by its account's retention period: the verdict and\nids stay, the text fields and links are ``None``.\n\n``visibility`` and ``depth`` are what the verification actually has: a\nverdict served from an earlier check keeps its own visibility and may be\n``standard`` for a ``low`` request. Sources are on the verification\nitself: ``client.verifications.get(verification_id)``, or ``url``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "content_status": { + "default": "available", + "title": "Content Status", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "depth": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Depth" + }, + "domain": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Domain" + }, + "entities": { + "items": { + "$ref": "#/$defs/ReviewEntity" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Executive Summary" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Language" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "task_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Task Id" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verdict" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "visibility": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Visibility" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "ReviewVerification", + "type": "object" + }, + "ReviewVerification:validation": { + "$defs": { + "FailureBlock": { + "additionalProperties": true, + "description": "Why a review, or one claim's work inside it, failed.\n\nThe same fields a failed ``GET /verify/status`` carries: ``failure_reason``\nis the specific cause (an open set, e.g. ``no_claim``,\n``insufficient_credits``, ``timeout``), ``failure_class`` the closed\n:data:`FailureClass`, ``retryable`` whether resending the same request can\nhelp, ``hint`` one sentence on what to do next and ``docs_url`` where the\nclass is explained.", + "properties": { + "docs_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Docs Url" + }, + "failure_class": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Class" + }, + "failure_reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": "", + "title": "Failure Reason" + }, + "hint": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Hint" + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + } + }, + "title": "FailureBlock", + "type": "object" + }, + "ReviewEntity": { + "additionalProperties": true, + "description": "An entity the deep check found in the claim. ``qid`` is its Wikidata\nid when resolved. Either may be ``None``.", + "properties": { + "name": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Name" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "ReviewEntity", + "type": "object" + } + }, + "additionalProperties": true, + "description": "A claim's deep check. ``status``: ``processing`` | ``completed`` |\n``failed``; while ``processing`` only ``status``, ``content_status`` and\nthe ids are set. ``content_status`` is ``purged`` once the verification\nwas deleted or removed by its account's retention period: the verdict and\nids stay, the text fields and links are ``None``.\n\n``visibility`` and ``depth`` are what the verification actually has: a\nverdict served from an earlier check keeps its own visibility and may be\n``standard`` for a ``low`` request. Sources are on the verification\nitself: ``client.verifications.get(verification_id)``, or ``url``.", + "properties": { + "claim": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Claim" + }, + "confidence": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Confidence" + }, + "content_status": { + "default": "available", + "title": "Content Status", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "depth": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Depth" + }, + "domain": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Domain" + }, + "entities": { + "items": { + "$ref": "#/$defs/ReviewEntity" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Executive Summary" + }, + "failure": { + "anyOf": [ + { + "$ref": "#/$defs/FailureBlock" + }, + { + "type": "null" + } + ], + "default": null + }, + "key_finding": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Key Finding" + }, + "language": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Language" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "task_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Task Id" + }, + "url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Url" + }, + "verdict": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verdict" + }, + "verification_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Id" + }, + "verification_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Verification Url" + }, + "visibility": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Visibility" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "ReviewVerification", + "type": "object" + }, + "ReviewVerificationCounts:serialization": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "planned": { + "default": 0, + "title": "Planned", + "type": "integer" + } + }, + "title": "ReviewVerificationCounts", + "type": "object" + }, + "ReviewVerificationCounts:validation": { + "additionalProperties": true, + "properties": { + "completed": { + "default": 0, + "title": "Completed", + "type": "integer" + }, + "failed": { + "default": 0, + "title": "Failed", + "type": "integer" + }, + "planned": { + "default": 0, + "title": "Planned", + "type": "integer" + } + }, + "title": "ReviewVerificationCounts", + "type": "object" + }, + "SimilarVerification:serialization": { + "additionalProperties": true, + "description": "An existing public verification that semantically resembles the submitted text.\n\nSame vocabulary as ``Verification`` \u2014 flat ``verdict`` / ``confidence`` /\n``lenz_score`` at top level, no nested ``Verdict`` object.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "distance": { + "default": 0.0, + "title": "Distance", + "type": "number" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "SimilarVerification", + "type": "object" + }, + "SimilarVerification:validation": { + "additionalProperties": true, + "description": "An existing public verification that semantically resembles the submitted text.\n\nSame vocabulary as ``Verification`` \u2014 flat ``verdict`` / ``confidence`` /\n``lenz_score`` at top level, no nested ``Verdict`` object.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "distance": { + "default": 0.0, + "title": "Distance", + "type": "number" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "SimilarVerification", + "type": "object" + }, + "Source:serialization": { + "additionalProperties": true, + "description": "A single citation backing a verification.", + "properties": { + "date": { + "default": "", + "title": "Date", + "type": "string" + }, + "snippet": { + "default": "", + "title": "Snippet", + "type": "string" + }, + "source_name": { + "default": "", + "title": "Source Name", + "type": "string" + }, + "title": { + "default": "", + "title": "Title", + "type": "string" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + } + }, + "title": "Source", + "type": "object" + }, + "Source:validation": { + "additionalProperties": true, + "description": "A single citation backing a verification.", + "properties": { + "date": { + "default": "", + "title": "Date", + "type": "string" + }, + "snippet": { + "default": "", + "title": "Snippet", + "type": "string" + }, + "source_name": { + "default": "", + "title": "Source Name", + "type": "string" + }, + "title": { + "default": "", + "title": "Title", + "type": "string" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + } + }, + "title": "Source", + "type": "object" + }, + "TaskAccepted:serialization": { + "additionalProperties": true, + "description": "Returned by ``POST /verify`` and per item of ``POST /verify/batch``.", + "properties": { + "claim_text": { + "default": "", + "title": "Claim Text", + "type": "string" + }, + "task_id": { + "default": "", + "title": "Task Id", + "type": "string" + } + }, + "title": "TaskAccepted", + "type": "object" + }, + "TaskAccepted:validation": { + "additionalProperties": true, + "description": "Returned by ``POST /verify`` and per item of ``POST /verify/batch``.", + "properties": { + "claim_text": { + "default": "", + "title": "Claim Text", + "type": "string" + }, + "task_id": { + "default": "", + "title": "Task Id", + "type": "string" + } + }, + "title": "TaskAccepted", + "type": "object" + }, + "TaskStatus:serialization": { + "$defs": { + "Assessment": { + "additionalProperties": true, + "description": "One reviewer's structured assessment.\n\nCurrent verifications carry three reviewers, ``Reviewer A`` to\n``Reviewer C``, all running the same checks over the evidence, plus\n``Reviewer D`` and ``Reviewer E`` when those three disagree. Their\n``focus_area`` reads ``\"Sources, evidence fit and wording\"``, and\n``warnings`` holds the source issues, evidence gaps and precision issues\nthat reviewer found, in one list.\n\nOlder verifications carry specialist panelists instead, one warning\ncategory each: logical fallacies (Logic Examiner), precision issues\n(Precision Analyst), weakest sources (Source Auditor) and, before\n2026-06, missing context (Context Analyst).\n\n``panelist_name`` is a display value, not a stable key \u2014 don't branch\non it. ``score`` is a reviewer-level 1-10 sub-score, distinct from the\ntop-level ``lenz_score`` on a ``Verification``.", + "properties": { + "focus_area": { + "default": "", + "title": "Focus Area", + "type": "string" + }, + "panelist_name": { + "default": "", + "title": "Panelist Name", + "type": "string" + }, + "reasoning": { + "default": "", + "title": "Reasoning", + "type": "string" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Score" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Assessment", + "type": "object" + }, + "Audit": { + "additionalProperties": true, + "description": "Nested explainability block \u2014 for callers who want the panel's work.", + "properties": { + "adjudication_summary": { + "default": "", + "title": "Adjudication Summary", + "type": "string" + }, + "assessments": { + "items": { + "$ref": "#/$defs/Assessment" + }, + "title": "Assessments", + "type": "array" + }, + "debate_con": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "debate_pro": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "panel_agreement": { + "default": "", + "title": "Panel Agreement", + "type": "string" + } + }, + "title": "Audit", + "type": "object" + }, + "CandidateClaim": { + "additionalProperties": true, + "description": "One of multiple distinct claims framing found in the submitted text.", + "properties": { + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "CandidateClaim", + "type": "object" + }, + "Coverage": { + "additionalProperties": true, + "description": "Whether this verdict carries Lenz's warranty, for YOUR account.\n\nPresent only when covered verification is enabled on the account's plan;\n``None`` otherwise. It describes the pair (your account, this analysis),\nnot the analysis alone \u2014 two accounts can hold two certificates over one\ncached verdict, so the block you see is never another customer's.\n\n``reasons`` is empty exactly when ``status`` is not ``\"uncovered\"``.\n\nThe money fields are three, not two: ``currency`` is ISO 4217 and the\namounts are integers in **major units** \u2014 ``cap=10000`` means ten\nthousand, not a hundred. They are contract figures, not amounts a payment\nprocessor charges. Read ``currency``; do not assume EUR.", + "properties": { + "aggregate": { + "default": 0, + "title": "Aggregate", + "type": "integer" + }, + "as_of": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "As Of" + }, + "cap": { + "default": 0, + "title": "Cap", + "type": "integer" + }, + "certificate_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Certificate Id" + }, + "certificate_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Certificate Url" + }, + "currency": { + "default": "", + "title": "Currency", + "type": "string" + }, + "reasons": { + "items": { + "type": "string" + }, + "title": "Reasons", + "type": "array" + }, + "status": { + "default": "uncovered", + "title": "Status", + "type": "string" + }, + "terms_version": { + "default": "", + "title": "Terms Version", + "type": "string" + } + }, + "title": "Coverage", + "type": "object" + }, + "DebateSide": { + "additionalProperties": true, + "description": "One side of the adversarial debate transcript.", + "properties": { + "argument": { + "default": "", + "title": "Argument", + "type": "string" + }, + "rebuttal": { + "default": "", + "title": "Rebuttal", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "DebateSide", + "type": "object" + }, + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + }, + "Progress": { + "additionalProperties": true, + "description": "Where a running verification has got to. Advisory \u2014 never results.\n\n``step`` is one of ``starting`` / ``framing`` / ``research`` / ``debate``\n/ ``adjudication`` / ``conclusion``. ``index`` is the 1-based stage\nposition (0 while ``starting``) out of ``total``; read ``total`` off the\nresponse rather than hard-coding it. ``poll_after_seconds`` is how long\nto wait before looking again \u2014 :meth:`Lenz.verify_and_wait` honours it\nfor you. ``elapsed_seconds`` is how long the run has been going, a\nmeasurement rather than an estimate of what is left.\n\n``index`` is stage POSITION, not elapsed work: the stages are uneven, so\na bar driven by it sits on ``research`` for roughly half the run.\n\n``step`` stays a plain ``str``, not a ``Literal`` \u2014 an SDK that\nhard-rejects a stage name the server adds later is worse than one that\npasses it through.\n\nThis was a plain ``dict`` up to 2.10.0. The mapping methods below keep\n``p[\"step\"]``, ``\"step\" in p``, ``p.keys()`` and ``dict(p)`` working on a\n2.x minor; they are deprecated and go in 3.0.0. Use attributes.", + "properties": { + "elapsed_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Elapsed Seconds" + }, + "index": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Index" + }, + "poll_after_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Poll After Seconds" + }, + "step": { + "default": "", + "title": "Step", + "type": "string" + }, + "total": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Total" + } + }, + "title": "Progress", + "type": "object" + }, + "SimilarVerification": { + "additionalProperties": true, + "description": "An existing public verification that semantically resembles the submitted text.\n\nSame vocabulary as ``Verification`` \u2014 flat ``verdict`` / ``confidence`` /\n``lenz_score`` at top level, no nested ``Verdict`` object.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "distance": { + "default": 0.0, + "title": "Distance", + "type": "number" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "SimilarVerification", + "type": "object" + }, + "Source": { + "additionalProperties": true, + "description": "A single citation backing a verification.", + "properties": { + "date": { + "default": "", + "title": "Date", + "type": "string" + }, + "snippet": { + "default": "", + "title": "Snippet", + "type": "string" + }, + "source_name": { + "default": "", + "title": "Source Name", + "type": "string" + }, + "title": { + "default": "", + "title": "Title", + "type": "string" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + } + }, + "title": "Source", + "type": "object" + }, + "Verification": { + "additionalProperties": true, + "description": "Full verification report \u2014 returned by ``verify_and_wait``,\n``verifications.get``, the ``/verify/status/{task_id}`` polling\nendpoint, and the webhook payload.\n\nThe verdict block is FLAT at top level (was nested ``Verdict`` object\npre-unify). ``created_at`` + ``modified_at`` are the only timestamp\nfields on the API surface \u2014 editorial ``published_at`` is internal-only.\n\n1.1.0: dropped ``url`` and ``visibility``. API claims are private by\ndefault and referenced by ``verification_id`` only. Cache-hit on\nanother customer's claim is transparent \u2014 the customer always sees\ntheir own ``verification_id``, never another customer's.\n\nLater: ``visibility`` returns \u2014 'private' | 'unlisted' | 'public'. It\nechoes what you set on submit ('private'/'unlisted' are settable;\n'public' can only be read, for listed claims). ``url`` stays dropped.", + "properties": { + "audit": { + "$ref": "#/$defs/Audit" + }, + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "coverage": { + "anyOf": [ + { + "$ref": "#/$defs/Coverage" + }, + { + "type": "null" + } + ], + "default": null + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "depth": { + "default": "", + "title": "Depth", + "type": "string" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "presumed_intent": { + "default": "", + "title": "Presumed Intent", + "type": "string" + }, + "sources": { + "items": { + "$ref": "#/$defs/Source" + }, + "title": "Sources", + "type": "array" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + }, + "visibility": { + "default": "", + "title": "Visibility", + "type": "string" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Verification", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Returned by ``GET /verify/status/{task_id}``.", + "properties": { + "candidates": { + "deprecated": true, + "items": { + "type": "string" + }, + "title": "Candidates", + "type": "array" + }, + "claims": { + "items": { + "$ref": "#/$defs/CandidateClaim" + }, + "title": "Claims", + "type": "array" + }, + "docs_url": { + "default": "", + "title": "Docs Url", + "type": "string" + }, + "error": { + "default": "", + "title": "Error", + "type": "string" + }, + "failure_class": { + "default": "", + "title": "Failure Class", + "type": "string" + }, + "failure_detail": { + "default": "", + "title": "Failure Detail", + "type": "string" + }, + "failure_reason": { + "default": "", + "title": "Failure Reason", + "type": "string" + }, + "hint": { + "default": "", + "title": "Hint", + "type": "string" + }, + "progress": { + "$ref": "#/$defs/Progress" + }, + "reason": { + "default": "", + "title": "Reason", + "type": "string" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/Verification" + }, + { + "type": "null" + } + ], + "default": null + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + }, + "similar_claims": { + "deprecated": true, + "items": { + "$ref": "#/$defs/SimilarVerification" + }, + "title": "Similar Claims", + "type": "array" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "task_id": { + "default": "", + "title": "Task Id", + "type": "string" + } + }, + "title": "TaskStatus", + "type": "object" + }, + "TaskStatus:validation": { + "$defs": { + "Assessment": { + "additionalProperties": true, + "description": "One reviewer's structured assessment.\n\nCurrent verifications carry three reviewers, ``Reviewer A`` to\n``Reviewer C``, all running the same checks over the evidence, plus\n``Reviewer D`` and ``Reviewer E`` when those three disagree. Their\n``focus_area`` reads ``\"Sources, evidence fit and wording\"``, and\n``warnings`` holds the source issues, evidence gaps and precision issues\nthat reviewer found, in one list.\n\nOlder verifications carry specialist panelists instead, one warning\ncategory each: logical fallacies (Logic Examiner), precision issues\n(Precision Analyst), weakest sources (Source Auditor) and, before\n2026-06, missing context (Context Analyst).\n\n``panelist_name`` is a display value, not a stable key \u2014 don't branch\non it. ``score`` is a reviewer-level 1-10 sub-score, distinct from the\ntop-level ``lenz_score`` on a ``Verification``.", + "properties": { + "focus_area": { + "default": "", + "title": "Focus Area", + "type": "string" + }, + "panelist_name": { + "default": "", + "title": "Panelist Name", + "type": "string" + }, + "reasoning": { + "default": "", + "title": "Reasoning", + "type": "string" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Score" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Assessment", + "type": "object" + }, + "Audit": { + "additionalProperties": true, + "description": "Nested explainability block \u2014 for callers who want the panel's work.", + "properties": { + "adjudication_summary": { + "default": "", + "title": "Adjudication Summary", + "type": "string" + }, + "assessments": { + "items": { + "$ref": "#/$defs/Assessment" + }, + "title": "Assessments", + "type": "array" + }, + "debate_con": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "debate_pro": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "panel_agreement": { + "default": "", + "title": "Panel Agreement", + "type": "string" + } + }, + "title": "Audit", + "type": "object" + }, + "CandidateClaim": { + "additionalProperties": true, + "description": "One of multiple distinct claims framing found in the submitted text.", + "properties": { + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "text": { + "default": "", + "title": "Text", + "type": "string" + } + }, + "title": "CandidateClaim", + "type": "object" + }, + "Coverage": { + "additionalProperties": true, + "description": "Whether this verdict carries Lenz's warranty, for YOUR account.\n\nPresent only when covered verification is enabled on the account's plan;\n``None`` otherwise. It describes the pair (your account, this analysis),\nnot the analysis alone \u2014 two accounts can hold two certificates over one\ncached verdict, so the block you see is never another customer's.\n\n``reasons`` is empty exactly when ``status`` is not ``\"uncovered\"``.\n\nThe money fields are three, not two: ``currency`` is ISO 4217 and the\namounts are integers in **major units** \u2014 ``cap=10000`` means ten\nthousand, not a hundred. They are contract figures, not amounts a payment\nprocessor charges. Read ``currency``; do not assume EUR.", + "properties": { + "aggregate": { + "default": 0, + "title": "Aggregate", + "type": "integer" + }, + "as_of": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "As Of" + }, + "cap": { + "default": 0, + "title": "Cap", + "type": "integer" + }, + "certificate_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Certificate Id" + }, + "certificate_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Certificate Url" + }, + "currency": { + "default": "", + "title": "Currency", + "type": "string" + }, + "reasons": { + "items": { + "type": "string" + }, + "title": "Reasons", + "type": "array" + }, + "status": { + "default": "uncovered", + "title": "Status", + "type": "string" + }, + "terms_version": { + "default": "", + "title": "Terms Version", + "type": "string" + } + }, + "title": "Coverage", + "type": "object" + }, + "DebateSide": { + "additionalProperties": true, + "description": "One side of the adversarial debate transcript.", + "properties": { + "argument": { + "default": "", + "title": "Argument", + "type": "string" + }, + "rebuttal": { + "default": "", + "title": "Rebuttal", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "DebateSide", + "type": "object" + }, + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + }, + "Progress": { + "additionalProperties": true, + "description": "Where a running verification has got to. Advisory \u2014 never results.\n\n``step`` is one of ``starting`` / ``framing`` / ``research`` / ``debate``\n/ ``adjudication`` / ``conclusion``. ``index`` is the 1-based stage\nposition (0 while ``starting``) out of ``total``; read ``total`` off the\nresponse rather than hard-coding it. ``poll_after_seconds`` is how long\nto wait before looking again \u2014 :meth:`Lenz.verify_and_wait` honours it\nfor you. ``elapsed_seconds`` is how long the run has been going, a\nmeasurement rather than an estimate of what is left.\n\n``index`` is stage POSITION, not elapsed work: the stages are uneven, so\na bar driven by it sits on ``research`` for roughly half the run.\n\n``step`` stays a plain ``str``, not a ``Literal`` \u2014 an SDK that\nhard-rejects a stage name the server adds later is worse than one that\npasses it through.\n\nThis was a plain ``dict`` up to 2.10.0. The mapping methods below keep\n``p[\"step\"]``, ``\"step\" in p``, ``p.keys()`` and ``dict(p)`` working on a\n2.x minor; they are deprecated and go in 3.0.0. Use attributes.", + "properties": { + "elapsed_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Elapsed Seconds" + }, + "index": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Index" + }, + "poll_after_seconds": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Poll After Seconds" + }, + "step": { + "default": "", + "title": "Step", + "type": "string" + }, + "total": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Total" + } + }, + "title": "Progress", + "type": "object" + }, + "SimilarVerification": { + "additionalProperties": true, + "description": "An existing public verification that semantically resembles the submitted text.\n\nSame vocabulary as ``Verification`` \u2014 flat ``verdict`` / ``confidence`` /\n``lenz_score`` at top level, no nested ``Verdict`` object.", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "distance": { + "default": 0.0, + "title": "Distance", + "type": "number" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "SimilarVerification", + "type": "object" + }, + "Source": { + "additionalProperties": true, + "description": "A single citation backing a verification.", + "properties": { + "date": { + "default": "", + "title": "Date", + "type": "string" + }, + "snippet": { + "default": "", + "title": "Snippet", + "type": "string" + }, + "source_name": { + "default": "", + "title": "Source Name", + "type": "string" + }, + "title": { + "default": "", + "title": "Title", + "type": "string" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + } + }, + "title": "Source", + "type": "object" + }, + "Verification": { + "additionalProperties": true, + "description": "Full verification report \u2014 returned by ``verify_and_wait``,\n``verifications.get``, the ``/verify/status/{task_id}`` polling\nendpoint, and the webhook payload.\n\nThe verdict block is FLAT at top level (was nested ``Verdict`` object\npre-unify). ``created_at`` + ``modified_at`` are the only timestamp\nfields on the API surface \u2014 editorial ``published_at`` is internal-only.\n\n1.1.0: dropped ``url`` and ``visibility``. API claims are private by\ndefault and referenced by ``verification_id`` only. Cache-hit on\nanother customer's claim is transparent \u2014 the customer always sees\ntheir own ``verification_id``, never another customer's.\n\nLater: ``visibility`` returns \u2014 'private' | 'unlisted' | 'public'. It\nechoes what you set on submit ('private'/'unlisted' are settable;\n'public' can only be read, for listed claims). ``url`` stays dropped.", + "properties": { + "audit": { + "$ref": "#/$defs/Audit" + }, + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "coverage": { + "anyOf": [ + { + "$ref": "#/$defs/Coverage" + }, + { + "type": "null" + } + ], + "default": null + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "depth": { + "default": "", + "title": "Depth", + "type": "string" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "presumed_intent": { + "default": "", + "title": "Presumed Intent", + "type": "string" + }, + "sources": { + "items": { + "$ref": "#/$defs/Source" + }, + "title": "Sources", + "type": "array" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + }, + "visibility": { + "default": "", + "title": "Visibility", + "type": "string" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Verification", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Returned by ``GET /verify/status/{task_id}``.", + "properties": { + "candidates": { + "deprecated": true, + "items": { + "type": "string" + }, + "title": "Candidates", + "type": "array" + }, + "claims": { + "items": { + "$ref": "#/$defs/CandidateClaim" + }, + "title": "Claims", + "type": "array" + }, + "docs_url": { + "default": "", + "title": "Docs Url", + "type": "string" + }, + "error": { + "default": "", + "title": "Error", + "type": "string" + }, + "failure_class": { + "default": "", + "title": "Failure Class", + "type": "string" + }, + "failure_detail": { + "default": "", + "title": "Failure Detail", + "type": "string" + }, + "failure_reason": { + "default": "", + "title": "Failure Reason", + "type": "string" + }, + "hint": { + "default": "", + "title": "Hint", + "type": "string" + }, + "progress": { + "$ref": "#/$defs/Progress" + }, + "reason": { + "default": "", + "title": "Reason", + "type": "string" + }, + "result": { + "anyOf": [ + { + "$ref": "#/$defs/Verification" + }, + { + "type": "null" + } + ], + "default": null + }, + "retryable": { + "anyOf": [ + { + "type": "boolean" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Retryable" + }, + "similar_claims": { + "deprecated": true, + "items": { + "$ref": "#/$defs/SimilarVerification" + }, + "title": "Similar Claims", + "type": "array" + }, + "status": { + "default": "", + "title": "Status", + "type": "string" + }, + "task_id": { + "default": "", + "title": "Task Id", + "type": "string" + } + }, + "title": "TaskStatus", + "type": "object" + }, + "Usage:serialization": { + "$defs": { + "UsageCapacity": { + "additionalProperties": true, + "description": "DEPRECATED. One capability's share of the pool, in that capability's unit.\n\n**Removed 2026-11-29**, together with the per-block ``credits`` alias.\nRead :attr:`Usage.credits` and :attr:`Usage.costs` and do the division \u2014\nit is the same one this block does::\n\n remaining = u.credits.remaining // u.costs[capability]\n total = u.credits.total // u.costs[capability]\n used = total - remaining\n\nTwo capabilities at the same price emit identical objects \u2014 ``ask`` and\n``assess`` are both 1 credit \u2014 because there is one balance behind all of\nthem, not a per-capability allowance.\n\nThese are **projections, not allowances**. Every billable capability draws\non the single balance in :attr:`Usage.credits`, at the weight in\n:attr:`Usage.costs`; this block answers \"how many ``/verify`` calls could I\nstill make if I spent everything on them\". Spending on any capability moves\nevery block, and the division floors \u2014 a ``verify`` block (weight 10) ticks\nonce per 10 credits spent anywhere.\n\n- ``quota_*`` \u2014 the monthly allowance projected into this unit; resets\n every period (see :attr:`Usage.quota_resets_at`). ``quota_used`` is\n derived as ``quota_total - quota_remaining``, so ``quota_used +\n quota_remaining == quota_total`` always holds.\n- ``bonus`` \u2014 :attr:`UsageCredits.extra`, the non-expiring part of the\n balance, in this unit. A user holding 5 extra credits sees\n ``assess.bonus == 5`` and ``verify.bonus == 0``: 5 credits does not\n buy a verification.\n\n``remaining`` is the usable capacity across both buckets.", + "properties": { + "bonus": { + "default": 0, + "title": "Bonus", + "type": "integer" + }, + "credits": { + "default": 0, + "deprecated": true, + "title": "Credits", + "type": "integer" + }, + "quota_remaining": { + "default": 0, + "title": "Quota Remaining", + "type": "integer" + }, + "quota_total": { + "default": 0, + "title": "Quota Total", + "type": "integer" + }, + "quota_used": { + "default": 0, + "title": "Quota Used", + "type": "integer" + }, + "remaining": { + "default": 0, + "title": "Remaining", + "type": "integer" + } + }, + "title": "UsageCapacity", + "type": "object" + }, + "UsageCredits": { + "additionalProperties": true, + "description": "The account's credit balance \u2014 the one pool every capability spends.\n\nEvery billable call debits this pool at the weight in :attr:`Usage.costs`\n(``/verify`` is 10 credits \u2014 5 at ``depth=\"low\"``, published as\n``cost_options[\"verify\"][\"depth\"][\"low\"]`` \u2014 ``/assess`` and ``/ask`` are 1, ``/extract`` is\nfree). Two buckets: the monthly allowance for the current plan, which\nresets at ``resets_at``, and non-expiring ``extra`` credits from grants and\ntop-ups, spent only once the allowance is gone. ``remaining`` covers both\nand is what a call is checked against. ``bonus`` is the deprecated old\nname of ``extra``, the same number, removed on 2026-11-29.\n\nServers predating the credit pool (before 2026-08-29) don't send this block\nat all, and it then reads as all-zero \u2014 check ``usage.credits.total``\nbefore trusting the balance.", + "properties": { + "bonus": { + "default": 0, + "deprecated": true, + "title": "Bonus", + "type": "integer" + }, + "extra": { + "default": 0, + "title": "Extra", + "type": "integer" + }, + "remaining": { + "default": 0, + "title": "Remaining", + "type": "integer" + }, + "resets_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Resets At" + }, + "total": { + "default": 0, + "title": "Total", + "type": "integer" + }, + "used": { + "default": 0, + "title": "Used", + "type": "integer" + } + }, + "title": "UsageCredits", + "type": "object" + }, + "UsageExtract": { + "additionalProperties": true, + "description": "Daily ``/extract`` usage \u2014 a per-day rate limit, not credit-based.", + "properties": { + "calls_today": { + "default": 0, + "title": "Calls Today", + "type": "integer" + }, + "daily_limit": { + "default": 0, + "title": "Daily Limit", + "type": "integer" + }, + "unlimited": { + "default": false, + "title": "Unlimited", + "type": "boolean" + } + }, + "title": "UsageExtract", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Returned by ``GET /me/usage`` \u2014 the account's balance and what it buys.\n\n``credits`` is the balance and ``costs`` is the price list (credits per\ncall, keyed by capability). The ``verify`` / ``ask`` / ``assess`` blocks\nare **projections** of that one pool into each capability's unit \u2014 read\nwhichever is convenient, they all describe the same money, and spending on\none moves all of them.\n\n``extract`` is free at the pool (``costs[\"extract\"] == 0``) and is bounded\nby a per-account daily fair-use cap instead; it rejects with 429, never\n402.\n\n``costs`` names capabilities, one entry each, at the default price.\nPrices that depend on a request PARAMETER live in :attr:`cost_options`,\nnested capability \u2192 parameter \u2192 value. Divide ``credits.remaining`` by one\nof those yourself for the low-depth count \u2014 there is deliberately no\n``verify_low`` block beside ``verify``.", + "properties": { + "ask": { + "$ref": "#/$defs/UsageCapacity" + }, + "assess": { + "$ref": "#/$defs/UsageCapacity" + }, + "cost_options": { + "additionalProperties": { + "additionalProperties": { + "additionalProperties": { + "type": "integer" + }, + "type": "object" + }, + "type": "object" + }, + "title": "Cost Options", + "type": "object" + }, + "costs": { + "additionalProperties": { + "type": "integer" + }, + "title": "Costs", + "type": "object" + }, + "credits": { + "$ref": "#/$defs/UsageCredits" + }, + "extract": { + "$ref": "#/$defs/UsageExtract" + }, + "has_webhook_secret": { + "default": false, + "title": "Has Webhook Secret", + "type": "boolean" + }, + "plan": { + "default": "", + "title": "Plan", + "type": "string" + }, + "plan_label": { + "default": "", + "title": "Plan Label", + "type": "string" + }, + "quota_resets_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Quota Resets At" + }, + "verify": { + "$ref": "#/$defs/UsageCapacity" + } + }, + "title": "Usage", + "type": "object" + }, + "Usage:validation": { + "$defs": { + "UsageCapacity": { + "additionalProperties": true, + "description": "DEPRECATED. One capability's share of the pool, in that capability's unit.\n\n**Removed 2026-11-29**, together with the per-block ``credits`` alias.\nRead :attr:`Usage.credits` and :attr:`Usage.costs` and do the division \u2014\nit is the same one this block does::\n\n remaining = u.credits.remaining // u.costs[capability]\n total = u.credits.total // u.costs[capability]\n used = total - remaining\n\nTwo capabilities at the same price emit identical objects \u2014 ``ask`` and\n``assess`` are both 1 credit \u2014 because there is one balance behind all of\nthem, not a per-capability allowance.\n\nThese are **projections, not allowances**. Every billable capability draws\non the single balance in :attr:`Usage.credits`, at the weight in\n:attr:`Usage.costs`; this block answers \"how many ``/verify`` calls could I\nstill make if I spent everything on them\". Spending on any capability moves\nevery block, and the division floors \u2014 a ``verify`` block (weight 10) ticks\nonce per 10 credits spent anywhere.\n\n- ``quota_*`` \u2014 the monthly allowance projected into this unit; resets\n every period (see :attr:`Usage.quota_resets_at`). ``quota_used`` is\n derived as ``quota_total - quota_remaining``, so ``quota_used +\n quota_remaining == quota_total`` always holds.\n- ``bonus`` \u2014 :attr:`UsageCredits.extra`, the non-expiring part of the\n balance, in this unit. A user holding 5 extra credits sees\n ``assess.bonus == 5`` and ``verify.bonus == 0``: 5 credits does not\n buy a verification.\n\n``remaining`` is the usable capacity across both buckets.", + "properties": { + "bonus": { + "default": 0, + "title": "Bonus", + "type": "integer" + }, + "credits": { + "default": 0, + "deprecated": true, + "title": "Credits", + "type": "integer" + }, + "quota_remaining": { + "default": 0, + "title": "Quota Remaining", + "type": "integer" + }, + "quota_total": { + "default": 0, + "title": "Quota Total", + "type": "integer" + }, + "quota_used": { + "default": 0, + "title": "Quota Used", + "type": "integer" + }, + "remaining": { + "default": 0, + "title": "Remaining", + "type": "integer" + } + }, + "title": "UsageCapacity", + "type": "object" + }, + "UsageCredits": { + "additionalProperties": true, + "description": "The account's credit balance \u2014 the one pool every capability spends.\n\nEvery billable call debits this pool at the weight in :attr:`Usage.costs`\n(``/verify`` is 10 credits \u2014 5 at ``depth=\"low\"``, published as\n``cost_options[\"verify\"][\"depth\"][\"low\"]`` \u2014 ``/assess`` and ``/ask`` are 1, ``/extract`` is\nfree). Two buckets: the monthly allowance for the current plan, which\nresets at ``resets_at``, and non-expiring ``extra`` credits from grants and\ntop-ups, spent only once the allowance is gone. ``remaining`` covers both\nand is what a call is checked against. ``bonus`` is the deprecated old\nname of ``extra``, the same number, removed on 2026-11-29.\n\nServers predating the credit pool (before 2026-08-29) don't send this block\nat all, and it then reads as all-zero \u2014 check ``usage.credits.total``\nbefore trusting the balance.", + "properties": { + "bonus": { + "default": 0, + "deprecated": true, + "title": "Bonus", + "type": "integer" + }, + "extra": { + "default": 0, + "title": "Extra", + "type": "integer" + }, + "remaining": { + "default": 0, + "title": "Remaining", + "type": "integer" + }, + "resets_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Resets At" + }, + "total": { + "default": 0, + "title": "Total", + "type": "integer" + }, + "used": { + "default": 0, + "title": "Used", + "type": "integer" + } + }, + "title": "UsageCredits", + "type": "object" + }, + "UsageExtract": { + "additionalProperties": true, + "description": "Daily ``/extract`` usage \u2014 a per-day rate limit, not credit-based.", + "properties": { + "calls_today": { + "default": 0, + "title": "Calls Today", + "type": "integer" + }, + "daily_limit": { + "default": 0, + "title": "Daily Limit", + "type": "integer" + }, + "unlimited": { + "default": false, + "title": "Unlimited", + "type": "boolean" + } + }, + "title": "UsageExtract", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Returned by ``GET /me/usage`` \u2014 the account's balance and what it buys.\n\n``credits`` is the balance and ``costs`` is the price list (credits per\ncall, keyed by capability). The ``verify`` / ``ask`` / ``assess`` blocks\nare **projections** of that one pool into each capability's unit \u2014 read\nwhichever is convenient, they all describe the same money, and spending on\none moves all of them.\n\n``extract`` is free at the pool (``costs[\"extract\"] == 0``) and is bounded\nby a per-account daily fair-use cap instead; it rejects with 429, never\n402.\n\n``costs`` names capabilities, one entry each, at the default price.\nPrices that depend on a request PARAMETER live in :attr:`cost_options`,\nnested capability \u2192 parameter \u2192 value. Divide ``credits.remaining`` by one\nof those yourself for the low-depth count \u2014 there is deliberately no\n``verify_low`` block beside ``verify``.", + "properties": { + "ask": { + "$ref": "#/$defs/UsageCapacity" + }, + "assess": { + "$ref": "#/$defs/UsageCapacity" + }, + "cost_options": { + "additionalProperties": { + "additionalProperties": { + "additionalProperties": { + "type": "integer" + }, + "type": "object" + }, + "type": "object" + }, + "title": "Cost Options", + "type": "object" + }, + "costs": { + "additionalProperties": { + "type": "integer" + }, + "title": "Costs", + "type": "object" + }, + "credits": { + "$ref": "#/$defs/UsageCredits" + }, + "extract": { + "$ref": "#/$defs/UsageExtract" + }, + "has_webhook_secret": { + "default": false, + "title": "Has Webhook Secret", + "type": "boolean" + }, + "plan": { + "default": "", + "title": "Plan", + "type": "string" + }, + "plan_label": { + "default": "", + "title": "Plan Label", + "type": "string" + }, + "quota_resets_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Quota Resets At" + }, + "verify": { + "$ref": "#/$defs/UsageCapacity" + } + }, + "title": "Usage", + "type": "object" + }, + "UsageCapacity:serialization": { + "additionalProperties": true, + "description": "DEPRECATED. One capability's share of the pool, in that capability's unit.\n\n**Removed 2026-11-29**, together with the per-block ``credits`` alias.\nRead :attr:`Usage.credits` and :attr:`Usage.costs` and do the division \u2014\nit is the same one this block does::\n\n remaining = u.credits.remaining // u.costs[capability]\n total = u.credits.total // u.costs[capability]\n used = total - remaining\n\nTwo capabilities at the same price emit identical objects \u2014 ``ask`` and\n``assess`` are both 1 credit \u2014 because there is one balance behind all of\nthem, not a per-capability allowance.\n\nThese are **projections, not allowances**. Every billable capability draws\non the single balance in :attr:`Usage.credits`, at the weight in\n:attr:`Usage.costs`; this block answers \"how many ``/verify`` calls could I\nstill make if I spent everything on them\". Spending on any capability moves\nevery block, and the division floors \u2014 a ``verify`` block (weight 10) ticks\nonce per 10 credits spent anywhere.\n\n- ``quota_*`` \u2014 the monthly allowance projected into this unit; resets\n every period (see :attr:`Usage.quota_resets_at`). ``quota_used`` is\n derived as ``quota_total - quota_remaining``, so ``quota_used +\n quota_remaining == quota_total`` always holds.\n- ``bonus`` \u2014 :attr:`UsageCredits.extra`, the non-expiring part of the\n balance, in this unit. A user holding 5 extra credits sees\n ``assess.bonus == 5`` and ``verify.bonus == 0``: 5 credits does not\n buy a verification.\n\n``remaining`` is the usable capacity across both buckets.", + "properties": { + "bonus": { + "default": 0, + "title": "Bonus", + "type": "integer" + }, + "credits": { + "default": 0, + "deprecated": true, + "title": "Credits", + "type": "integer" + }, + "quota_remaining": { + "default": 0, + "title": "Quota Remaining", + "type": "integer" + }, + "quota_total": { + "default": 0, + "title": "Quota Total", + "type": "integer" + }, + "quota_used": { + "default": 0, + "title": "Quota Used", + "type": "integer" + }, + "remaining": { + "default": 0, + "title": "Remaining", + "type": "integer" + } + }, + "title": "UsageCapacity", + "type": "object" + }, + "UsageCapacity:validation": { + "additionalProperties": true, + "description": "DEPRECATED. One capability's share of the pool, in that capability's unit.\n\n**Removed 2026-11-29**, together with the per-block ``credits`` alias.\nRead :attr:`Usage.credits` and :attr:`Usage.costs` and do the division \u2014\nit is the same one this block does::\n\n remaining = u.credits.remaining // u.costs[capability]\n total = u.credits.total // u.costs[capability]\n used = total - remaining\n\nTwo capabilities at the same price emit identical objects \u2014 ``ask`` and\n``assess`` are both 1 credit \u2014 because there is one balance behind all of\nthem, not a per-capability allowance.\n\nThese are **projections, not allowances**. Every billable capability draws\non the single balance in :attr:`Usage.credits`, at the weight in\n:attr:`Usage.costs`; this block answers \"how many ``/verify`` calls could I\nstill make if I spent everything on them\". Spending on any capability moves\nevery block, and the division floors \u2014 a ``verify`` block (weight 10) ticks\nonce per 10 credits spent anywhere.\n\n- ``quota_*`` \u2014 the monthly allowance projected into this unit; resets\n every period (see :attr:`Usage.quota_resets_at`). ``quota_used`` is\n derived as ``quota_total - quota_remaining``, so ``quota_used +\n quota_remaining == quota_total`` always holds.\n- ``bonus`` \u2014 :attr:`UsageCredits.extra`, the non-expiring part of the\n balance, in this unit. A user holding 5 extra credits sees\n ``assess.bonus == 5`` and ``verify.bonus == 0``: 5 credits does not\n buy a verification.\n\n``remaining`` is the usable capacity across both buckets.", + "properties": { + "bonus": { + "default": 0, + "title": "Bonus", + "type": "integer" + }, + "credits": { + "default": 0, + "deprecated": true, + "title": "Credits", + "type": "integer" + }, + "quota_remaining": { + "default": 0, + "title": "Quota Remaining", + "type": "integer" + }, + "quota_total": { + "default": 0, + "title": "Quota Total", + "type": "integer" + }, + "quota_used": { + "default": 0, + "title": "Quota Used", + "type": "integer" + }, + "remaining": { + "default": 0, + "title": "Remaining", + "type": "integer" + } + }, + "title": "UsageCapacity", + "type": "object" + }, + "UsageCredits:serialization": { + "additionalProperties": true, + "description": "The account's credit balance \u2014 the one pool every capability spends.\n\nEvery billable call debits this pool at the weight in :attr:`Usage.costs`\n(``/verify`` is 10 credits \u2014 5 at ``depth=\"low\"``, published as\n``cost_options[\"verify\"][\"depth\"][\"low\"]`` \u2014 ``/assess`` and ``/ask`` are 1, ``/extract`` is\nfree). Two buckets: the monthly allowance for the current plan, which\nresets at ``resets_at``, and non-expiring ``extra`` credits from grants and\ntop-ups, spent only once the allowance is gone. ``remaining`` covers both\nand is what a call is checked against. ``bonus`` is the deprecated old\nname of ``extra``, the same number, removed on 2026-11-29.\n\nServers predating the credit pool (before 2026-08-29) don't send this block\nat all, and it then reads as all-zero \u2014 check ``usage.credits.total``\nbefore trusting the balance.", + "properties": { + "bonus": { + "default": 0, + "deprecated": true, + "title": "Bonus", + "type": "integer" + }, + "extra": { + "default": 0, + "title": "Extra", + "type": "integer" + }, + "remaining": { + "default": 0, + "title": "Remaining", + "type": "integer" + }, + "resets_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Resets At" + }, + "total": { + "default": 0, + "title": "Total", + "type": "integer" + }, + "used": { + "default": 0, + "title": "Used", + "type": "integer" + } + }, + "title": "UsageCredits", + "type": "object" + }, + "UsageCredits:validation": { + "additionalProperties": true, + "description": "The account's credit balance \u2014 the one pool every capability spends.\n\nEvery billable call debits this pool at the weight in :attr:`Usage.costs`\n(``/verify`` is 10 credits \u2014 5 at ``depth=\"low\"``, published as\n``cost_options[\"verify\"][\"depth\"][\"low\"]`` \u2014 ``/assess`` and ``/ask`` are 1, ``/extract`` is\nfree). Two buckets: the monthly allowance for the current plan, which\nresets at ``resets_at``, and non-expiring ``extra`` credits from grants and\ntop-ups, spent only once the allowance is gone. ``remaining`` covers both\nand is what a call is checked against. ``bonus`` is the deprecated old\nname of ``extra``, the same number, removed on 2026-11-29.\n\nServers predating the credit pool (before 2026-08-29) don't send this block\nat all, and it then reads as all-zero \u2014 check ``usage.credits.total``\nbefore trusting the balance.", + "properties": { + "bonus": { + "default": 0, + "deprecated": true, + "title": "Bonus", + "type": "integer" + }, + "extra": { + "default": 0, + "title": "Extra", + "type": "integer" + }, + "remaining": { + "default": 0, + "title": "Remaining", + "type": "integer" + }, + "resets_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Resets At" + }, + "total": { + "default": 0, + "title": "Total", + "type": "integer" + }, + "used": { + "default": 0, + "title": "Used", + "type": "integer" + } + }, + "title": "UsageCredits", + "type": "object" + }, + "UsageExtract:serialization": { + "additionalProperties": true, + "description": "Daily ``/extract`` usage \u2014 a per-day rate limit, not credit-based.", + "properties": { + "calls_today": { + "default": 0, + "title": "Calls Today", + "type": "integer" + }, + "daily_limit": { + "default": 0, + "title": "Daily Limit", + "type": "integer" + }, + "unlimited": { + "default": false, + "title": "Unlimited", + "type": "boolean" + } + }, + "title": "UsageExtract", + "type": "object" + }, + "UsageExtract:validation": { + "additionalProperties": true, + "description": "Daily ``/extract`` usage \u2014 a per-day rate limit, not credit-based.", + "properties": { + "calls_today": { + "default": 0, + "title": "Calls Today", + "type": "integer" + }, + "daily_limit": { + "default": 0, + "title": "Daily Limit", + "type": "integer" + }, + "unlimited": { + "default": false, + "title": "Unlimited", + "type": "boolean" + } + }, + "title": "UsageExtract", + "type": "object" + }, + "Verification:serialization": { + "$defs": { + "Assessment": { + "additionalProperties": true, + "description": "One reviewer's structured assessment.\n\nCurrent verifications carry three reviewers, ``Reviewer A`` to\n``Reviewer C``, all running the same checks over the evidence, plus\n``Reviewer D`` and ``Reviewer E`` when those three disagree. Their\n``focus_area`` reads ``\"Sources, evidence fit and wording\"``, and\n``warnings`` holds the source issues, evidence gaps and precision issues\nthat reviewer found, in one list.\n\nOlder verifications carry specialist panelists instead, one warning\ncategory each: logical fallacies (Logic Examiner), precision issues\n(Precision Analyst), weakest sources (Source Auditor) and, before\n2026-06, missing context (Context Analyst).\n\n``panelist_name`` is a display value, not a stable key \u2014 don't branch\non it. ``score`` is a reviewer-level 1-10 sub-score, distinct from the\ntop-level ``lenz_score`` on a ``Verification``.", + "properties": { + "focus_area": { + "default": "", + "title": "Focus Area", + "type": "string" + }, + "panelist_name": { + "default": "", + "title": "Panelist Name", + "type": "string" + }, + "reasoning": { + "default": "", + "title": "Reasoning", + "type": "string" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Score" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Assessment", + "type": "object" + }, + "Audit": { + "additionalProperties": true, + "description": "Nested explainability block \u2014 for callers who want the panel's work.", + "properties": { + "adjudication_summary": { + "default": "", + "title": "Adjudication Summary", + "type": "string" + }, + "assessments": { + "items": { + "$ref": "#/$defs/Assessment" + }, + "title": "Assessments", + "type": "array" + }, + "debate_con": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "debate_pro": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "panel_agreement": { + "default": "", + "title": "Panel Agreement", + "type": "string" + } + }, + "title": "Audit", + "type": "object" + }, + "Coverage": { + "additionalProperties": true, + "description": "Whether this verdict carries Lenz's warranty, for YOUR account.\n\nPresent only when covered verification is enabled on the account's plan;\n``None`` otherwise. It describes the pair (your account, this analysis),\nnot the analysis alone \u2014 two accounts can hold two certificates over one\ncached verdict, so the block you see is never another customer's.\n\n``reasons`` is empty exactly when ``status`` is not ``\"uncovered\"``.\n\nThe money fields are three, not two: ``currency`` is ISO 4217 and the\namounts are integers in **major units** \u2014 ``cap=10000`` means ten\nthousand, not a hundred. They are contract figures, not amounts a payment\nprocessor charges. Read ``currency``; do not assume EUR.", + "properties": { + "aggregate": { + "default": 0, + "title": "Aggregate", + "type": "integer" + }, + "as_of": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "As Of" + }, + "cap": { + "default": 0, + "title": "Cap", + "type": "integer" + }, + "certificate_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Certificate Id" + }, + "certificate_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Certificate Url" + }, + "currency": { + "default": "", + "title": "Currency", + "type": "string" + }, + "reasons": { + "items": { + "type": "string" + }, + "title": "Reasons", + "type": "array" + }, + "status": { + "default": "uncovered", + "title": "Status", + "type": "string" + }, + "terms_version": { + "default": "", + "title": "Terms Version", + "type": "string" + } + }, + "title": "Coverage", + "type": "object" + }, + "DebateSide": { + "additionalProperties": true, + "description": "One side of the adversarial debate transcript.", + "properties": { + "argument": { + "default": "", + "title": "Argument", + "type": "string" + }, + "rebuttal": { + "default": "", + "title": "Rebuttal", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "DebateSide", + "type": "object" + }, + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + }, + "Source": { + "additionalProperties": true, + "description": "A single citation backing a verification.", + "properties": { + "date": { + "default": "", + "title": "Date", + "type": "string" + }, + "snippet": { + "default": "", + "title": "Snippet", + "type": "string" + }, + "source_name": { + "default": "", + "title": "Source Name", + "type": "string" + }, + "title": { + "default": "", + "title": "Title", + "type": "string" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + } + }, + "title": "Source", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Full verification report \u2014 returned by ``verify_and_wait``,\n``verifications.get``, the ``/verify/status/{task_id}`` polling\nendpoint, and the webhook payload.\n\nThe verdict block is FLAT at top level (was nested ``Verdict`` object\npre-unify). ``created_at`` + ``modified_at`` are the only timestamp\nfields on the API surface \u2014 editorial ``published_at`` is internal-only.\n\n1.1.0: dropped ``url`` and ``visibility``. API claims are private by\ndefault and referenced by ``verification_id`` only. Cache-hit on\nanother customer's claim is transparent \u2014 the customer always sees\ntheir own ``verification_id``, never another customer's.\n\nLater: ``visibility`` returns \u2014 'private' | 'unlisted' | 'public'. It\nechoes what you set on submit ('private'/'unlisted' are settable;\n'public' can only be read, for listed claims). ``url`` stays dropped.", + "properties": { + "audit": { + "$ref": "#/$defs/Audit" + }, + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "coverage": { + "anyOf": [ + { + "$ref": "#/$defs/Coverage" + }, + { + "type": "null" + } + ], + "default": null + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "depth": { + "default": "", + "title": "Depth", + "type": "string" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "presumed_intent": { + "default": "", + "title": "Presumed Intent", + "type": "string" + }, + "sources": { + "items": { + "$ref": "#/$defs/Source" + }, + "title": "Sources", + "type": "array" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + }, + "visibility": { + "default": "", + "title": "Visibility", + "type": "string" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Verification", + "type": "object" + }, + "Verification:validation": { + "$defs": { + "Assessment": { + "additionalProperties": true, + "description": "One reviewer's structured assessment.\n\nCurrent verifications carry three reviewers, ``Reviewer A`` to\n``Reviewer C``, all running the same checks over the evidence, plus\n``Reviewer D`` and ``Reviewer E`` when those three disagree. Their\n``focus_area`` reads ``\"Sources, evidence fit and wording\"``, and\n``warnings`` holds the source issues, evidence gaps and precision issues\nthat reviewer found, in one list.\n\nOlder verifications carry specialist panelists instead, one warning\ncategory each: logical fallacies (Logic Examiner), precision issues\n(Precision Analyst), weakest sources (Source Auditor) and, before\n2026-06, missing context (Context Analyst).\n\n``panelist_name`` is a display value, not a stable key \u2014 don't branch\non it. ``score`` is a reviewer-level 1-10 sub-score, distinct from the\ntop-level ``lenz_score`` on a ``Verification``.", + "properties": { + "focus_area": { + "default": "", + "title": "Focus Area", + "type": "string" + }, + "panelist_name": { + "default": "", + "title": "Panelist Name", + "type": "string" + }, + "reasoning": { + "default": "", + "title": "Reasoning", + "type": "string" + }, + "score": { + "anyOf": [ + { + "type": "number" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Score" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Assessment", + "type": "object" + }, + "Audit": { + "additionalProperties": true, + "description": "Nested explainability block \u2014 for callers who want the panel's work.", + "properties": { + "adjudication_summary": { + "default": "", + "title": "Adjudication Summary", + "type": "string" + }, + "assessments": { + "items": { + "$ref": "#/$defs/Assessment" + }, + "title": "Assessments", + "type": "array" + }, + "debate_con": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "debate_pro": { + "anyOf": [ + { + "$ref": "#/$defs/DebateSide" + }, + { + "type": "null" + } + ], + "default": null + }, + "panel_agreement": { + "default": "", + "title": "Panel Agreement", + "type": "string" + } + }, + "title": "Audit", + "type": "object" + }, + "Coverage": { + "additionalProperties": true, + "description": "Whether this verdict carries Lenz's warranty, for YOUR account.\n\nPresent only when covered verification is enabled on the account's plan;\n``None`` otherwise. It describes the pair (your account, this analysis),\nnot the analysis alone \u2014 two accounts can hold two certificates over one\ncached verdict, so the block you see is never another customer's.\n\n``reasons`` is empty exactly when ``status`` is not ``\"uncovered\"``.\n\nThe money fields are three, not two: ``currency`` is ISO 4217 and the\namounts are integers in **major units** \u2014 ``cap=10000`` means ten\nthousand, not a hundred. They are contract figures, not amounts a payment\nprocessor charges. Read ``currency``; do not assume EUR.", + "properties": { + "aggregate": { + "default": 0, + "title": "Aggregate", + "type": "integer" + }, + "as_of": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "As Of" + }, + "cap": { + "default": 0, + "title": "Cap", + "type": "integer" + }, + "certificate_id": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Certificate Id" + }, + "certificate_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Certificate Url" + }, + "currency": { + "default": "", + "title": "Currency", + "type": "string" + }, + "reasons": { + "items": { + "type": "string" + }, + "title": "Reasons", + "type": "array" + }, + "status": { + "default": "uncovered", + "title": "Status", + "type": "string" + }, + "terms_version": { + "default": "", + "title": "Terms Version", + "type": "string" + } + }, + "title": "Coverage", + "type": "object" + }, + "DebateSide": { + "additionalProperties": true, + "description": "One side of the adversarial debate transcript.", + "properties": { + "argument": { + "default": "", + "title": "Argument", + "type": "string" + }, + "rebuttal": { + "default": "", + "title": "Rebuttal", + "type": "string" + }, + "role": { + "default": "", + "title": "Role", + "type": "string" + } + }, + "title": "DebateSide", + "type": "object" + }, + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + }, + "Source": { + "additionalProperties": true, + "description": "A single citation backing a verification.", + "properties": { + "date": { + "default": "", + "title": "Date", + "type": "string" + }, + "snippet": { + "default": "", + "title": "Snippet", + "type": "string" + }, + "source_name": { + "default": "", + "title": "Source Name", + "type": "string" + }, + "title": { + "default": "", + "title": "Title", + "type": "string" + }, + "url": { + "default": "", + "title": "Url", + "type": "string" + } + }, + "title": "Source", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Full verification report \u2014 returned by ``verify_and_wait``,\n``verifications.get``, the ``/verify/status/{task_id}`` polling\nendpoint, and the webhook payload.\n\nThe verdict block is FLAT at top level (was nested ``Verdict`` object\npre-unify). ``created_at`` + ``modified_at`` are the only timestamp\nfields on the API surface \u2014 editorial ``published_at`` is internal-only.\n\n1.1.0: dropped ``url`` and ``visibility``. API claims are private by\ndefault and referenced by ``verification_id`` only. Cache-hit on\nanother customer's claim is transparent \u2014 the customer always sees\ntheir own ``verification_id``, never another customer's.\n\nLater: ``visibility`` returns \u2014 'private' | 'unlisted' | 'public'. It\nechoes what you set on submit ('private'/'unlisted' are settable;\n'public' can only be read, for listed claims). ``url`` stays dropped.", + "properties": { + "audit": { + "$ref": "#/$defs/Audit" + }, + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "coverage": { + "anyOf": [ + { + "$ref": "#/$defs/Coverage" + }, + { + "type": "null" + } + ], + "default": null + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "depth": { + "default": "", + "title": "Depth", + "type": "string" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "presumed_intent": { + "default": "", + "title": "Presumed Intent", + "type": "string" + }, + "sources": { + "items": { + "$ref": "#/$defs/Source" + }, + "title": "Sources", + "type": "array" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + }, + "visibility": { + "default": "", + "title": "Visibility", + "type": "string" + }, + "warnings": { + "items": { + "type": "string" + }, + "title": "Warnings", + "type": "array" + } + }, + "title": "Verification", + "type": "object" + }, + "VerificationList:serialization": { + "$defs": { + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + }, + "VerificationListItem": { + "additionalProperties": true, + "description": "Compact item for the verifications list endpoint and the public\nlibrary list. Slim shape \u2014 no ``url`` (reference by\n``verification_id``), no ``visibility`` (1.1.0).", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "VerificationListItem", + "type": "object" + } + }, + "additionalProperties": true, + "properties": { + "items": { + "items": { + "$ref": "#/$defs/VerificationListItem" + }, + "title": "Items", + "type": "array" + }, + "page": { + "default": 1, + "title": "Page", + "type": "integer" + }, + "page_size": { + "default": 20, + "title": "Page Size", + "type": "integer" + }, + "total": { + "default": 0, + "title": "Total", + "type": "integer" + } + }, + "title": "VerificationList", + "type": "object" + }, + "VerificationList:validation": { + "$defs": { + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + }, + "VerificationListItem": { + "additionalProperties": true, + "description": "Compact item for the verifications list endpoint and the public\nlibrary list. Slim shape \u2014 no ``url`` (reference by\n``verification_id``), no ``visibility`` (1.1.0).", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "VerificationListItem", + "type": "object" + } + }, + "additionalProperties": true, + "properties": { + "items": { + "items": { + "$ref": "#/$defs/VerificationListItem" + }, + "title": "Items", + "type": "array" + }, + "page": { + "default": 1, + "title": "Page", + "type": "integer" + }, + "page_size": { + "default": 20, + "title": "Page Size", + "type": "integer" + }, + "total": { + "default": 0, + "title": "Total", + "type": "integer" + } + }, + "title": "VerificationList", + "type": "object" + }, + "VerificationListItem:serialization": { + "$defs": { + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Compact item for the verifications list endpoint and the public\nlibrary list. Slim shape \u2014 no ``url`` (reference by\n``verification_id``), no ``visibility`` (1.1.0).", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "VerificationListItem", + "type": "object" + }, + "VerificationListItem:validation": { + "$defs": { + "EntityRef": { + "additionalProperties": true, + "description": "An entity referenced in the claim.\n\n``qid`` is the Wikidata Q identifier (e.g. ``Q42``) when the entity\nwas resolved against Lenz's internal catalog; ``None`` otherwise.", + "properties": { + "name": { + "default": "", + "title": "Name", + "type": "string" + }, + "qid": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Qid" + } + }, + "title": "EntityRef", + "type": "object" + } + }, + "additionalProperties": true, + "description": "Compact item for the verifications list endpoint and the public\nlibrary list. Slim shape \u2014 no ``url`` (reference by\n``verification_id``), no ``visibility`` (1.1.0).", + "properties": { + "claim": { + "default": "", + "title": "Claim", + "type": "string" + }, + "confidence": { + "default": "low", + "title": "Confidence", + "type": "string" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Created At" + }, + "domain": { + "default": "", + "title": "Domain", + "type": "string" + }, + "entities": { + "items": { + "$ref": "#/$defs/EntityRef" + }, + "title": "Entities", + "type": "array" + }, + "executive_summary": { + "default": "", + "title": "Executive Summary", + "type": "string" + }, + "key_finding": { + "default": "", + "title": "Key Finding", + "type": "string" + }, + "language": { + "default": "en", + "title": "Language", + "type": "string" + }, + "lenz_score": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Lenz Score" + }, + "modified_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Modified At" + }, + "suggested_rewrite": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "default": null, + "title": "Suggested Rewrite" + }, + "verdict": { + "default": "", + "title": "Verdict", + "type": "string" + }, + "verification_id": { + "default": "", + "title": "Verification Id", + "type": "string" + } + }, + "title": "VerificationListItem", + "type": "object" + } +} diff --git a/tests/parity_generate.py b/tests/parity_generate.py new file mode 100644 index 0000000..cf386f2 --- /dev/null +++ b/tests/parity_generate.py @@ -0,0 +1,45 @@ +"""Freeze what the previous release made of every original-shape response. + +Run once against the code BEFORE this SDK read the newer response shape, with +that code first on the path, e.g. from a checkout of the parent commit:: + + PYTHONPATH=/path/to/parent-checkout/src:tests python tests/parity_generate.py + +It writes ``tests/fixtures/parity/expected/.json`` and +``tests/fixtures/parity/requests.json``: the oracle +``tests/test_parity.py`` holds both response shapes to. Do not regenerate it +with the current code; that would make the test compare the code with itself. +""" + +from __future__ import annotations + +import json +import sys +from pathlib import Path + +from parity_observe import FIXTURES, load, names, observe +from parity_requests import bodies +from parity_static import pickles, schemas + +import lenz_io + + +def main() -> None: + print(f"observing with lenz_io from {lenz_io.__file__}", file=sys.stderr) + if "--allow-current" not in sys.argv and Path(lenz_io.__file__).resolve().is_relative_to( + Path(__file__).resolve().parents[1] + ): + raise SystemExit("refusing: this is the current code; put the previous release first on PYTHONPATH") + out = FIXTURES / "expected" + out.mkdir(exist_ok=True) + for name in names(): + result = observe(name, load("legacy", name)) + (out / name).write_text(json.dumps(result, indent=2, ensure_ascii=False, sort_keys=True) + "\n") + (FIXTURES / "requests.json").write_text(json.dumps(bodies(), indent=2, sort_keys=True) + "\n") + (FIXTURES / "schemas.json").write_text(json.dumps(schemas(), indent=2, sort_keys=True) + "\n") + (FIXTURES / "pickles.json").write_text(json.dumps(pickles(), indent=2, sort_keys=True) + "\n") + print(f"wrote {len(names())} files and requests.json", file=sys.stderr) + + +if __name__ == "__main__": + main() diff --git a/tests/parity_observe.py b/tests/parity_observe.py new file mode 100644 index 0000000..0ed28d7 --- /dev/null +++ b/tests/parity_observe.py @@ -0,0 +1,255 @@ +"""What the SDK and the CLI make of one response, as plain JSON. + +Shared by ``tests/test_parity.py`` and ``tests/parity_generate.py``. It uses +only the public surface that existed before this SDK read the newer response +shape, so the generator can run it against the previous release's code and +freeze the result (``tests/fixtures/parity/expected/``): the frozen output is +the oracle both response shapes are held to. + +Fixture names are ``__.json``; the area picks what is observed. +""" + +from __future__ import annotations + +import contextlib +import io +import json +import warnings +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + +from rich.console import Console + +import lenz_io.cli.render as render_mod +from lenz_io import errors as errors_mod +from lenz_io import models +from lenz_io.cli import citecheck as citecheck_cli +from lenz_io.cli import review as review_cli +from lenz_io.cli.errors import friendly_text, to_payload +from lenz_io.client import Lenz +from lenz_io.webhooks import parse_webhook + +FIXTURES = Path(__file__).parent / "fixtures" / "parity" +MISSING = "" + +#: The time the CLI's relative reset dates are rendered against. +FROZEN_NOW = datetime(2026, 10, 2, 12, 0, 0, tzinfo=timezone.utc) + +#: Every attribute an SDK exception may carry, read when present. +_ERROR_ATTRS = ( + "message", + "cause", + "fix", + "doc_url", + "request_id", + "status_code", + "code", + "retry_after", + "limit", + "reset_in_seconds", + "upgrade_url", + "remaining", + "resets_at", + "requested", + "credit_balance", + "cost", + "errors", + "task_id", + "status", + "hint", + "failure_reason", + "failure_class", + "retryable", + "purged_at", + "kind", + "payload", +) + + +class _FrozenDatetime(datetime): + @classmethod + def now(cls, tz: Any = None) -> Any: # type: ignore[override] + return FROZEN_NOW if tz else FROZEN_NOW.replace(tzinfo=None) + + +def _jsonable(value: Any) -> Any: + if hasattr(value, "model_dump"): + return value.model_dump(mode="json") + return json.loads(json.dumps(value, default=str)) + + +def attr_view(obj: Any, template: Any) -> Any: + """Read ``obj`` by ATTRIBUTE along the keys of ``template`` (a dump). + + A dump shows only what a model serialises; this reads what code reading + the attributes gets, so a newer-shape response can be held to the dump the + original shape produced. + """ + if isinstance(template, dict): + out = {} + for key, sub in template.items(): + if isinstance(obj, dict): + value = obj.get(key, MISSING) + else: + value = getattr(obj, key, MISSING) + out[key] = MISSING if value is MISSING else attr_view(value, sub) + return out + if isinstance(template, list): + if not isinstance(obj, (list, tuple)) or len(obj) != len(template): + return _jsonable(obj) + items = list(obj) + return [attr_view(o, t) for o, t in zip(items, template, strict=True)] + return _jsonable(obj) + + +def _console() -> tuple[Console, io.StringIO]: + buf = io.StringIO() + return Console(file=buf, no_color=True, width=120, highlight=False, force_terminal=False), buf + + +def _render(fn: Any, *args: Any, json_mode: bool = False, **kwargs: Any) -> str: + out = render_mod.Output(json_mode=json_mode, no_color=True) + out.json_mode = json_mode + out.console, buf = _console() + out.err, _ = _console() + stdout = io.StringIO() + real_dt = render_mod.datetime + render_mod.datetime = _FrozenDatetime # type: ignore[misc] + try: + with contextlib.redirect_stdout(stdout): + fn(out, *args, **kwargs) + except SystemExit as exc: + buf.write(f"") + finally: + render_mod.datetime = real_dt # type: ignore[misc] + return buf.getvalue() + stdout.getvalue() + + +def _error_view(err: BaseException) -> dict[str, Any]: + view: dict[str, Any] = {"type": type(err).__name__} + for name in _ERROR_ATTRS: + if name in vars(err) or hasattr(type(err), name): + view[name] = _jsonable(getattr(err, name)) + view["friendly_text"] = friendly_text(err) + view["payload_json"] = _jsonable(to_payload(err)) + return view + + +def _model_for(name: str) -> Any: + area = name.split("__", 1)[0] + case = name.split("__", 1)[1] + if area == "extract": + return models.ExtractedClaims + if area == "assess": + return models.AssessResponse + if area == "account" and case.startswith("me_usage"): + return models.Usage + if area == "account" and case.startswith("library"): + return models.LibraryList + if area == "review": + return models.ReviewStarted if case.startswith(("receipt", "idempotent", "replay")) else models.ReviewFull + if area == "citecheck": + return models.CitecheckStarted if case.startswith(("receipt", "idempotent")) else models.Citecheck + if area == "verify": + if case.startswith("status_"): + return models.TaskStatus + if case.startswith(("batch_", "select_")): + return models.BatchAccepted + if case.startswith("list"): + return models.VerificationList + if case.startswith("verification_"): + return models.Verification + return models.TaskAccepted + return None + + +def observe(name: str, fixture: dict[str, Any]) -> dict[str, Any]: + """Everything the SDK and the CLI produce from one recorded response.""" + status, body = fixture["status"], fixture["body"] + headers = {k: str(v) for k, v in (fixture.get("headers") or {}).items()} + result: dict[str, Any] = {} + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + if name.startswith("webhook__"): + event = parse_webhook(body) + view: dict[str, Any] = {"type": type(event).__name__} + for key, value in vars(event).items(): + if key != "raw": + view[key] = _jsonable(value) + result["event"] = view + return result + if status >= 400: + err = errors_mod.map_response_to_error(status, json.dumps(body).encode(), headers) + result["error"] = _error_view(err) + return result + cls = _model_for(name) + if cls is None: + return result + model = _extract_via_client(name, body) if cls is models.ExtractedClaims else cls.model_validate(body) + result["dump"] = model.model_dump(mode="json") + result["dump_unset"] = model.model_dump(mode="json", exclude_unset=True) + result["repr"] = repr(model) + result["render_json"] = None + if cls is models.ExtractedClaims: + result["render"] = _render(render_mod.render_extract, model) + result["render_json"] = _render(render_mod.render_extract, model, json_mode=True) + elif cls is models.AssessResponse: + result["render"] = _render(render_mod.render_assess, model) + result["render_json"] = _render(render_mod.render_assess, model, json_mode=True) + elif cls is models.Usage: + result["render"] = _render(render_mod.render_usage, model) + result["render_json"] = _render(render_mod.render_usage, model, json_mode=True) + elif cls is models.Verification: + result["render"] = _render(render_mod.render_verification_full, model) + result["render_concise"] = _render(render_mod.render_verification, model) + result["render_json"] = _render(render_mod.render_verification_full, model, json_mode=True) + elif cls is models.TaskStatus: + result["render"] = _render(render_mod.render_task_status, model, task_id="t") + result["render_json"] = _render(render_mod.render_task_status, model, task_id="t", json_mode=True) + client = Lenz(api_key="lenz_" + "0" * 32) + try: + verification = client._verification_from_terminal(model, "t") + result["wait"] = {"returned": verification.model_dump(mode="json")} + except errors_mod.LenzError as exc: + result["wait"] = _error_view(exc) + finally: + client.close() + if model.status == "completed" and model.result is not None: + result["render_verification"] = _render(render_mod.render_verification_full, model.result) + elif cls is models.ReviewFull: + result["render"] = _render(review_cli.render_review, model) + result["render_issues"] = _render(review_cli.render_review, model, issues_only=True) + result["exit_code"] = review_cli.exit_code_for_review(model) + elif cls is models.Citecheck: + result["render"] = _render(citecheck_cli.render_citecheck, model) + result["exit_code"] = citecheck_cli.exit_code_for_citecheck(model) + return result + + +def located(name: str) -> bool: + """Whether the recorded /extract call asked to locate its claims.""" + return "locate" in name + + +def _extract_via_client(name: str, body: dict[str, Any]) -> Any: + """``client.extract`` on the recorded body, with the recorded ``locate``.""" + import respx + + from lenz_io.client import DEFAULT_BASE_URL + + client = Lenz(api_key="lenz_" + "0" * 32) + try: + with respx.mock(base_url=DEFAULT_BASE_URL) as mock: + mock.post("/extract").respond(200, json=body) + return client.extract(text="text", locate=True if located(name) else None) + finally: + client.close() + + +def load(shape: str, name: str) -> dict[str, Any]: + return json.loads((FIXTURES / shape / name).read_text()) + + +def names() -> list[str]: + return sorted(p.name for p in (FIXTURES / "legacy").glob("*.json")) diff --git a/tests/parity_requests.py b/tests/parity_requests.py new file mode 100644 index 0000000..826cc9f --- /dev/null +++ b/tests/parity_requests.py @@ -0,0 +1,99 @@ +"""The request bodies the SDK sends, for ``tests/test_parity.py``. + +Like ``parity_observe``, this uses only what the previous release had, so +``parity_generate.py`` can freeze the previous release's bodies as the +oracle (``tests/fixtures/parity/requests.json``). +""" + +from __future__ import annotations + +import json +from typing import Any + +import respx + +from lenz_io.client import DEFAULT_BASE_URL, Lenz + +DRAFT = "The Eiffel Tower is in Berlin. See https://example.org/eiffel." + +#: (name, method, path, response, kwargs). The /review and /citecheck rows pin +#: ``webhook_url`` in all three states: unset, ``""`` (no webhook) and a URL. +CALLS: list[tuple[str, str, str, dict[str, Any], dict[str, Any]]] = [ + ("review_default", "review", "/review", {"review_id": "r1", "status": "queued"}, {"text": DRAFT}), + ("review_webhook_empty", "review", "/review", {"review_id": "r1"}, {"text": DRAFT, "webhook_url": ""}), + ( + "review_webhook_url", + "review", + "/review", + {"review_id": "r1"}, + {"text": DRAFT, "webhook_url": "https://hooks.example.test/x"}, + ), + ( + "review_options", + "review", + "/review", + {"review_id": "r1"}, + { + "text": DRAFT, + "verdicts": ["False"], + "confidence": ["low"], + "max_assessments": 5, + "max_verifications": 2, + "depth": "low", + "max_citations": 3, + "suggest_edits": True, + "language": "de", + "visibility": "unlisted", + }, + ), + ("citecheck_default", "citecheck", "/citecheck", {"citecheck_id": "c1"}, {"text": DRAFT}), + ("citecheck_webhook_empty", "citecheck", "/citecheck", {"citecheck_id": "c1"}, {"text": DRAFT, "webhook_url": ""}), + ( + "citecheck_webhook_url", + "citecheck", + "/citecheck", + {"citecheck_id": "c1"}, + {"text": DRAFT, "webhook_url": "https://hooks.example.test/x", "max_citations": 4}, + ), + ( + "citecheck_pairs", + "citecheck", + "/citecheck", + {"citecheck_id": "c1"}, + {"pairs": [{"statement": "The tower is in Paris.", "url": "https://example.org/eiffel"}], "language": "fr"}, + ), + ( + "verify_webhook_url", + "verify_and_submit", + "/verify", + {"task_id": "t1", "status": "queued"}, + {"claim": "The Earth is round.", "webhook_url": "https://hooks.example.test/x"}, + ), + ( + "verify_batch_webhook_url", + "verify_batch", + "/verify/batch", + {"batch_id": "b1", "items": []}, + {"claims": [{"claim": "The Earth is round."}], "webhook_url": "https://hooks.example.test/x"}, + ), +] + + +def capture(method: str, path: str, response: dict[str, Any], kwargs: dict[str, Any]) -> Any: + client = Lenz(api_key="lenz_" + "0" * 32) + try: + with respx.mock(base_url=DEFAULT_BASE_URL) as mock: + route = mock.post(path).respond(202, json=response) + if method == "verify_and_submit": + client._verify_submit(claim=kwargs["claim"], webhook_url=kwargs["webhook_url"], idempotency_key="k") + elif method == "verify_batch": + client.verify_batch(idempotency_key="k", **kwargs) + else: + getattr(client, method)(idempotency_key="k", **kwargs) + return json.loads(route.calls.last.request.content) + finally: + client.close() + + +def bodies() -> dict[str, Any]: + return {name: capture(method, path, response, kwargs) for name, method, path, response, kwargs in CALLS} diff --git a/tests/parity_static.py b/tests/parity_static.py new file mode 100644 index 0000000..8883f0d --- /dev/null +++ b/tests/parity_static.py @@ -0,0 +1,46 @@ +"""Model schemas and pickles, frozen by ``parity_generate.py`` from the +previous release (``schemas.json``, ``pickles.json``) and checked by +``test_parity.py``: this release must publish the same JSON schemas for every +model, and unpickle and dump what the previous release pickled.""" + +from __future__ import annotations + +import base64 +import pickle +import warnings +from typing import Any + +from parity_observe import _model_for, load, names +from pydantic import BaseModel + +from lenz_io import models + + +def model_classes() -> dict[str, type[BaseModel]]: + return { + name: obj + for name in models.__all__ + if isinstance(obj := getattr(models, name), type) and issubclass(obj, BaseModel) + } + + +def schemas() -> dict[str, Any]: + out = {} + for name, cls in model_classes().items(): + for mode in ("validation", "serialization"): + out[f"{name}:{mode}"] = cls.model_json_schema(mode=mode) + return out + + +def _pickle_names() -> list[str]: + return [n for n in names() if _model_for(n) is not None and load("legacy", n)["status"] < 400] + + +def pickles() -> dict[str, str]: + out = {} + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + for name in _pickle_names(): + model = _model_for(name).model_validate(load("legacy", name)["body"]) + out[name] = base64.b64encode(pickle.dumps(model, protocol=4)).decode() + return out diff --git a/tests/test_cli.py b/tests/test_cli.py index caa271a..1051d39 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -940,7 +940,7 @@ def test_usage_json_success(monkeypatch): assert payload["verify"]["bonus"] == 20 assert payload["assess"]["remaining"] == 5070 assert payload["extract"]["calls_today"] == 4 - # The deprecated alias is still emitted (server sends it until 2026-11-29) + # The deprecated alias is still emitted (the server keeps sending it to existing callers) # and dumping it must not warn — see tests/test_usage_models.py. assert payload["verify"]["credits"] == 20 diff --git a/tests/test_input_aliases.py b/tests/test_input_aliases.py index f1013f5..ca59dbc 100644 --- a/tests/test_input_aliases.py +++ b/tests/test_input_aliases.py @@ -52,7 +52,8 @@ def test_positional_claim_is_unchanged(self, client): with respx.mock(base_url=DEFAULT_BASE) as r: route = r.post("/verify").respond(202, json={"task_id": "tsk_1", "status": "queued"}) client.verify(CLAIM) - assert _body(route) == {"text": CLAIM, "source_url": "", "webhook_url": ""} + # No ``webhook_url`` unless one was given: omitted means the key's default. + assert _body(route) == {"text": CLAIM, "source_url": ""} class TestVerifyBatch: diff --git a/tests/test_parity.py b/tests/test_parity.py new file mode 100644 index 0000000..b398423 --- /dev/null +++ b/tests/test_parity.py @@ -0,0 +1,246 @@ +"""Both response shapes give existing code exactly what the previous release did. + +The oracle in ``tests/fixtures/parity/expected/`` was produced by the code +BEFORE this SDK read the newer response shape (see +``tests/parity_generate.py``), from the original-shape responses in +``tests/fixtures/parity/legacy/``. Each response has its newer-shape twin in +``tests/fixtures/parity/canonical/`` (the same answer, as the API's newer +version sends it). + +* An original-shape response must produce the frozen output byte for byte: + the model dump, every CLI rendering (text and ``--json``), the exception + ``wait`` raises, the error an HTTP error maps to, the parsed webhook. +* Its newer-shape twin must produce the same values through every attribute + the previous release had, the same CLI text, the same ``wait`` outcome and + the same error, except for the few values the newer shape does not carry, + listed one by one in ``KNOWN_GAPS`` with the reason. + +``model_dump()`` and the CLI's ``--json`` show the shape the server sent, so +they are compared for the original shape only. +""" + +from __future__ import annotations + +import json +import warnings +from typing import Any + +import pytest +from parity_observe import FIXTURES, MISSING, _extract_via_client, _model_for, attr_view, load, names, observe + +from lenz_io import models +from lenz_io.webhooks import parse_webhook + +EXPECTED = FIXTURES / "expected" + +# ── What the newer shape cannot reproduce ─────────────────────────────── +# +# Each gap is allowed only where the two recorded responses themselves differ +# in the value it comes from: a rule never excuses a difference the SDK made. +# The categories are the ones the Node SDK allows, so the two behave alike: +# the server's sentences (error / failure text), the codes and field errors it +# sends on a 422, `chain_id`, the review / citation-check webhook `task_id`, +# and a row hint the newer shape does not carry. The single entries in +# ``KNOWN_GAPS`` below fall in those categories too, plus one where the two +# recordings number an id differently. + +#: An exception's text fields: built from the body's ``detail``. +_MESSAGE_PATHS = ("message", "cause", "friendly_text", "payload_json.error.message") + + +def _failure(body: dict[str, Any]) -> dict[str, Any]: + failure = body.get("failure") + return failure if isinstance(failure, dict) else {} + + +def _validation_items(body: dict[str, Any]) -> Any: + detail = body.get("detail") + return detail if isinstance(detail, list) else body.get("errors", []) + + +def _allowed(name: str, path: str, legacy: dict[str, Any], canonical: dict[str, Any]) -> str | None: + """Why ``path`` may differ for ``name``, or ``None`` when it may not.""" + lb, cb = legacy["body"], canonical["body"] + head, _, rest = path.partition(".") + if head == "error": + if rest in _MESSAGE_PATHS and lb.get("detail") != cb.get("detail"): + return "the server words `detail` differently (a 422 sends a sentence, not the list)" + if rest == "code" and lb.get("code") != cb.get("code"): + return "the server sends a different (or a first) `code`" + if rest.startswith("errors") and _validation_items(lb) != _validation_items(cb): + return "the server's field errors differ" + if rest in ("hint", "fix", "friendly_text", "payload_json.error.fix") and lb.get("hint") != cb.get("hint"): + return "the server words the hint differently" + if head == "wait" or path in ("dump.error", "render"): + sentence = lb.get("error") + if isinstance(sentence, str) and sentence != _failure(cb).get("detail"): + if path in ("dump.error", "render") or rest in _MESSAGE_PATHS: + return "the failed run's sentence: the newer shape's `failure.detail` is worded differently" + if path in ("dump.hint", "wait.hint") and lb.get("hint", "") != _failure(cb).get("hint", ""): + return "the newer shape carries a hint the original did not" + if path.startswith("wait.payload.") and name.startswith("verify__status_needs_input"): + return "LenzNeedsInputError.payload is the status as sent (model_dump)" + if path == "dump.chain_id" and "chain_id" in lb and "chain_id" not in cb: + return "`chain_id` is not in the newer shape" + if path == "event.task_id" and "task_id" in lb and "task_id" not in cb: + return "review/citecheck webhooks drop `task_id` (never pollable); it reads the review or check id" + if path.startswith("event.result.") and name.startswith("webhook__verification_completed"): + return "`result` is the dict as sent; the newer shape's carries `completed_at`" + return KNOWN_GAPS.get((name, path)) + + +#: Single gaps no rule covers, each with its reason. +KNOWN_GAPS: dict[tuple[str, str], str] = { + ("assess__list_compound_item.json", "dump.claims[0].hint"): ( + "the newer shape sends no hint on a completed row with other claims found" + ), + ("assess__list_compound_item.json", "render"): "the same hint line, printed by the CLI", + ("review__get_assessment_rows_full_fields.json", "dump.claims[0].assessment.hint"): ( + "the newer shape sends no hint on a completed quick check with other claims found" + ), + ("review__get_failed_every_assessment_failed.json", "dump.failure.hint"): "the server words the hint differently", + ("review__get_failed_every_assessment_failed.json", "render"): "the same hint, printed by the CLI", + ("review__get_failed_every_assessment_failed.json", "render_issues"): "the same hint, printed by the CLI", + ("extract__not_a_claim_beside_claims.json", "dump.status"): ( + "the newer shape answers `ready` when claims came back beside a non-claim" + ), + ("webhook__review_completed.json", "event.review.claims[0].verification.task_id"): ( + "the two recordings number their task ids differently (the newer payload has no delivery task_id)" + ), +} + + +def _expected(name: str) -> dict[str, Any]: + return json.loads((EXPECTED / name).read_text()) + + +def _diff(a: Any, b: Any, path: str = "") -> list[tuple[str, Any, Any]]: + if isinstance(a, dict) and isinstance(b, dict): + out: list[tuple[str, Any, Any]] = [] + for key in sorted(set(a) | set(b)): + out += _diff(a.get(key, MISSING), b.get(key, MISSING), f"{path}.{key}" if path else key) + return out + if isinstance(a, list) and isinstance(b, list) and len(a) == len(b): + out = [] + for i, (x, y) in enumerate(zip(a, b, strict=True)): + out += _diff(x, y, f"{path}[{i}]") + return out + return [] if a == b else [(path, a, b)] + + +#: Attributes this release added to the webhook events. Everything else on an +#: event must read exactly as before. +NEW_EVENT_ATTRS = {"event_id", "failure", "reason", "claims"} + + +def _old_event_attrs(observed: dict[str, Any], expected: dict[str, Any]) -> dict[str, Any]: + if "event" not in observed: + return observed + event = observed["event"] + added = set(event) - set(expected["event"]) + assert added <= NEW_EVENT_ATTRS, added + return {**observed, "event": {k: v for k, v in event.items() if k in expected["event"]}} + + +@pytest.mark.parametrize("name", names()) +def test_original_shape_is_unchanged(name: str) -> None: + expected = _expected(name) + assert _old_event_attrs(observe(name, load("legacy", name)), expected) == expected + + +def _canonical_view(name: str, expected: dict[str, Any]) -> dict[str, Any]: + fixture = load("canonical", name) + got = _old_event_attrs(observe(name, fixture), expected) + view = {k: v for k, v in got.items() if k not in ("dump", "dump_unset", "repr", "render_json")} + if "event" in expected: + # A review or citation check on an event: read it by attribute too. + event = parse_webhook(fixture["body"]) + for key, old in expected["event"].items(): + value = getattr(event, key, None) + if isinstance(old, dict) and hasattr(value, "model_dump"): + view["event"][key] = attr_view(value, old) + if "dump" in expected: + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + cls = _model_for(name) + model = ( + _extract_via_client(name, fixture["body"]) + if cls is models.ExtractedClaims + else cls.model_validate(fixture["body"]) + ) + view["dump"] = attr_view(model, expected["dump"]) + returned = expected.get("wait", {}).get("returned") + if returned is not None: + # ``wait`` returns the polled result: read it by attribute too. + view["wait"] = {"returned": attr_view(model.result, returned)} + return view + + +def _canonical_names() -> list[str]: + return [n for n in names() if (FIXTURES / "canonical" / n).exists()] + + +@pytest.mark.parametrize("name", _canonical_names()) +def test_newer_shape_reads_the_same(name: str) -> None: + expected = {k: v for k, v in _expected(name).items() if k not in ("render_json", "dump_unset", "repr")} + got = _canonical_view(name, expected) + legacy, canonical = load("legacy", name), load("canonical", name) + gaps = [ + (path, old, new) for path, old, new in _diff(expected, got) if _allowed(name, path, legacy, canonical) is None + ] + assert not gaps, "\n".join(f"{path}: {old!r} -> {new!r}" for path, old, new in gaps) + + +def test_every_known_gap_is_still_a_gap() -> None: + """A listed gap that closed is stale: drop it, so the list stays exact.""" + stale = [] + for (name, path), _reason in KNOWN_GAPS.items(): + expected = {k: v for k, v in _expected(name).items() if k not in ("render_json", "dump_unset", "repr")} + if path not in {p for p, _, _ in _diff(expected, _canonical_view(name, expected))}: + stale.append((name, path)) + assert not stale + + +# ── Request bodies ────────────────────────────────────────────────────────── + + +def test_request_bodies_match_the_previous_release() -> None: + """/review and /citecheck keep every body byte for byte, ``webhook_url`` + included in all three states (on those endpoints ``""`` means no webhook, + so it must still be sent). A /verify or /verify/batch call with a webhook + URL is unchanged too.""" + from parity_requests import bodies + + assert bodies() == json.loads((FIXTURES / "requests.json").read_text()) + + +# ── Schemas and pickles ───────────────────────────────────────────────────── + + +def test_model_schemas_match_the_previous_release() -> None: + """Every model the previous release had publishes the same validation and + serialization JSON schema: the newer names are properties, not fields.""" + from parity_static import schemas + + def _shape(schema: Any) -> Any: + # Doc text (class docstrings) may change; the shape may not. + if isinstance(schema, dict): + return {k: _shape(v) for k, v in schema.items() if k != "description"} + if isinstance(schema, list): + return [_shape(v) for v in schema] + return schema + + frozen = _shape(json.loads((FIXTURES / "schemas.json").read_text())) + current = _shape(schemas()) + assert {k: current.get(k) for k in frozen} == frozen + + +def test_objects_pickled_by_the_previous_release_still_dump() -> None: + import base64 + import pickle + + frozen = json.loads((FIXTURES / "pickles.json").read_text()) + assert frozen + for name, blob in frozen.items(): + model = pickle.loads(base64.b64decode(blob)) + assert model.model_dump(mode="json") == _expected(name)["dump"], name diff --git a/tests/test_read_both_shapes.py b/tests/test_read_both_shapes.py new file mode 100644 index 0000000..a8741bb --- /dev/null +++ b/tests/test_read_both_shapes.py @@ -0,0 +1,437 @@ +"""The new attributes read the same from either response shape, and the old +ones keep their meaning. ``test_parity.py`` holds the old attributes to the +previous release's output; this file checks the new ones.""" + +from __future__ import annotations + +import json +import warnings + +import pytest +import respx +from parity_observe import load + +from lenz_io import Lenz +from lenz_io.client import DEFAULT_BASE_URL +from lenz_io.errors import LenzPipelineError, LenzRateLimitError, LenzValidationError, map_response_to_error +from lenz_io.models import ( + AssessClaim, + AssessResponse, + BatchAccepted, + ExtractedClaims, + FailureBlock, + ReviewFull, + TaskAccepted, + TaskStatus, + Usage, + Verification, + VerificationList, +) +from lenz_io.webhooks import ( + CitecheckEvent, + ReviewEvent, + VerificationCompleted, + VerificationFailed, + VerificationNeedsInput, + parse_webhook, +) + +pytestmark = pytest.mark.filterwarnings("error::DeprecationWarning") + + +def _both(name: str) -> tuple[dict, dict]: + return load("legacy", name)["body"], load("canonical", name)["body"] + + +# ── /extract ── + + +@pytest.mark.parametrize( + "name", + [ + "extract__ready_one_claim.json", + "extract__ready_several_claims.json", + "extract__locate_true.json", + "extract__locate_some_dropped.json", + "extract__url_input_located.json", + "extract__no_match_with_focus.json", + "extract__not_a_claim.json", + ], +) +def test_extract_claims_reads_the_same_from_both_shapes(name): + legacy, canonical = (ExtractedClaims.model_validate(b) for b in _both(name)) + assert [c.model_dump() for c in legacy.claims] == [c.model_dump() for c in canonical.claims] + assert legacy.status == canonical.status # "not_a_claim" from either spelling + + +def test_extract_one_claim_is_a_list_of_one(): + legacy, canonical = (ExtractedClaims.model_validate(b) for b in _both("extract__ready_one_claim.json")) + assert [c.claim for c in legacy.claims] == [c.claim for c in canonical.claims] == ["Alpha rose 5% in 2024."] + assert canonical.identified_claims == [] and canonical.claim == "Alpha rose 5% in 2024." + + +def test_extract_claims_union_keeps_the_primary_from_an_older_server(): + out = ExtractedClaims.model_validate({"status": "ready", "claim": "A.", "identified_claims": ["B.", "C."]}) + assert [c.claim for c in out.claims] == ["A.", "B.", "C."] + + +def test_extract_empty_claims_does_not_fall_back_to_old_fields(): + out = ExtractedClaims.model_validate({"status": "no_match", "claims": [], "claim": "stale"}) + assert out.claims == [] and out.claim == "stale" + + +# ── /assess ── + + +def test_assess_failed_rows_from_both_shapes(): + legacy, canonical = (AssessResponse.model_validate(b) for b in _both("assess__list_mixed_rows.json")) + for resp in (legacy, canonical): + assert resp.status == "ok" + assert [r.status for r in resp.claims] == ["completed", "failed", "failed", "failed"] + assert [r.failure.code if r.failure else None for r in resp.claims] == [ + None, + "no_checkable_claim", + "upstream_unavailable", + "framing_failed", + ] + assert resp.claims[1].failure.hint.startswith("The input is a greeting.") + # the newer shape: no verdict on a failed row, read as the original "Error"/"low" + row = canonical.claims[1] + assert (row.verdict, row.confidence, row.error_code) == ("Error", "low", "no_claim") + + +def test_assess_single_no_claim_from_both_shapes(): + legacy, canonical = (AssessResponse.model_validate(b) for b in _both("assess__single_no_claim.json")) + for resp in (legacy, canonical): + assert resp.status == "no_checkable_claim" + assert resp.failure is not None and resp.failure.code == "no_checkable_claim" + assert resp.error_code == "no_claim" and resp.error + + +def test_assess_more_claims_on_a_row_from_both_shapes(): + legacy, canonical = (AssessResponse.model_validate(b) for b in _both("assess__list_compound_item.json")) + assert legacy.claims[0].more_claims == canonical.claims[0].more_claims == ["Second claim.", "Third claim."] + assert canonical.claims[0].identified_claims == ["Second claim.", "Third claim."] + + +def test_assess_empty_more_claims_does_not_fall_back(): + row = AssessClaim.model_validate({"claim": "x", "status": "completed", "verdict": "True", "more_claims": []}) + assert row.more_claims == [] and row.identified_claims == [] + row = AssessClaim.model_validate( + {"claim": "x", "verdict": "True", "more_claims": [], "identified_claims": ["stale"]} + ) + assert row.more_claims == [] + + +@pytest.mark.parametrize( + ("rows", "status"), + [ + ([{"verdict": "Error", "error_code": "no_claim"}] * 2, "no_checkable_claim"), + ([{"verdict": "Error", "error_code": "timeout"}], "error"), + ([{"verdict": "Error", "error_code": "timeout"}, {"verdict": "True"}], "ok"), + ], +) +def test_assess_status_is_computed_for_the_original_shape(rows, status): + assert AssessResponse.model_validate({"claims": rows, "error": None}).status == status + + +# ── /verify ── + + +def test_receipt_claim_from_both_shapes(): + legacy, canonical = (BatchAccepted.model_validate(b) for b in _both("verify__batch_202.json")) + assert ( + [i.claim for i in legacy.items] == [i.claim for i in canonical.items] == [i.claim_text for i in canonical.items] + ) + assert TaskAccepted.model_validate({"task_id": "t"}).claim == "" + + +@pytest.mark.parametrize( + "name", + [ + "verify__status_failed.json", + "verify__status_failed_retryable.json", + "verify__status_not_a_claim.json", + "verify__status_cancelled_after_a_while.json", + ], +) +def test_failed_status_failure_block_from_both_shapes(name): + legacy, canonical = (TaskStatus.model_validate(b) for b in _both(name)) + for st in (legacy, canonical): + assert st.failure is not None + assert st.failure.code == _both(name)[1]["failure"]["code"] + assert st.failure.failure_class == canonical.failure_class + assert st.failure.retryable is canonical.retryable + assert st.failure.detail + assert canonical.failure_reason == legacy.failure_reason + assert canonical.error == canonical.failure.detail + + +def test_needs_input_options_from_both_shapes(): + legacy, canonical = (TaskStatus.model_validate(b) for b in _both("verify__status_needs_input.json")) + assert [c.claim for c in legacy.claims] == [c.claim for c in canonical.claims] + assert [c.text for c in canonical.claims] == [c.claim for c in canonical.claims] + + +def test_completed_at_and_the_original_modified_at_rule(): + late, early = "2026-10-01T23:55:00+00:00", "2026-10-02T00:03:00+00:00" + crossed = Verification.model_validate({"created_at": late, "completed_at": early}) + assert crossed.modified_at == early + same_day = Verification.model_validate({"created_at": "2026-10-01T08:00:00Z", "completed_at": "2026-10-01T20:00Z"}) + assert same_day.modified_at is None and same_day.completed_at == "2026-10-01T20:00Z" + # a UTC calendar day, whatever offset the strings carry + offset = Verification.model_validate( + {"created_at": "2026-10-01T22:00:00+00:00", "completed_at": "2026-10-02T01:00:00+02:00"} + ) + assert offset.modified_at is None + legacy = Verification.model_validate({"created_at": late, "modified_at": early}) + assert legacy.completed_at == early + assert Verification.model_validate({"created_at": late, "modified_at": None}).completed_at is None + + +@pytest.mark.parametrize( + "name", + [ + "verify__verification_200_modified_at_crosses_midnight_by_minutes.json", + "verify__verification_200_modified_at_same_day_hours_apart.json", + "verify__list_200_modified_at_crosses_midnight_by_minutes.json", + ], +) +def test_modified_at_from_both_shapes(name): + cls = VerificationList if "list" in name else Verification + legacy, canonical = (cls.model_validate(b) for b in _both(name)) + pick = (lambda m: m.items[0]) if cls is VerificationList else (lambda m: m) + assert pick(legacy).modified_at == pick(canonical).modified_at + + +# ── /me/usage ── + + +@pytest.mark.parametrize( + "name", + ["account__me_usage_pro_extra.json", "account__me_usage_free_partly_spent.json", "account__me_usage_free.json"], +) +def test_usage_blocks_are_computed_from_the_pool(name): + legacy, canonical = (Usage.model_validate(b) for b in _both(name)) + for cap in ("verify", "ask", "assess"): + assert getattr(legacy, cap).model_dump() == getattr(canonical, cap).model_dump() + assert canonical.quota_resets_at == canonical.credits.resets_at + with warnings.catch_warnings(): + warnings.simplefilter("ignore", DeprecationWarning) + assert canonical.credits.bonus == legacy.credits.bonus + + +# ── /review ── + + +@pytest.mark.parametrize( + "name", + [ + "review__get_more_claims.json", + "review__get_claim_limit_reached_exact.json", + "review__get_citations_limit_reached.json", + "review__get_completed_issues_full.json", + "review__get_assessment_rows_full_fields.json", + ], +) +def test_review_new_names_from_both_shapes(name): + legacy, canonical = (ReviewFull.model_validate(b) for b in _both(name)) + # The original shape says only that the claim limit was REACHED. + assert legacy.summary.claim_limit_exceeded is None + assert canonical.summary.claim_limit_exceeded == bool(canonical.more_claims) + assert legacy.summary.citation_limit_exceeded == canonical.summary.citation_limit_exceeded + for a, b in zip(legacy.claims, canonical.claims, strict=True): + assert a.assessment.more_claims == b.assessment.more_claims + if a.assessment.failure is not None: + assert a.assessment.failure.code == b.assessment.failure.code + + +def test_review_failure_code_reads_the_new_spelling(): + legacy, canonical = (ReviewFull.model_validate(b) for b in _both("review__get_failed_no_claim.json")) + assert legacy.failure.code == canonical.failure.code == "no_checkable_claim" + assert canonical.failure.failure_reason == "no_claim" + assert FailureBlock.model_validate({"failure_reason": "not_a_claim"}).code == "no_checkable_claim" + + +# ── the original shape is parsed exactly as before ── + + +def test_newer_shape_dump_keeps_every_key_sent(): + canonical = load("canonical", "assess__list_mixed_rows.json")["body"] + dumped = AssessResponse.model_validate(canonical).model_dump(mode="json") + assert set(canonical) <= set(dumped) + assert all(set(row) <= set(d) for row, d in zip(canonical["claims"], dumped["claims"], strict=True)) + + +def test_explicit_null_retryable_is_kept(): + st = TaskStatus.model_validate({"status": "failed", "retryable": None, "failure": {"code": "x", "retryable": True}}) + assert st.retryable is None + assert st.failure is not None and st.failure.retryable is True + + +def test_sparse_usage_dumps_every_default(): + assert set(Usage.model_validate({"plan": "free"}).model_dump()) == set(Usage.model_fields) + + +def test_original_shape_keeps_unset_fields_unset(): + body = {"claim": "x", "verdict": "True", "confidence": "high"} + assert AssessClaim.model_validate(body).model_dump(exclude_unset=True) == body + assert AssessResponse.model_validate({"claims": []}).model_dump(exclude_unset=True) == {"claims": []} + + +def test_new_names_are_properties_not_fields(): + for cls, name in ( + (AssessClaim, "status"), + (AssessClaim, "failure"), + (ExtractedClaims, "claims"), + (TaskStatus, "failure"), + (Verification, "completed_at"), + (FailureBlock, "code"), + ): + assert name not in cls.model_fields + + +def test_model_copy_update_shows_in_the_dump(): + row = AssessClaim.model_validate({"claim": "x", "verdict": "True"}) + assert row.model_copy(update={"verdict": "False"}).model_dump()["verdict"] == "False" + + +# ── webhooks ── + + +@pytest.mark.parametrize( + "name", + [ + "webhook__verification_failed_not_a_claim.json", + "webhook__verification_failed_upstream_unavailable.json", + ], +) +def test_failed_webhook_from_both_shapes(name): + legacy, canonical = (parse_webhook(b) for b in _both(name)) + assert isinstance(legacy, VerificationFailed) and isinstance(canonical, VerificationFailed) + assert legacy.error == canonical.error + assert legacy.failure.code == canonical.failure.code + assert (legacy.failure_class, legacy.retryable) == (canonical.failure_class, canonical.retryable) + assert canonical.event_id + + +def test_needs_input_webhook_from_both_shapes(): + legacy, canonical = (parse_webhook(b) for b in _both("webhook__verification_needs_input_multi_claim.json")) + assert isinstance(canonical, VerificationNeedsInput) + assert legacy.needs_input == canonical.needs_input + assert [c.claim for c in legacy.claims] == [c.claim for c in canonical.claims] + assert legacy.reason == canonical.reason == "multi_claim" + + +def test_completed_webhook_result_from_both_shapes(): + name = "webhook__verification_completed_modified_at_crosses_midnight_by_minutes.json" + legacy, canonical = (parse_webhook(b) for b in _both(name)) + assert isinstance(canonical, VerificationCompleted) + assert legacy.verification_id == canonical.verification_id + assert legacy.result["modified_at"] == canonical.result["modified_at"] + + +def test_needs_input_with_a_null_domain_does_not_raise(): + event = parse_webhook( + { + "event": "verification.needs_input", + "task_id": "t", + "needs_input": {"claims": [{"text": "A", "domain": None}]}, + } + ) + assert event.needs_input == {"claims": [{"text": "A", "domain": None}]} + assert [c.claim for c in event.claims] == ["A"] + + +def test_legacy_webhook_event_still_serialises(): + import dataclasses + + event = parse_webhook(load("legacy", "webhook__verification_failed_not_a_claim.json")["body"]) + assert json.loads(json.dumps(dataclasses.asdict(event)))["error"] == "not_a_claim" + assert "failure" not in dataclasses.asdict(event) + + +@pytest.mark.parametrize("name", ["webhook__review_completed.json", "webhook__citecheck_completed.json"]) +def test_review_webhook_without_task_id(name): + canonical = parse_webhook(load("canonical", name)["body"]) + assert isinstance(canonical, (ReviewEvent, CitecheckEvent)) + work_id = canonical.review_id if isinstance(canonical, ReviewEvent) else canonical.citecheck_id + assert canonical.task_id == work_id != "" and canonical.event_id != "" + legacy = parse_webhook(load("legacy", name)["body"]) + assert legacy.task_id == load("legacy", name)["body"]["task_id"] + + +# ── errors ── + + +def test_409_failed_run_reads_the_failure_block(): + _, canonical = _both("verify__verification_failed_409.json") + err = map_response_to_error(409, json.dumps(canonical).encode()) + assert isinstance(err, LenzPipelineError) + assert (err.failure_reason, err.failure_class, err.retryable) == ( + "research_empty", + "insufficient_evidence", + False, + ) + _, canonical = _both("verify__verification_failed_409_not_a_claim_after_a_while.json") + assert map_response_to_error(409, json.dumps(canonical).encode()).failure_reason == "not_a_claim" + + +def test_validation_errors_from_both_shapes(): + legacy, canonical = _both("errors__validation_wrong_type.json") + for body in (legacy, canonical): + err = map_response_to_error(422, json.dumps(body).encode()) + assert isinstance(err, LenzValidationError) + assert [e["msg"] for e in err.errors] == ["Input should be a valid string"] + + +def test_rate_limit_wait_from_both_shapes(): + for body in _both("errors__rate_limited_extract.json"): + err = map_response_to_error(429, json.dumps(body).encode()) + assert isinstance(err, LenzRateLimitError) + assert (err.retry_after, err.reset_in_seconds) == (900, 900) + err = map_response_to_error(429, json.dumps({"code": "review_in_flight", "retry_after": 0}).encode()) + assert (err.retry_after, err.reset_in_seconds) == (0, None) + + +def test_error_fields_follow_key_presence(): + err = map_response_to_error( + 429, json.dumps({"code": "rate_limited", "reset_in_seconds": None, "retry_after": 30}).encode() + ) + assert err.reset_in_seconds is None + body = {"code": "verification_failed", "hint": "", "failure": {"code": "x", "hint": "from the block"}} + assert map_response_to_error(409, json.dumps(body).encode()).hint == "" + + +def test_quota_remaining_is_derived_when_absent(): + legacy, canonical = _both("citecheck__402_no_credits.json") + assert map_response_to_error(402, json.dumps(canonical).encode()).remaining == 100 + assert map_response_to_error(402, json.dumps(legacy).encode()).remaining == 100 + assert map_response_to_error(402, json.dumps({"credits_remaining": 9, "cost": 1}).encode()).remaining is None + + +# ── requests ── + + +def _sent(call) -> dict: + with respx.mock(base_url=DEFAULT_BASE_URL, assert_all_called=False) as mock: + verify = mock.post("/verify").respond(202, json={"task_id": "t"}) + batch = mock.post("/verify/batch").respond(202, json={"batch_id": "b", "items": []}) + client = Lenz(api_key="lenz_" + "0" * 32) + call(client) + route = verify if verify.called else batch + return json.loads(route.calls.last.request.content) + + +@pytest.mark.parametrize("webhook_url", [None, ""]) +def test_verify_never_sends_an_empty_webhook_url(webhook_url): + kwargs = {} if webhook_url is None else {"webhook_url": webhook_url} + assert "webhook_url" not in _sent(lambda c: c._verify_submit(claim="x", **kwargs)) + assert "webhook_url" not in _sent(lambda c: c.verify_batch(claims=[{"claim": "x"}], **kwargs)) + item = _sent(lambda c: c.verify_batch(claims=[{"claim": "x", "webhook_url": ""}]))["claims"][0] + assert "webhook_url" not in item + + +def test_verify_sends_a_webhook_url_that_was_set(): + body = _sent(lambda c: c.verify("x", webhook_url="https://hooks.example.test/x")) + assert body["webhook_url"] == "https://hooks.example.test/x" diff --git a/tests/test_usage_models.py b/tests/test_usage_models.py index 697ad32..b54604e 100644 --- a/tests/test_usage_models.py +++ b/tests/test_usage_models.py @@ -118,13 +118,13 @@ def test_capability_blocks_are_projections_of_the_one_pool(): def test_reading_the_credits_alias_warns_and_returns_bonus(): cap = UsageCapacity.model_validate(POOL_PAYLOAD["verify"]) assert cap.bonus == 20 - with pytest.deprecated_call(match="2026-11-29"): + with pytest.deprecated_call(match="is deprecated;"): assert cap.credits == 20 def test_dumping_keeps_the_alias_and_does_not_warn(): """Serialization must stay warning-free — a `--json` dump of usage is not - a deprecated read, and the key stays on the wire until 2026-11-29.""" + a deprecated read, and the key stays on the wire for existing callers.""" cap = UsageCapacity.model_validate(POOL_PAYLOAD["verify"]) with warnings.catch_warnings(): warnings.simplefilter("error", DeprecationWarning) @@ -144,7 +144,7 @@ def test_old_server_sending_only_credits_still_fills_bonus(): def test_server_after_the_alias_removal_still_fills_credits(): - """After 2026-11-29 the server drops `credits`; the alias keeps reading.""" + """A response without `credits` (a computed block) still reads the alias.""" cap = UsageCapacity.model_validate( {"quota_used": 13, "quota_total": 520, "quota_remaining": 507, "bonus": 20, "remaining": 507} ) @@ -173,13 +173,13 @@ def test_pre_pool_server_leaves_the_balance_empty_not_wrong(): def test_reading_the_bonus_alias_warns_and_returns_extra(): c = UsageCredits.model_validate(POOL_PAYLOAD["credits"]) assert c.extra == 200 - with pytest.deprecated_call(match="2026-11-29"): + with pytest.deprecated_call(match="is deprecated;"): assert c.bonus == 200 def test_dumping_the_pool_keeps_bonus_and_does_not_warn(): """A `--json` dump is not a deprecated read, and the key stays on the wire - until 2026-11-29.""" + for existing callers.""" c = UsageCredits.model_validate(POOL_PAYLOAD["credits"]) with warnings.catch_warnings(): warnings.simplefilter("error", DeprecationWarning) @@ -193,7 +193,7 @@ def test_a_server_sending_only_bonus_still_fills_extra(): def test_a_server_sending_only_extra_still_fills_bonus(): - """After 2026-11-29 the server sends only `extra`; `bonus` keeps reading.""" + """The newer response shape sends only `extra`; `bonus` keeps reading.""" c = UsageCredits.model_validate({"total": 300, "used": 0, "remaining": 300, "extra": 200}) assert c.extra == 200 with pytest.deprecated_call():