--- name: my-performance description: Generate a partner's own performance scorecard with one customer — their EULER health score (0–100), key stats (revenue, deals, commissions, referrals), and the single biggest thing to improve — using EULER MCP tools. Use this skill whenever a partner wants their personal performance read — phrases like "how am I doing", "my performance", "my numbers", "my partner scorecard", "how's my pipeline", "am I on track this quarter". Partner-facing (a partner viewing their OWN numbers), NOT a customer admin reviewing partners — that distinction selects this over generate-qbr. --- # my-performance — your performance scorecard ## When to use this skill Invoke when **a partner** wants a read on **their own** performance with one customer — a fast self-service scorecard: their health score, the headline stats, and the single biggest thing to improve: - "How am I doing?" / "How am I doing with {Customer} this quarter?" - "My performance" / "My numbers" / "My partner scorecard" - "How's my pipeline?" / "Am I on track with {Customer}?" - `/euler-for-partner-managers:my-performance` DO NOT invoke for: - **A customer admin reviewing a partner** — that is `generate-qbr` (third-person, the full shareable retrospective). This skill is the partner looking at *themselves*. - **A customer admin wanting the whole roster** — a ranking across all the customer's partners. This skill is one partner, one customer. The distinction that selects this skill: **the connected account is the partner, and the subject is that same partner's own numbers.** It is the partner-facing **mirror of generate-qbr** — same underlying signals, same health model, but self-scoped, framed for self-improvement ("you/your"), and lighter (a scorecard, not the full doc). ## Account type — required: partner This skill is partner-scope — the **inverse** of the customer-admin gate. It needs a connection with a `type === 'partner'` entry (the partner viewing their own numbers). **Step 1 is always `list_accounts`.** Apply the account gate in [`references/account-gate.md`](references/account-gate.md) before anything else: - Connected account has a `type === 'partner'` entry → proceed (partner context); take `partner_id` + `affiliate_company_name` from that entry. - **Customer-only connection** (no `type === 'partner'`) → emit the friendly gate message and **STOP** (do not proceed into a raw `forbidden_scope`): "my-performance shows *your* numbers as a partner; you're connected as a customer admin — for a partner review use `generate-qbr`, or open your dashboard: ``." Use the `dashboard_url` from the customer entry. - Both roles → proceed as the partner (use the partner entry). `partner_id` comes **only** from the chosen `type: 'partner'` entry — **never** from `partner_directory_search` (that returns a directory `profile_id`, rejected downstream as `partner_not_in_consent`). Translate any escaping `forbidden_scope` into the same friendly message; never show the user `forbidden_scope` or any `euler_*` code. ## Inputs (optional — never block) No partner is named — it is always the caller's own data. Two optional inputs only: | Input | Default | Accepts | |---|---|---| | **Which customer** | the only `type:'partner'` account | a customer name → match `affiliate_company_name`. If >1 partner account and the user named none (or it matches several), **ask** which — show the `affiliate_company_name` list. | | **Time window** | last **90 days** | "this quarter" / "last 30 days" / "Q1 2026" / explicit dates. Convert to `start_date` / `end_date` in **`YYYY-MM-DD`** (no time component — the datetime form is broken backend-side, same gotcha as `generate-qbr`). | The 90-day default matches the health model's window for Production / Engagement / Recency. One partner + one customer pairing per invocation — do not fan out across accounts. ## Orchestration sequence The **QBR subset, self-scoped** — ~5–6 calls. For exact response field paths and the backend quirks per tool, consult [`references/mcp-field-paths.md`](references/mcp-field-paths.md) (numerics arrive as strings; `referrals` is loose JSON; dates are `YYYY-MM-DD`). | # | Tool call | Provides | |---|-----------|----------| | 1 | `list_accounts` | Account gate + `partner_id` + customer `affiliate_company_name` (header). | | 2 | `performance(action:'partner', partner_id, start_date, end_date)` | **Window** headline metrics: closed-won revenue, deal count, win rate, sales cycle, ACV. | | 3 | `partner_artifacts(action:'deals', partner_id)` | **Lifetime** open pipeline (`Deal name`, stage, `Amount`). | | 4 | `commissions(action:'partner', partner_id, start_date, end_date)` | **Window** commissions earned + breakdown. | | 5 | `referrals(action:'for_partner', partner_id)` | **Lifetime** referrals submitted (+ `Submitted On` dates). | | 6 | `partner_artifacts(action:'agreements', partner_id)` | Agreements — `Status` + `Signed On`. | **These six are exactly the signals the health model needs** — so the score in §Your health score is computed from data already in hand, **no extra calls**. (This is the light scorecard: no attribution split, no historical quarters, no invoices — those are `generate-qbr`'s heavier retrospective.) ### Error handling - Customer-only account → friendly gate message (see §Account type), STOP. - `partner_not_in_consent` → tell the user to disconnect + reconnect and include this account in their consent selection; do not render a partial scorecard. - `backend_data_issue` on `list_accounts` → surface its `support_email`, note reconnecting won't help, and continue with whatever the other tools return. - `forbidden_scope` escaping mid-run → translate via `references/account-gate.md` into the friendly message; never surface the raw code. - Any single tool empty/errors mid-run → continue; one-line footnote at the END of the read if a section could not be loaded. No giant banner; the scorecard must still present. ## Your health score Compute the partner's health per [`partner-health-model.md`](references/partner-health-model.md) in **full** mode — you already fetched every source in the Orchestration sequence, so this adds no extra calls. **Use exactly these five factors and weights — do not rename, drop, re-weight, or invent factors** (no "Compliance", no 4-factor variants): | Factor | Weight | From | |---|---|---| | Production | 35 | closed-won revenue + deals (window) | | Pipeline | 20 | open pipeline value | | Engagement | 20 | referrals submitted + recency | | Foundation | 15 | foundational agreements signed | | Recency | 10 | days since last deal/referral | `score = Σ(factor_norm × weight ÷ 100)` → an integer **0–100**. The per-factor normalization thresholds, band cutoffs, and hard-rule caps live in the model doc — apply them **verbatim**. Produce: - the **score 0–100** (always show the number — never just a band), - the **band** (Healthy / Watch / At-risk / Ramping), - the **breakdown** across **all five** factors (each as value out of its weight — e.g. "Production 28/35 · Pipeline 8/20 · …"), and - the **next lever** = the **lowest-contribution** factor, framed as one concrete action ("Your biggest lift: Pipeline 8/20 — only $18k open; the others are strong"). **Caps — apply only the model's exact rules; never invent one.** A partner with lifetime closed-won is **NOT** capped merely for 0 closes in the window — its band comes from the score. The Watch cap fires only when its full condition holds (0 in-window **and** 0 lifetime closed-won, or an unsigned foundational agreement **and** 0 lifetime closed-won); name a cap in the read only then. This is **transparency** — the partner sees exactly how their customer's health model reads them, and exactly which move grows the number. Same model `generate-qbr` uses, viewed from the partner's own side. ## Product how-to questions (`euler_help`) If the user asks how EULER itself works or how to do something in the product — not about their own data — e.g. "how do I register a deal", "where do I find X in the portal", "how does onboarding work" — call `euler_help` with their question and answer briefly from its result. Do not guess about product behavior. This is a tangent to this skill's main job: answer in 1–3 sentences (no HTML report) and return to the task. ## Output format Render a **single self-contained HTML file** — no external CSS/fonts/scripts beyond the one web-font import. Opens in a browser, prints to PDF, or shares by file/link (email, Notion, Slack). Note: pasting raw HTML into Slack does not render — share the file or a link. ### How to produce the HTML 1. Read [`assets/styles.css`](assets/styles.css) and inline its **FULL** contents into a single `