G-0004 · INC: G-0003 p95_latency_ms breach
closed
cycle 1
· flag goal_0004_latency_budget_retry · issue #5 · MR !4
## Summary Goal G-0003 (#4): "Reduce failed payments caused by gateway timeouts by 20%". Lengo Core killed the flag `goal_0003_timeout_retry` after the `p95_latency_ms` guardrail broke. The flag is already off (rollout_pct 0) and users are safe. This incident does not turn it back on, and nothing here is merged. ## What happened (kill record) - Reason, quoted: `guardrail p95_latency_ms: more than 5% of treatment requests exceed 1756 ms ((1+0.2) x control p95); lower bound 0.054` - Source: `ingest_fast_path` (the fast path killed it, not the periodic tick). - Time to kill: 620.333 ms, plus up to 5 s for clients to refresh flag state (per the kill note on #4). - Policy: hands_off, automatic kill, actions disable_flag, open_incident, reopen_goal (max 2 kills per goal). - `http_5xx_rate` was **not** part of the kill reason. Warning signs before the kill, from the analyst's decision 17 (verdict expand, 1% to 10%): - control p95 1,463 ms, treatment p95 3,242 ms. - 8.7% of treatment requests were above the 1,756 ms threshold. The lower bound of that share was 4.3%, just under the 5% trigger, so the guardrail still read "ok". - The analyst flagged p95 latency as the guardrail to watch. The kill came when the lower bound crossed 5% (0.054). - failure_rate was only -3.5% relative (interval -5.73 to +5.02 points, includes zero), far from the 20% target. - 5xx was 0.27% in control and 0.40% in treatment (+0.13 points, interval includes zero), well under the 2% hard limit. - The sample ratio check showed no mismatch (chi-square p = 0.94). ## Impact - Who: users in the flag-on arm of `goal_0003_timeout_retry`. At the 1% step the analysis had 501 flag-on users against 48,504 flag-off users. The flag was moved toward 10% in decision 17 just before the kill. I could not see the exact number of users exposed at 10%. - How long: the release notes on #4 were posted at about 16:45 UTC (flag at 1%). The kill note was posted at about 17:01 UTC, on 2026-10-24. This is roughly 16 minutes of exposure at most. I worked this out from the issue note timestamps, so treat it as approximate. - What users saw (hypothesis, see below): slower payment attempts, not more errors. The 5xx rate did not clearly move. - Users with the flag off were never affected. ## Runbook steps being followed - **RB-001#1**: confirm the timeout pattern by comparing the `gateway_timeout` share of failed payments for the last hour against the previous day. A rise above 5 points means a timeout incident. I have no payment-level data in the context note, so this comparison is still **to do** for the on-call owner. It is not done yet. - **RB-001#0** (symptoms): latency p95 sits close to the 1,500 ms client timeout because timed-out attempts are counted at the timeout value. This explains the control p95 of 1,463 ms and is relevant to the cause below. - **RB-002#0** (5xx): checked and ruled out as the trigger. 5xx was about 0.4% in treatment, against a 2% hard limit and a baseline of about 0.3%. No RB-002 steps apply to this breach. ## Suspected cause (from reading the change) The change is MR !3. `apps/pesalite/app/release.py` sets `FLAG_KEY = "goal_0003_timeout_retry"` and `TREATMENT_RETRY_POLICY = "backoff"`. In `apps/pesalite/app/retry.py` the `backoff` policy has `max_attempts=2`, `base_backoff_ms=400`, `jitter=True` and an idempotency key. The loop in `charge_with_retry` adds the elapsed time of each attempt plus the back-off delay to the reported latency. Reasoning: 1. A timed-out attempt is counted at `timeout_ms` = 1,500 ms (`gateway_sim.py`). 2. The retry then waits 200 to 400 ms (400 ms base, jittered to 50% to 100%). 3. The second attempt can time out again at 1,500 ms. The simulator treats 66% of timeouts as persistent by default (`transient_timeout_share` 0.34). 4. A payment that times out twice therefore reports about 1,500 + 200 to 400 + 1,500 = about 3,200 to 3,400 ms. This matches the observed treatment p95 of 3,242 ms. 5. The guardrail threshold is 1,756 ms
Goal metric: failure rate
holdWith the flag on: — versus off (always-valid interval — to —). Control rate —; 0 events with the flag on, 0 off. Method: msprt.
Guardrails
must not get worseLatest decision
#2833 at 1% · · tick- collecting data: 0/500 treatment events at 1%
What happened
15 events-
flow · corelengo-plan-build started (plan, attempt 1)session completed
-
handoff · ai-lengo-plan-build-gitlab-ai-hackathonstrategist → builder: done accepted, citations 100% validPlan a single-retry, back-off, idempotent, latency-budgeted gateway timeout retry behind flag goal_0004_latency_budget_retry to cut failure_rate by 20% without breaching the 5xx or p95 latency guardrails.
-
state · coreproposed → plannedStrategist plan validated
-
handoff · ai-lengo-plan-build-gitlab-ai-hackathonbuilder → gatekeeper: done accepted, citations 100% validOpened MR !4: a latency-budgeted (1,750 ms) single gateway-timeout retry with jittered back-off and an idempotency key, behind goal_0004_latency_budget_retry. Flag-off path unchanged; tests cover both flag states.
-
state · coreplanned → builtBuilder opened !4
-
flow · corelengo-gate started (gate, attempt 1)session completed
-
handoff · ai-lengo-gate-gitlab-ai-hackathongatekeeper → launcher: fixed accepted, citations 100% validLint job failed (formatting in the new G-0004 test file) and the rest of the pipeline was skipped. I committed a formatting-only fix to the MR branch. Manual policy review found no violation: no protected path, 4 files, flag wired to goal_0004_latency_budget_retry, both flag states tested, no secrets. Scans, tests and image build have not run, so there is no image digest or SBOM. A fresh pipeline on the fixed commit must pass before Core's policy check and merge.
-
state · corebuilt → gate_passedGatekeeper verdict: fixed
-
state · coregate_passed → stageddeployed to staging (deployment 1640205598)
-
flag · coreflag on at 1% (applied)allow: all checks passed
-
state · corestaged → rollout_1flag goal_0004_latency_budget_retry on for 1% of users
-
flow · corelengo-launch started (launch, attempt 1)session completed
-
handoff · ai-lengo-launch-gitlab-ai-hackathonlauncher → analyst: done accepted, citations 100% validRelease notes for G-0004 (MR !4, flag goal_0004_latency_budget_retry, live at 1%): a single jittered, idempotent retry with a 1,750 ms total latency budget. Rollout steps are 1/10/50/100, each gated by a statistics decision and minimum dwell time, with 5xx and p95 latency guardrails and automatic kill by Core.
-
flag · coreflag off (applied) time to kill 6531 msstopped by @kareemblessed: Opened by mistake: this is the incident issue for G-0003 cycle 1, which Core turned into a goal before incidents were excluded. Its change was never part of an experiment, and it held every later merge.
-
state · corerollout_1 → closedstopped by @kareemblessed: Opened by mistake: this is the incident issue for G-0003 cycle 1, which Core turned into a goal before incidents were excluded. Its change was never part of an experiment, and it held every later merge.
Memory the agents cited
21 / 21 supplied| ID | Cited by | Source |
|---|---|---|
| M-0002 | strategist | Outcome M-0002: Reduce failed payments caused by gateway timeouts by 20% |
| RB-001#0 | strategist | RB-001: Payment gateway timeouts > Overview |
| RB-001#3 | strategist | RB-001: Payment gateway timeouts > Step 3 |
| CONV-feature-flags#3 | strategist | Feature flag conventions > Guarding a change |
| AGENTS#4 | strategist | AGENTS.md: conventions for every agent working in this repository > 3. Rules for every code change |
| RB-002#0 | strategist | RB-002: High rate of 5xx responses > Overview |
| M-0002 | builder | Outcome M-0002: Reduce failed payments caused by gateway timeouts by 20% |
| RB-001#0 | builder | RB-001: Payment gateway timeouts > Overview |
| RB-001#3 | builder | RB-001: Payment gateway timeouts > Step 3 |
| CONV-feature-flags#3 | builder | Feature flag conventions > Guarding a change |
| AGENTS#4 | builder | AGENTS.md: conventions for every agent working in this repository > 3. Rules for every code change |
| RB-002#0 | builder | RB-002: High rate of 5xx responses > Overview |
| CONV-feature-flags#3 | gatekeeper | Feature flag conventions > Guarding a change |
| AGENTS#4 | gatekeeper | AGENTS.md: conventions for every agent working in this repository > 3. Rules for every code change |
| AGENTS#3 | gatekeeper | AGENTS.md: conventions for every agent working in this repository > 2. Repository map |
| RB-001#3 | gatekeeper | RB-001: Payment gateway timeouts > Step 3 |
| M-0006 | launcher | Outcome M-0006: Reduce failed payments caused by gateway timeouts by 20% |
| M-0006#p95_latency_ms | launcher | M-0006 > p95_latency_ms |
| M-0006#http_5xx_rate | launcher | M-0006 > http_5xx_rate |
| M-0006#failure_rate | launcher | M-0006 > failure_rate |
| M-0002 | launcher | Outcome M-0002: Reduce failed payments caused by gateway timeouts by 20% |
Agents may cite only IDs Core supplied in the latest context note; anything else counts against citation validity.
Flag changes
| When | Change | Status | Time to kill |
|---|---|---|---|
| goal_0004_latency_budget_retry create → 1% |
applied | — | |
| goal_0004_latency_budget_retry deactivate |
applied | 6531 ms |
Audit trail
hash chain verified| # | When | Actor | Action | Subject |
|---|---|---|---|---|
| 117 | core | goal.transition | rollout_1->closed | |
| 116 | core | flag.rollback | goal_0004_latency_budget_retry | |
| 68 | ai-lengo-launch-gitlab-ai-hackathon | handoff.accepted | launcher | |
| 67 | core | flow.start | lengo-launch | |
| 66 | core | goal.transition | staged->rollout_1 | |
| 65 | core | flag.create | goal_0004_latency_budget_retry | |
| 64 | core | goal.transition | gate_passed->staged | |
| 62 | core | mr.merged | !4 | |
| 61 | ai-lengo-gate-gitlab-ai-hackathon | handoff.accepted | gatekeeper | |
| 60 | core | flow.start | lengo-gate | |
| 59 | core | goal.transition | planned->built | |
| 58 | ai-lengo-plan-build-gitlab-ai-hackathon | handoff.accepted | builder | |
| 56 | ai-lengo-plan-build-gitlab-ai-hackathon | handoff.accepted | strategist | |
| 53 | core | flow.start | lengo-plan-build | |
| 52 | kareemblessed | goal.created | issue #5 |