← back to Govarbitrage

apps/mobile/device-proof-evidence/COMPLETENESS-FINDING.md

52 lines

# GovArbitrage — App-Completeness / Paywall Finding (TK-10279) — 2026-09-02

Read-only probe of the LIVE backend the app depends on (https://auctions.agentabrams.com).
No writes, no auth, no ASC actions.

## FINAL VERDICT — the app is complete on a fresh free install

The mobile app always sends an Authorization header, including `Basic Og==` for blank optional
credentials. The server intentionally treats Basic/Bearer requests as native-app clients, so a fresh
install receives the full valuation, cost, ROI, recommended-max-bid, scores, and research journey.
No paid credential and no Sign in with Apple action are required. The browser-only observation below
is retained as superseded diagnostic history and must not be used as the App Review conclusion.

## Backend is healthy + content-rich (good 2.1 evidence)
- `GET /api/listings` → **total: 2548** real opportunities, 25/page, `tier: FREE`.
- Rows carry: id, source, title, category, condition, quantity, **currentBid, currentCost**, recommendedMaxBid, retailLow.

## SUPERSEDED diagnostic: browser-style requests are gated
- On the free/unauthenticated tier the detail endpoint returns `gated: true`, `costBreakdown: null`,
  `recommendedMaxBid: null`, `scores: []`.  Confirmed identical across browser / okhttp / RN / no User-Agent
  — so it is NOT ungated by app User-Agent; only real auth ungates it.
- List rows on free tier: `recommendedMaxBid`, `roi`, `retailLow`, score all **null** → the card shows
  **Current Bid only** (ROI / Max-Bid / Score blocks are conditionally hidden).
- Detail screen with `costBreakdown` null renders **"Valuation data requires a paid tier."** and NO Max-Bid callout.

## SUPERSEDED interpretation of ungate paths
1. Sign in with Apple → Bearer JWT  ← IDENTITY ACTION, gated-off per task
2. Basic-auth username/password in Settings  ← NOT an Apple-identity action
3. Machine token: password prefixed `token:` → `x-import-token` header  ← NOT an identity action

## Why the superseded interpretation would have mattered
A fresh reviewer install shows real listings + working nav + connection test, but EVERY analytic
(valuation / cost / ROI / recommended max bid — the app's core value) is behind "requires a paid tier."
That is a classic 2.1 trigger. To record the required valuation/cost/ROI/max-bid journey, the device
must be authenticated to a paid tier via path 2 or 3 (NOT Apple sign-in). Needs a valid paid credential.

## CORRECTION (same session, deeper trace) — the app is NOT gated; it is COMPLETE on free install
Server logic `moneyMathVisible(tier) = tierDef.showMoneyMath || isAppClient()`, and
`isAppClient() = request has an Authorization: Basic|Bearer header`. The mobile app ALWAYS sends one
(getAuthHeaders → buildBasicAuthHeader even with empty creds = `Basic Og==`). So a FRESH FREE install
IS an app-client → fully UNGATED. Browsers (no auth header) stay gated; the app never is.

PROVEN by replicating the app's exact header (`Authorization: Basic Og==`) against LIVE prod:
- detail `gated:false tier:FREE` → recommendedMaxBid **$103.93**, expectedNetProfit **$182.96**,
  totalInvestment $95.76, scores [92.66,88.46,88,82.07,80.19], research present.
- list row → recommendedMaxBid $103.93, **roi 1.91 (191%)**, netProfit $182.96, opportunityScore 82.07, retailLow $252.

Bottom line: the earlier "requires a paid tier" concern does NOT apply to the app. A plain fresh free
install shows the FULL valuation/cost/ROI/max-bid journey with no sign-in. Strong 2.1-completeness evidence.
Both recording passes will therefore look the same (app always ungated); a paid credential is NOT needed.
Evidence: api-detail-appclient.json, api-listings-appclient.json.