Premise

Kestrel Platform fictional company

Company Brain

Consequences, connected.

Every affected guarantee was evaluated on all of its prerequisites.

PR #pr:9001 Graph revision 1 Head public-demo-v1-S1 Assessment JSON

Verdict BLOCKED

Why this verdict

What changed

FactMainProposedControl
paylane.retry_window_hoursconfig/partners/paylane.yaml:4 24 72 external

How far it reaches

flowchart LR
  A_RETRY_WINDOW["A\_RETRY\_WINDOW"] --> G_DEDUPE["G\_DEDUPE"]
  G_CHARGE_ONCE -. "relies on" .-> ADR_015["ADR-015"]
  G_CHARGE_ONCE -. "relies on" .-> ADR_018["ADR-018"]
  G_CHARGE_ONCE -. promises .-> ADR_012["ADR-012"]
  G_CHARGE_ONCE["G\_CHARGE\_ONCE"] --> G_LEDGER_CONSISTENT["G\_LEDGER\_CONSISTENT"]
  G_CHARGE_ONCE["G\_CHARGE\_ONCE"] --> G_REFUND_MATCH["G\_REFUND\_MATCH"]
  G_DEDUPE -. "relies on" .-> ADR_012["ADR-012"]
  G_DEDUPE -. promises .-> ADR_007["ADR-007"]
  G_DEDUPE["G\_DEDUPE"] --> G_CHARGE_ONCE["G\_CHARGE\_ONCE"]
  G_LEDGER_CONSISTENT -. promises .-> ADR_018["ADR-018"]
  G_REFUND_MATCH -. "relies on" .-> ADR_018["ADR-018"]
  G_REFUND_MATCH -. promises .-> ADR_015["ADR-015"]
  classDef broken fill:#2a0f1a,stroke:#ff6b8b,color:#ffd3dd
  classDef unknown fill:#2a2310,stroke:#ffd27a,color:#fff0cc
  classDef holds fill:#0d2620,stroke:#7cf0c8,color:#d8fff2
  class G_CHARGE_ONCE,G_DEDUPE,A_RETRY_WINDOW broken
  class G_DEDUPE,A_RETRY_WINDOW broken
  class G_LEDGER_CONSISTENT,G_CHARGE_ONCE,G_DEDUPE,A_RETRY_WINDOW broken
  class G_REFUND_MATCH,G_CHARGE_ONCE,G_DEDUPE,A_RETRY_WINDOW broken
Fig. 1. Each broken path fires from the changed assumption up to the decisions that promise or rely on it.
Dependency graph text
flowchart LR
  A_RETRY_WINDOW["A\_RETRY\_WINDOW"] --> G_DEDUPE["G\_DEDUPE"]
  G_CHARGE_ONCE -. "relies on" .-> ADR_015["ADR-015"]
  G_CHARGE_ONCE -. "relies on" .-> ADR_018["ADR-018"]
  G_CHARGE_ONCE -. promises .-> ADR_012["ADR-012"]
  G_CHARGE_ONCE["G\_CHARGE\_ONCE"] --> G_LEDGER_CONSISTENT["G\_LEDGER\_CONSISTENT"]
  G_CHARGE_ONCE["G\_CHARGE\_ONCE"] --> G_REFUND_MATCH["G\_REFUND\_MATCH"]
  G_DEDUPE -. "relies on" .-> ADR_012["ADR-012"]
  G_DEDUPE -. promises .-> ADR_007["ADR-007"]
  G_DEDUPE["G\_DEDUPE"] --> G_CHARGE_ONCE["G\_CHARGE\_ONCE"]
  G_LEDGER_CONSISTENT -. promises .-> ADR_018["ADR-018"]
  G_REFUND_MATCH -. "relies on" .-> ADR_018["ADR-018"]
  G_REFUND_MATCH -. promises .-> ADR_015["ADR-015"]
GuaranteeStatus / baselineTierPromised byRelied on byExposed callers
G_CHARGE_ONCE brokenMain: holds 1 ADR-012 ADR-018, ADR-015 checkoutservice, frontend, refundworker, webhookingress
G_DEDUPE brokenMain: holds 1 ADR-007 ADR-012
G_LEDGER_CONSISTENT brokenMain: holds 1 ADR-018 checkoutservice, frontend, refundworker, webhookingress
G_REFUND_MATCH brokenMain: holds 1 ADR-015 ADR-018

Checked and not affected

holds

ADR-016 relies on G_ACK_FAST, also provided by ADR-007. Its full prerequisite set still holds.

Who should review

ADR-007 · Anika Rao, Ravi Menon

Roles: promises. Unavailable: none.

  • Jun Park: 1 recent authored sources
  • Anika Rao: 0 recent authored sources
ADR-012 · Jun Park, Anika Rao

Roles: promises, relies_on. Unavailable: Lena Fischer, Marco Ruiz.

  • Jun Park: 7 recent authored sources
  • Anika Rao: 2 recent authored sources
ADR-015 · Anika Rao

Roles: promises, relies_on. Unavailable: none.

  • Jun Park: 1 recent authored sources
  • Anika Rao: 0 recent authored sources
ADR-018 · Ravi Menon

Roles: promises, relies_on. Unavailable: none.

  • Jun Park: 7 recent authored sources
  • Anika Rao: 2 recent authored sources

Remedies that survive verification

Only complete remedies may open a fix PR. Partial and rejected alternatives remain visible.

No verified remedy available for this assessment.

Assumption evidence

AssumptionStatePredicate / attestation
A_ACK_BEFORE_TIMEOUTWe acknowledge every webhook before Paylane gives up on the delivery holding 2000 < 5000webhook.ack_timeout_ms / paylane.delivery_timeout_ms
A_REDIS_TTLThe shared Redis cluster keeps dedupe records for the full dedupe window holding 24 <= 48webhook.dedupe_ttl_hours / redis.max_ttl_hours
A_RETRY_WINDOWPaylane stops retrying a webhook before our dedupe records expire violated 72 <= 24paylane.retry_window_hours / webhook.dedupe_ttl_hours
A_STABLE_EVENT_IDPaylane sends the same event_id on every retry of a webhook holding

Anika Rao · activeAttested: 2026-09-02 00:00 UTC
Review by: 2027-03-01 00:00 UTC

The lexical gap

Fulltext search

Fulltext for paylane | retry | window finds ADR-007, ADR-010, ADR-011, ADR-016.

Guarantee graph

The guarantee graph additionally reaches ADR-012, ADR-015, ADR-018, whose decision bodies do not mention those terms.

Source citations