BVP Quadrant Scatter
Business Value Points vs composite cost. Tasks = small dots, arcs = larger dots. Drag a slider below to preview re-ranking client-side; Commit persists via fw bvp weight --from-watchtower (§ACD).
Live weight sliders
Drag a slider to preview re-ranking client-side (no commit). Press Commit to persist via fw bvp weight --from-watchtower (§ACD, D8). Rationale ≥30 chars required (R6).
| Driver | Server weight | Slider | Current | |
|---|---|---|---|---|
{{ d_id }}
{% if driver_names and driver_names[d_id] %}
{{ driver_names[d_id] }}
{% endif %}
{#- T-2084: per-driver 0-5 scoring rubric expand. Native
= no JS, accessible by keyboard, no Pico tooltip dependency.
Source: policy/bvp-scoring-rubric.md (D1-D4) + value-drivers.yaml
rationale (F1+). Gracefully absent when _driver_rubrics() returns
no entry for this driver. -#}
{% if driver_rubrics and driver_rubrics[d_id] %}
(?){#- T-2085: list-style:none — the explicit N below is the only number; without this the
|
{{ w }} | {{ w }} | {# T-1965 (T-1958 B): per-row Remove for free drivers only — D1-D4 are protected #} {% if not d_id.startswith('D') %} {#- T-2079: htmx replaces the JS click handler. hx-prompt collects the rationale (sent as HX-Prompt header); driver id travels in the URL query. No vanilla fetch() path means no navigation surprises if JS errors elsewhere on the page. -#} {% else %} protected {% endif %} |
Pending driver proposals ({{ pending_proposals|length }})
Agent-filed proposals awaiting your decision. Approve runs
fw bvp driver --add --from-watchtower (the Sovereign rail is
preserved). Reject appends a state: rejected row with your
rationale — both decisions are auditable in
.context/bvp-driver-proposals.jsonl.
| ID | Name | Weight | Rationale | Author | Actions |
|---|---|---|---|---|---|
{{ p.id }} |
{{ p.name }} | {{ p.weight }} | {{ p.rationale }} | {{ p.author or 'unknown' }}{% if p.task %} · {{ p.task }}{% endif %} |
Add free driver
Add a free driver (D1-D4 are protected — immutable in identity). Total drivers cap at 9 (M1).
At cap, you must drop an existing free driver to add a new one (add-one-drop-one).
§ACD: posted via fw bvp driver --add --from-watchtower. Rationale ≥30 chars (R6).
No scored entities yet. The scatter is empty until tasks/arcs carry confirmed bvp_scores: (via fw bvp confirm T-XXX --i-am-human) or estimator-proposed bvp_scores_proposed: (via the T-1922 worker; advisory). Proposed scores render at reduced opacity until confirmed.
Once scoring lands, this page will show a four-quadrant scatter:
- HV-LC (high value, low cost) — top-left, prime auto-promote zone
- HV-HC (high value, high cost) — top-right, strategic but expensive
- LV-LC (low value, low cost) — bottom-left, quick wins
- LV-HC (low value, high cost) — bottom-right, avoid
Quadrant scatter — {{ task_points|length }} task(s), {{ arc_points|length }} arc(s). Hover a dot to see cost composite (blast_radius × 0.6 + tier × 0.3 + effort × 0.1) or T-shirt fallback (Q2).
Legend:
filled = confirmed task ·
outlined = proposed task (estimator output, advisory — confirm via fw bvp confirm T-XXX --i-am-human)
·
arc (confirmed) ·
arc (proposed)
Raw data ({{ task_points|length + arc_points|length }} point(s))
| Kind | ID | Name | WF | BVP_norm | Cost | Source | Status |
|---|---|---|---|---|---|---|---|
| arc | {{ p.id }} |
{{ p.name }} | — | {{ "%.3f"|format(p.bvp_norm) }} | {{ "%.2f"|format(p.cost) if p.cost is not none else "—" }} | {{ p.cost_source }} | {{ p.status }} |
| task | {{ p.id }} |
{{ p.name }} | {# T-2192: WF column makes inceptions glanceable in the raw-data table without hovering each dot #}{% if p.workflow_type == 'inception' %}inception{% elif p.workflow_type %}{{ p.workflow_type }}{% else %}—{% endif %} | {{ "%.3f"|format(p.bvp_norm) }} | {{ "%.2f"|format(p.cost) }} | {{ p.cost_source }} | {{ p.status }} |
Per-driver scores ({{ task_points|length }} task(s) × {{ weights|length }} driver(s))
Per-driver 0-5 scores. Headers carry data-driver-id + a
title= rubric tooltip (hover the header). Confirmed scores
come from bvp_scores:; estimator-proposed scores come from
the latest bvp_scores_proposed: entry. "—" = driver not
scored for this task (e.g. new driver added after the proposal cron).
| ID | Name | {%- for d_id, w in weights.items() %}
{{ d_id }}
{%- if driver_names and driver_names[d_id] %}{{ driver_names[d_id] }}{% endif %} w={{ w }} |
{%- endfor %}
|---|---|---|
{{ p.id }} |
{{ p.name }} | {%- for d_id, w in weights.items() %}{%- if p.scores and d_id in p.scores -%} {{ p.scores[d_id] }} {%- else -%} — {%- endif -%} | {%- endfor %}