Capital Tensor's crypto modality fits its panel against CoinGecko categories — layer-1, decentralized-exchange, lending-borrowing, stablecoins, and so on. Users on Elite can compose a custom universe of categories. Early on we hit a recurring failure: certain category pairs would produce byte-identical weekly panels, the tensor fit would succeed but with a degenerate equilibrium row, and the Node-side wrapper would reject the snapshot with a generic 502 — after the user had waited through a full ingest cycle.
The canonical case was layer-1 + smart-contract-platform. CoinGecko classifies BTC, ETH, BNB, SOL, and XRP into both categories at top-5-by-mcap. Pulling top-N for each category returned the same coins in the same rank order; the resulting weekly market-cap panels were identical; the equilibrium tensor's rows were duplicated; the post-fit detector caught the duplicates and 502'd. The user saw a generic upstream error a minute or two after submitting the request.
The fix that shipped is a pre-fit category-overlap guard. After step 1 of the ingest (resolve top-N coin ids per requested category — one cheap request per category) and before step 2 (fetch market-cap history — many expensive requests), the guard computes the Jaccard similarity between every pair of top-N sets. If any pair's similarity exceeds 0.6, the guard raises CategoryOverlapError, the FastAPI handler returns 422 with a structured error_code: 'category_overlap' detail carrying the offending pair, the shared coin ids, and the actual Jaccard value. The Node wrapper passes the 422 through with the structured payload intact, and the dashboard renders a precise prompt instead of a server-error.
Why 0.6 specifically. We measured the canonical layer-1 + smart-contract-platform collision at top-5 (Jaccard 1.0 — every coin shared) and intentional non-collisions like layer-1 + lending-borrowing (Jaccard ~0.17 — only ETH or BNB might appear in both). The threshold has to sit comfortably above the natural-overlap range and well below the collision range. A pair that shares 4 of 6 candidates (Jaccard 0.67) is genuinely too similar to fit independently; a pair that shares 3 of 7 (Jaccard 0.43) is fine. 0.6 puts the boundary in the gap.
The change also collapses an entire class of post-fit-rejected requests into a fast pre-fit refusal — instead of waiting for the full ingest to complete and then 502-ing, the user gets the structured 422 within seconds and the engine doesn't burn its CoinGecko quota on a request that was always going to be rejected. Tested via a focused pytest suite covering full overlap, partial overlap below threshold, the exact 0.6 boundary, multi-category lexicographic ordering, single-category no-op, and empty-top-N edge cases.
Vortex Legacy
Vortex Research Suite modules produce quantitative diagnostic assessments only. They do not constitute investment advice, price prediction, or buy/sell recommendations.