Ready

mirendev/runtime#1165

I read through all four changed files carefully and traced every call site. This is a well-reasoned, tightly scoped fix for a real production bug: service chains left empty as black holes when a batch fails because a named counter is absent.

The two independent root causes are correctly identified and fixed.

  1. Counter declaration (writeChainBody, line 340): Adding tx.Add(&knftables.Counter{…}) inside the same transaction that references the counter removes the dependency on Init having succeeded first. The add verb in nft is idempotent and doesn't reset totals, so the cost is genuinely zero. The comment explaining the unknown failure mode honestly is the right call — the field evidence is gone, and hardening against the symptom rather than a speculative cause is the correct engineering choice.

  2. Cache poisoning on batch failure (Create line 475, applyGC line 340): setEndpoints optimistically records the endpoint set before the batch commits, so a rejected batch leaves the cache believing rules that never reached the kernel. On the next pass the cache hit short-circuits the rebuild, perpetuating the empty chain. invalidateChainCache() is the right remedy — it's just a clear of a mutex-protected map, the cost is one extra rebuild, and the invariant it restores (a cache entry means nft accepted that body) is exactly correct.

Coverage is solid. Three unit tests:

Plus an integration test (TestChainBodyLandsWhenCounterUndeclared) that runs against real nftables to confirm the batch actually commits when a previously undeclared counter is named.

One thing I checked and found to be fine: Init doesn't call setEndpoints, so its batch failure path doesn't need its own cache invalidation — the cache is empty at that point anyway since Init initializes it immediately before running the batch.

Nothing I'd block on. The fix is correct, the tests are precise, the comments are honest. Ready to merge.


Verdict: ready

Data

{
  "owner": "mirendev",
  "repo": "runtime",
  "number": 1165,
  "verdict": "ready",
  "event": "approve",
  "summary": "I read through all four changed files carefully and traced every call site. This is a well-reasoned, tightly scoped fix for a real production bug: service chains left empty as black holes when a batch fails because a named counter is absent.\n\n**The two independent root causes are correctly identified and fixed.**\n\n1. **Counter declaration** (`writeChainBody`, line 340): Adding `tx.Add(\u0026knftables.Counter{…})` inside the same transaction that references the counter removes the dependency on `Init` having succeeded first. The `add` verb in nft is idempotent and doesn't reset totals, so the cost is genuinely zero. The comment explaining the unknown failure mode honestly is the right call — the field evidence is gone, and hardening against the symptom rather than a speculative cause is the correct engineering choice.\n\n2. **Cache poisoning on batch failure** (`Create` line 475, `applyGC` line 340): `setEndpoints` optimistically records the endpoint set before the batch commits, so a rejected batch leaves the cache believing rules that never reached the kernel. On the next pass the cache hit short-circuits the rebuild, perpetuating the empty chain. `invalidateChainCache()` is the right remedy — it's just a clear of a mutex-protected map, the cost is one extra rebuild, and the invariant it restores (a cache entry means nft accepted that body) is exactly correct.\n\n**Coverage is solid.** Three unit tests:\n- `TestChainBodyDeclaresItsCounter` — verifies the `add counter` line appears in the batch *before* the `counter name` reference (catches ordering regressions, not just presence).\n- `TestFailedApplyDoesNotPoisonChainCache` — directly exercises the `invalidateChainCache` path by simulating a failed apply, then verifies the next pass rebuilds.\n- `TestUnchangedEndpointsStillSkipRebuild` — guards the optimization so the fix doesn't break the cache's reason for existing.\n\nPlus an integration test (`TestChainBodyLandsWhenCounterUndeclared`) that runs against real nftables to confirm the batch actually commits when a previously undeclared counter is named.\n\n**One thing I checked and found to be fine:** `Init` doesn't call `setEndpoints`, so its batch failure path doesn't need its own cache invalidation — the cache is empty at that point anyway since `Init` initializes it immediately before running the batch.\n\n**Nothing I'd block on.** The fix is correct, the tests are precise, the comments are honest. Ready to merge.",
  "posted_to_pr": true
}