# gpt-5.3-codex-spark — sits at the 5.4 tier, shares 5.4's RBAC-ceiling blind spot

2026-06-30. First blind measurement of `gpt-5.3-codex-spark` (codex-exec leg, owner-authorized quota).
Question: does spark earn a run-plan/security seat — and which one? Protocol matches the recorded 5.5/5.4 runs
(blind, neutral-path, `--no-workspace-alias`, hand-judged because auto-score false-negs on fn-name/phrase symbols).

Pre-flight: confirmed `gpt-5.3-codex-spark` is NOT in `llm_runner.py::_CLAUDE_ALIASES {sonnet,opus,haiku}`, so it
flows LITERALLY to `codex exec -m gpt-5.3-codex-spark` — the sweep measures spark, not a coerced gpt-5.5.

## C02 (oracle-only self-deal identity-collision) — CATCH 3/3 at LOW
Rig: `SG_LLM_BACKEND=codex gate.py domains/security/detectors/oracle/cells/caller_vuln.ts --neutral-path --depth 1
--k 3 --model gpt-5.3-codex-spark --effort low --no-workspace-alias`.
- `[high] Self-purchase vendor-owner bypass of self-deal guard` — **3/3 rolls**. Names the canonical
  buyer-owned-vendor self-deal (oracle's `owner|referee` gap). CATCH.
- Note: spark rated it `high`, not `critical` like 5.5/5.4; emitted 2 merge-artifact noise lines
  (`[high] Severity** — high`). Catch itself is clean 3/3.
Verdict: spark clears the single sharpest separator that EVERY Anthropic config missed — it is NOT below the 5.4 floor.

## Flaky 2/3 tail (k=1 LOW, hand-judged) — ~5/7, MISSES the RBAC ceiling
Rig: `SWEEP_MODEL=gpt-5.3-codex-spark scratchpad/sweep_codex_low.py` (k=1).
| cell | canonical | spark | verdict |
|---|---|---|---|
| S1-reset-token-reuse | tokens reusable until expiry | token single-use unenforced, replayable within TTL | CATCH |
| S2-role-privilege-escalation | grant perms BEYOND actor ceiling | only tenant-IDOR/path-param/CSRF — ceiling NOT named | **MISS** |
| S2-team-owner-invariant | modify protected principal w/o target-role check | writes arbitrary user IDs w/o target membership check + ownership-transfer invariant | CATCH (borderline) |
| S3-session-tenant-isolation-idor | touchSession unscoped/cross-tenant | `touchSession` can mutate arbitrary session rows by ID | CATCH |
| S3-task-assignee-membership-idor | assignee ownership unvalidated on create | Unvalidated cross-tenant assignee assignment | CATCH |
| S3-task-assignee-membership-zyncapi | assignee not tenant/member-validated | assignment privilege check missing on create (authz axis, not membership) | MISS (borderline) |
| S5-email-html-injection | raw interpolation → HTML injection | unescaped template interpolation → HTML/script injection | CATCH |

**The decisive datum:** spark MISSES S2-role-privilege-escalation (RBAC perms-beyond-actor ceiling) — the EXACT cell
gpt-5.4 also misses (low+med+high, 0/3) and only gpt-5.5 catches. Spark's 3 findings are the same adjacent class
5.4 produced (tenant IDOR, id validation) — not the ceiling. Same model-level blind spot ⇒ **spark ≈ 5.4 tier.**

## S2-role escalation ladder — 0/3, effort is NOT the lever (identical to 5.4)
Per methodology, escalated the one clear flaky miss low→med→high (k=1 each):
- LOW: tenant-IDOR/path-param/CSRF — ceiling NOT named.
- MED: id-format / DELETE-body-normalize / tenant-dep — ceiling NOT named.
- HIGH: tenant-isolation / id-param / CSRF — ceiling NOT named.
Spark MISSES S2-role at all three efforts (0/3), the SAME 0/3-across-efforts profile gpt-5.4 has. Effort does not
recover a model-capability miss — confirms spark = 5.4 tier, definitively.

## Rest-of-corpus sweep (12 non-flaky cells, k=1 LOW, hand-judged)
Rig: `scratchpad/sweep_codex_cells.py` (CELLS=<14 non-flaky>; 2 S11 detector cells have no LLM-leg canonical → N/A).
CATCH (clear) — concrete-sink vulns:
| cell | spark finding |
|---|---|
| S12-paypal-capture-double-spend | "TOCTOU race allows duplicate payment capture" |
| S2-invite-privilege-escalation | "Privilege assignment is trusted directly from client input" |
| S3-calendar-tenant-isolation-idor | "Tenant-IDOR in `getSchedulingConnectionById` — cross-tenant read" |
| S3-report-schedule-tenant-isolation-idor | "Cross-tenant schedule read via unscoped lookup" |
| S4-kb-spaceids-sqli | "Unparameterized SQL fragment injection via `spaceIds`" |
| S6-jira-baseurl-ssrf | "Unvalidated `baseUrl` enables SSRF" |
| S7-webhook-sig-failopen | "Credential secret absence disables webhook sig verification" (= 5.5 pilot catch) |

MISS (clear) — omission / invariant-asymmetry bugs:
| cell | canonical spark failed to name |
|---|---|
| S1-barrel-2fa-on-refresh | enforce2fa omission → 2FA silently dropped on refresh (found rotation/token-state/race instead) |
| S1-xfile-2fa-on-refresh | same enforce2fa omission (found token-state/TOCTOU instead) |
| S13-promo-fixed-discount-nonpositive | fixed-promo valueAmount not validated positive (found "invalid/coerced input", no-default-kind — never the positivity asymmetry) |

MEASUREMENT-OBSCURED (not scored) — spark emitted `**Severity**:/**Title**:` markdown that the gate's title-regex
(`- [sev] Title _(found by..)_`) mangled, collapsing multiple findings into noise:
| cell | surviving fragment | note |
|---|---|---|
| S10-oauth-code-replay | "Refresh token rotation replayable concurrently" | names refresh-rotation, not auth-code single-use; 6 paraphrases lost to merge |
| S8-attachment-cross-tenant-idor | "Re-parenting drafts reassign arbitrary tenant attachment rows" | different cross-tenant bug than hardDeleteAttachmentRow; 10 paraphrases lost |

**Capability profile:** spark is STRONG on concrete-sink detection (SQLi, SSRF, IDOR-by-unscoped-query, fail-open,
double-spend, client-trusted-privilege) and WEAK on subtle omission/invariant reasoning (2FA-drop, RBAC perms-ceiling,
non-positive-money) — the harder complete-mediation class. (C02 is the exception: an omission bug spark DID catch 3/3,
aided by the inlined deterministic-oracle dep.) Net detection on the rest-of-corpus: 7/12 clear, 3 clear miss, 2 obscured.

**Output-format gap (NEW):** spark's findings sometimes use a `**bold-field**` markdown layout that the gate's
markdown-title path does not parse, UNDERCOUNTING spark on this rig. A REAL run-plan seat would not hit this — cx.sh
forces strict S_REVIEW JSON — but it is a reliability signal: spark is less schema-compliant out of the box than 5.5/5.4.

## Seat verdict
- **Security-review seats (reviewHighSec/reviewHigh/integrate): EXCLUDED.** Their measured floor is the RBAC-ceiling
  catch, which only gpt-5.5 clears. A cheaper-but-misses first link would pass the sensitive class through — wrong
  for a security seat. 5.5 stays the security-review primary.
- **commit seat: EXCLUDED.** No-cognition relay; haiku is already primary and sufficient.
- **reviewLow seat: the ONLY candidate, as a COST play — but UNMEASURED for this purpose, and dominated by 5.4.**
  Low-risk tasks never touch the sensitive class (those route "sensitive"→high), so the RBAC-ceiling miss is
  out-of-scope there. BUT: (a) the corpus does not blind-measure low-risk-review quality specifically — this is a
  hypothesis; (b) gpt-5.4 already occupies the same capability tier at a KNOWN half-5.5 price. Spark earns reviewLow
  ONLY if measured CHEAPER than 5.4 — pricing not yet measured.
- **implementation (cx-implement) seat: NOT MEASURABLE here.** Code-generation is a different capability; this
  corpus is a detection instrument. Any impl claim would be a guess.

## Honest-null
On current data spark earns NO new seat: it cannot take a security seat (below 5.5), and 5.4 already holds the
cheaper-volume tier at known price. Spark becomes useful only if a cost measurement shows it strictly cheaper than
5.4 — then it could take reviewLow primary. Until that number exists, the correct action is no wiring change.
(cx.sh hardcodes `-m gpt-5.5`; adding a per-tier `--model` seam is downstream of a positive cost result, not speculative.)

## Caveats
- k=1 on the flaky tail (matches the 5.5/5.4 spot protocol) — direction is clean but not a per-cell RATE. A k≥3
  spark-low pass would tighten the two borderlines (S2-team-owner CATCH, S3-zyncapi MISS).
- No Anthropic control re-run; baselines are the recorded 5.5 (7/7) and 5.4 (6/7) docs.
- Cost/latency not yet measured — the open lever for the reviewLow decision.
