A population-fit and pilot-planning tool for examining whether behavioral-health need, access barriers, benefit-navigation friction, and community feasibility create a credible role for Double Cup in a specific health plan's population — and what a bounded pilot could look like.
Every assessment resolves to one of three outcomes. Two of them are reasons not to build a pilot — which is the point. A high behavioral-health-need population does not automatically mean Double Cup is a fit.
Need, access friction, and community feasibility line up well enough to design a small, measurable test — scoped to benefit awareness and completed navigation, not clinical care.
The concept may fit, but missing or conflicting information prevents a responsible recommendation. The tool proposes what to learn first rather than overstating relevance.
Existing programs already cover the gap, or the community model isn't feasible here. The tool names what's working and what would need to change before reassessing.
Choose one of four seeded synthetic Minnesota health plans, then adjust the assumptions to see how the recommendation moves. Nothing here is a real plan; every value is generated deterministically so a scenario reads the same on every refresh. Tip: to see the "insufficient evidence" behavior, toggle a critical field to not reported.
—
Fields marked CRIT are critical: if any is left as "not reported," the model refuses to overstate relevance and routes to discovery required. Use the "not reported" toggle to simulate missing data.
An executive-readable read produced by generateRecommendation() from the deterministic evidence packet — schema-validated before it renders. Every conclusion below traces back to a displayed signal.
Pick a scenario above and press Run assessment. The recommendation, opportunity score, confidence, supporting and counter-evidence, and a pilot or discovery plan will appear here.
These visuals redraw for the selected scenario. Values are synthetic and illustrative — they show the shape of the evidence a real assessment would weigh, not measured outcomes.
A deliberate separation: deterministic analytics compute the numbers and enforce the rules; an interpretation layer turns the structured evidence packet into readable language. Version one runs that layer locally from templates — no model-provider API key ships in the browser — behind an interface a server-side model could later fill.
In one sentence: deterministic analytics decide and stay auditable; a model only phrases the result; schema validation and human review gate every output. This is the least-autonomous design that does the job — the pattern to prefer for a consequential, regulated recommendation.
generateRecommendation() — local templates now, model adapter later.// Every field required; validation failure → safe error state { "decision": "pilot_candidate | discovery_required | not_current_fit", "opportunityScore": 0-100, "confidence": "high | medium | low", "executiveSummary": "", "priorityPopulation": "", "supportingEvidence": [ ], "counterEvidence": [ ], "missingEvidence": [ ], "recommendedNextStep": "", "pilot": { geography, duration, population, primaryOutcome, leadingIndicators[], guardrails[], expansionThreshold, stopCriteria } }
The score and the decision are not produced by a language model. They come from auditable arithmetic and explicit rules, so a plan's analytics team can reproduce and challenge them. The interpretation layer only phrases what the packet already contains — it cannot invent a conclusion the evidence doesn't support.
The generator is honestly labeled a structured recommendation prototype. It is template-driven, not a live LLM call. Swapping in a server-side model means implementing one adapter behind generateRecommendation(packet) — the UI, schema validation, and safe error state stay unchanged.
If the returned object fails schema validation, the UI shows a safe error rather than partially rendering a misleading result.
generateRecommendation(packet) is async and routes through a pluggable provider. The deterministic decision, score, evidence IDs, and request-scope disposition stay authoritative — a provider may phrase the prose, never change the verdict. Switching a provider re-scores the assessment and the whole golden suite live.
{ }// server.js — the API key stays server-side (env var).
import express from 'express';
import Anthropic from '@anthropic-ai/sdk';
const app = express();
app.use(express.json({ limit: '256kb' }));
const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
app.post('/api/recommend', async (req, res) => {
const packet = req.body; // evidence packet + disposition
const msg = await client.messages.create({
model: 'claude-sonnet-5',
max_tokens: 1200,
system: 'Phrase an executive recommendation from the '
+ 'supplied evidence ONLY. Do not change the decision, '
+ 'score, confidence, evidence IDs, or request disposition. '
+ 'Do not introduce evidence not in the packet. '
+ 'Return ONLY the fixed recommendation JSON schema.',
messages: [{ role: 'user', content: JSON.stringify(packet) }]
});
res.json(JSON.parse(msg.content[0].text)); // client re-validates + reconciles
});
app.listen(8080);The browser never holds the key. The client still validates the schema, reconciles authoritative fields, and checks groundedness on whatever the server returns — so a misbehaving model is caught, not trusted.
A pre-LLM evaluation harness for the current deterministic baseline. It scores the recommendation system against a fixed suite of 20 golden cases — including cases it is supposed to fail loudly, like missing critical data and inappropriate-use requests — using stable evidence IDs and an explicit request-scope check, then computes an illustrative release gate. It is not forced to pass.
Run the suite to compute the gate. Safety-critical gates (prohibited-evidence avoidance, critical missing-data detection, request-scope safety, schema validity, zero severe unsupported pilots, zero prohibited outputs) must be perfect or the result is "Not ready." Quality gates (decision agreement, evidence recall, precision, appropriate uncertainty) must each reach 90%.
When a case fails, the runner tags it with a failure type: incorrect fit classification · missed required evidence · selected prohibited evidence · ignored counterevidence · overstated certainty · missing-data failure · wrong request-scope disposition · unsafe/prohibited output · output-schema failure. Request-scope, prohibited-output, missing-data, and schema failures are safety-critical and force the gate to "Not ready." Boundary disagreements are flagged Decision required — a product-policy question, not a code defect.
Passing the offline gate earns a limited internal pilot, not a launch. These are the measures that would be watched once real reviewers and real members are involved — grouped by what they tell us.
The full model is here — formulas, weights, decision rules, and honest limitations. Progressive disclosure: the primary path stays readable; the arithmetic lives in these panels.
Each dimension is a weighted blend of the adjustable 0–100 inputs. Nothing is random; the same inputs always produce the same score.
The overall opportunity score is a weighted sum of the six dimensions:
The raw score is then multiplied by an incremental-fit factor = 1 − 0.4·(existingProgramStrength/100), where existing strength = 0.6·overlapping-intervention strength + 0.4·EAP engagement. This is why a plan whose gap is already covered scores lower even when raw need is high — Double Cup is measured on incremental value, not absolute need.
Classification is not a simple threshold. These rules run after scoring, in order:
Confidence is driven by data completeness and internal conflict, independent of the score. Completeness = share of the twelve inputs reported, blended with benefit-document completeness. Then:
Confidence is shown as an explicit chip with a plain-language reason, and it is displayed with both color and a filled-bar count so it never depends on color alone.