PINK: FLAWS doc — backfill real SHA f3a5f21 for pass-5 entries
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -21,9 +21,9 @@
|
||||
| O10 — no `close()` on ExecutionKernel | `3ca154e` | `close()` nulls `_backend` to prevent double-free; `__enter__`/`__exit__` added |
|
||||
| N1 — `with_handle_mut` zero sync (partial) | `c87ca78` | `catch_unwind` at FFI boundary; concurrent-call UB mitigated by Python GIL |
|
||||
| Z6 — `process_intent()` no exception handler on `venue.submit()` | `a9ba407` | try/except around submit; synthetic ORDER_REJECT event feeds FSM rollback → IDLE on failure |
|
||||
| N2/N3/N4 — `_run()` two-path blocking + repeated `asyncio.run()` | `(pass-5)` | `BingxVenueAdapter.submit_async()` awaits backend directly; `ExecutionKernel.process_intent_async()` uses it; `pink_direct.step()` → `await kernel.process_intent_async()` — hot path never touches `_run()` or thread-pool |
|
||||
| N2/N3/N4 — `_run()` two-path blocking + repeated `asyncio.run()` | `f3a5f21` | `BingxVenueAdapter.submit_async()` awaits backend directly; `ExecutionKernel.process_intent_async()` uses it; `pink_direct.step()` → `await kernel.process_intent_async()` — hot path never touches `_run()` or thread-pool |
|
||||
| N5 — `_snapshot_ready` cascading re-fetch (resolved prior) | `338811e` | `reconcile()` rewritten to `async def` using `await backend.refresh_state()` directly; `_backend_snapshot()` only called from sync `submit()` (test/compat path, not production) |
|
||||
| restore_state JSON parse leaks JSONDecodeError | `(pass-5)` | `ExecutionKernel.restore_state()` wraps Rust call in `try/except (ValueError, json.JSONDecodeError): return False`; docstring contract now enforced |
|
||||
| restore_state JSON parse leaks JSONDecodeError | `f3a5f21` | `ExecutionKernel.restore_state()` wraps Rust call in `try/except (ValueError, json.JSONDecodeError): return False`; docstring contract now enforced |
|
||||
|
||||
**Sources:**
|
||||
- This file (A-series): Detailed writeups for architectural flaws.
|
||||
@@ -360,9 +360,9 @@
|
||||
| M9 — ORDER_REJECT nukes POSITION_OPEN | `fb03300` | Spurious reject (no matching order) no longer resets fsm_state; only entry-phase rejects → IDLE |
|
||||
| G9 — venue_order_id targets wrong order | `fb03300` | Routes by FSM state: exit-phase events update exit order, not stale entry order |
|
||||
| H6 — unknown enum variant crashes bridge | `fb03300` | `_safe_enum()` helper returns configurable default on unknown variants |
|
||||
| N2 | `_run()` has two completely different code paths — runtime branch, not design — **✅ FIXED `(pass-5)`** | Venue | **Critical** |
|
||||
| N3 | `_run()` path B blocks event loop thread for every venue HTTP operation — **✅ FIXED `(pass-5)`** | Venue | **Critical** |
|
||||
| N4 | `asyncio.run()` called repeatedly — creates/destroys event loops per call — **✅ FIXED `(pass-5)`** | Venue | **Critical** |
|
||||
| N2 | `_run()` has two completely different code paths — runtime branch, not design — **✅ FIXED `f3a5f21`** | Venue | **Critical** |
|
||||
| N3 | `_run()` path B blocks event loop thread for every venue HTTP operation — **✅ FIXED `f3a5f21`** | Venue | **Critical** |
|
||||
| N4 | `asyncio.run()` called repeatedly — creates/destroys event loops per call — **✅ FIXED `f3a5f21`** | Venue | **Critical** |
|
||||
| N5 | `_snapshot_ready` cascading re-fetch — N callers produce N overlapping HTTP — **✅ RESOLVED `338811e`** (`reconcile()` now uses `await backend.refresh_state()`; `_backend_snapshot` not on production async path) | Venue | **High** |
|
||||
| N6 | `BingxUserStream.close()` doesn't cancel pending tasks | Stream | Medium |
|
||||
| N7 | Live test architecture forces worst-case `_run()` path for every operation | Test | Medium |
|
||||
@@ -389,11 +389,11 @@
|
||||
| Flaw | Commit | What changed |
|
||||
|------|--------|--------------|
|
||||
| Z6 — `process_intent()` no exception handler on `venue.submit()` | `a9ba407` | try/except around venue.submit() in sync `process_intent()`; synthetic ORDER_REJECT event feeds `on_venue_event()` → FSM rolls back to IDLE; slot never stranded |
|
||||
| N2/N3 — `_run()` two-code-path blocking; event loop thread stall | `(pass-5)` | `BingxVenueAdapter.submit_async(self, intent)` added — awaits `backend.submit_intent()` directly in caller's event loop; no thread-pool, no `asyncio.run()`, no `_backend_snapshot()` round-trips |
|
||||
| N4 — `asyncio.run()` repeated; creates/destroys event loops per call | `(pass-5)` | `ExecutionKernel.process_intent_async(self, intent)` added — same guard logic as sync version; replaces `venue.submit()` with `await venue.submit_async()`; sync `process_intent()` untouched (tests stay green) |
|
||||
| N2/N3 — `_run()` two-code-path blocking; event loop thread stall | `f3a5f21` | `BingxVenueAdapter.submit_async(self, intent)` added — awaits `backend.submit_intent()` directly in caller's event loop; no thread-pool, no `asyncio.run()`, no `_backend_snapshot()` round-trips |
|
||||
| N4 — `asyncio.run()` repeated; creates/destroys event loops per call | `f3a5f21` | `ExecutionKernel.process_intent_async(self, intent)` added — same guard logic as sync version; replaces `venue.submit()` with `await venue.submit_async()`; sync `process_intent()` untouched (tests stay green) |
|
||||
| N5 — `_snapshot_ready` cascading re-fetch (confirmed resolved) | `338811e` | Confirmed: `reconcile()` is `async def` and calls `await backend.refresh_state(None, include_history=False)` — never touches `_backend_snapshot()`; the cascading issue is on the test/compat sync path only |
|
||||
| `restore_state` leaks `JSONDecodeError` on corrupt input | `(pass-5)` | `ExecutionKernel.restore_state()` wraps Rust FFI call in `try/except (ValueError, json.JSONDecodeError): return False` — matches documented contract; `test_restore_corrupt_json_rejected` now passes |
|
||||
| `step()` hot path used sync `process_intent()` (event-loop blocking) | `(pass-5)` | `pink_direct.PinkDirectRuntime.step()` line 952: `outcome = self.kernel.process_intent(kernel_intent)` → `outcome = await self.kernel.process_intent_async(kernel_intent)` |
|
||||
| `restore_state` leaks `JSONDecodeError` on corrupt input | `f3a5f21` | `ExecutionKernel.restore_state()` wraps Rust FFI call in `try/except (ValueError, json.JSONDecodeError): return False` — matches documented contract; `test_restore_corrupt_json_rejected` now passes |
|
||||
| `step()` hot path used sync `process_intent()` (event-loop blocking) | `f3a5f21` | `pink_direct.PinkDirectRuntime.step()` line 952: `outcome = self.kernel.process_intent(kernel_intent)` → `outcome = await self.kernel.process_intent_async(kernel_intent)` |
|
||||
|
||||
**Triage notes — remaining async/thread flaws:**
|
||||
- **T1** (Critical) InMemoryZincPlane Condition deadlock: test-only path; PINK production uses RealZincPlane; asyncio cooperative prevents re-entrancy. Risk: low in current architecture.
|
||||
|
||||
Reference in New Issue
Block a user