Skip to main content

Router candidates triage

Operator walkthrough for /dashboard/router-candidates — frontend-only triage UI for the LLM-classified rail-candidates report. Filter, claim, defer, reject, export.

1 min read · updated

Router candidates triage

The /dashboard/router-candidates page is the operator's triage surface for new rails to add to the meta-tool router. It consumes the markdown report produced by the offline classifier (scripts/classify-meta-tool-candidates.ts) and lets you mark each candidate as claimed, deferred, or rejected — then export the claimed subset as JSON for hand-curation.

The page is fully frontend-only. Nothing the operator drops on the page leaves the browser; there is no server round-trip and no telemetry. This matters because the classifier output may include unredacted tool descriptions and fragments of the catalog that should not flow through the standard logging path.

Use this page after running classify-meta-tool-candidates.ts against the live mcp_tools catalog. Without a fresh markdown report, the page renders an empty triage state and a link back to the script docs.

Generating the report

The classifier is a one-shot operator script. It walks the entire mcp_tools catalog (~2,200 rows in production), and for each tool asks Claude Haiku whether the tool is a routing candidate for one of the 9 meta-tools — and at what confidence.

# from codespar-enterprise
npm run classify:meta-tool-candidates -- \
  --output scripts/meta-tool-candidates.md

The output file at scripts/meta-tool-candidates.md is gitignored. A full run against the 2,200-row catalog costs roughly $0.50 in Anthropic API spend and takes 15–30 minutes wall-clock. Re-run when the catalog grows materially or when you add a new meta-tool that needs back-fill.

Triaging

Drop the markdown file onto the page (or use the file picker). The browser parses it via parse-candidates.ts and renders one row per candidate with these controls:

  • Filter by meta-tool. Limit the view to candidates for a single meta-tool — codespar_pay, codespar_charge, codespar_invoice, codespar_notify, codespar_ship, codespar_crypto_pay, codespar_kyc, codespar_discover, codespar_manage_connections.
  • Filter by confidence. The classifier emits a 0–1 confidence per candidate. Hide low-confidence rows when you are sweeping for obvious wins.
  • Filter by vertical. One of the 9 verticals — payments, banking, crypto, communication, ecommerce, erp, fiscal, fraud, identity.
  • Sort by any of the columns (meta-tool, confidence, provider, vertical).

Per row, three actions:

ActionMeaning
ClaimYou will hand-curate the to_canonical / from_canonical transforms for this candidate and add it to META_TOOL_CATALOG.
DeferPlausible but not next-batch. Revisit on the next sweep.
RejectClearly wrong classification — the tool does not belong on this meta-tool. The exporter excludes rejected rows.

State persists in localStorage keyed by the report's checksum, so a reload (or a closed-tab-by-accident) does not erase your triage progress. Drop a fresh report and the keys reset.

Exporting

The Export claimed button downloads a JSON file containing only the claimed candidates. Shape:

[
  {
    "meta_tool": "codespar_charge",
    "provider_id": "stone",
    "tool_name": "STONE_CREATE_CHARGE",
    "confidence": 0.94,
    "vertical": "payments",
    "rationale": "Direct inbound Pix-or-card charge endpoint…"
  }
]

Take the JSON to catalog/<provider>.json and hand-write the to_canonical / from_canonical transforms. Add the row to META_TOOL_CATALOG once the transforms pass dry-run-meta-tools.ts --ci. The classifier suggests; you author.

Why frontend-only

The triage report is sensitive enough that round-tripping it through the backend would create a meaningful logging surface. Frontend-only avoids that:

  • No request is made to api.codespar.dev with the report contents.
  • No analytics event captures the rows.
  • The exporter writes to the user's download directory; the backend never sees the claimed list.

If the operator wants to share triage state across machines, they export the JSON and check it into a private operations repo by hand. There is no CodeSpar-hosted sync.

Next steps

Edit on GitHub

Last updated on