Developer Productivity Dashboard — V1 Build-Out Playbook
Developer Productivity Dashboard — V1 Build-Out Playbook
STATUS: COMPLETE (as of 2026-07-23). T0/T1/T2 shipped and merged to
dev. T3 and T5 were relocated todocs/playbooks/v2-team-velocity-playbook.md(owner: Fatima) — see that file for their live status. T4 (commit-trailer attribution) was deleted outright — the trailer convention was judged not the best solution for AI-attribution and will not be built; its work-item file was removed. New work (UI responsiveness, BOLDVelocity branding, Next.js/Vue migration) lives indocs/playbooks/v3-platform-modernization-playbook.md(owner: Sultan) and must land ondevbefore v2’s remaining tasks resume. This file is kept as the historical record for T0–T2; do not add new tasks here.
File:
docs/playbooks/v1-dev-productivity-dashboard-playbook.mdBase branch:dev(integration branch —mainstays protected/production; PRs targetdev) Branch naming:feature/<ado-task-id>-<slug>-v1-pr<n>(e.g.feature/112270-azure-devops-connector-v1-pr1) — PR-0 is the exception, committed directly todevwith no feature branch (see PR 0). Plan date: July 2026 Source spec:uploads/AlphaBOLD_Dev_Productivity_Dashboard_Design.docx(extracted toscratch/extracted_text.txt), Sections 5–9
How to Use This Document
Single source of truth for turning the current repo — a design-canvas mockup
(Developer Productivity Dashboard.dc.html + mockData.js) of the chosen “Editorial Soft”
dashboard design — into the real system described in the design doc’s Section 5
(Recommended Architecture) and Section 8
(Implementation Roadmap): connectors → metrics store → served dashboard → optional AI Assistant.
Each PR has a verbatim prompt block — copy the fenced block, paste into a fresh Claude
Code session, let it execute.
Task order is T0 → T1 → T2 → T3 → T4 → T5, matching the roadmap’s phase order (Section 8). PR numbers now match task numbers 1:1 (PR-0 = T0 … PR-5 = T5). Each phase’s PR(s) branch from the previous phase’s merged work — this is a straight stack, not a fan-out, because each phase’s connector/API is additive on top of the last (Section 6.3: “Build in phases, not all at once”).
Reference inside Claude Code:
@docs/playbooks/v1-dev-productivity-dashboard-playbook.md read section "PR 1" and execute the prompt verbatim0. Prerequisite — Baseline Commit
This directory is currently untracked in its git repo (~/Projects, branch main) — the
mockup files (Developer Productivity Dashboard.dc.html, mockData.js, support.js, assets/,
CLAUDE.md, USAGE.md) have never been committed. Before any PR branches, commit the existing
prototype to main as-is (it is the visual spec PR-0 works from — do not modify it as part of
this commit). No PR in this playbook should be the one that first introduces these files.
Then cut dev from main. PR-0 (T0) is committed directly to dev — no feature branch, no
PR review — since it’s the bootstrap step that establishes dev’s initial working state (shell
extraction + graphify knowledge graph). Every PR from PR-1 onward branches from dev or a
prior PR’s branch, and goes through the normal feature-branch + PR review flow back into dev.
main stays the protected production branch; promoting dev → main for a release is a
separate, later decision outside this playbook’s scope.
1. Executive Summary
| # | Item | Status / Gap | Roadmap phase |
|---|---|---|---|
| T0 | The dashboard design exists only as a stakeholder-review canvas (.dc.html, CDN-loaded React/Babel via support.js, not shippable) | No production dashboard shell exists yet; mock data is hardcoded in-repo with no served API | Phase 1 (shell) — DONE, merged to dev |
| T1 | No connector layer | No code pulls Git/Azure DevOps activity; mockData.js fabricates commits/PRs/velocity instead of reading real data | Phase 1 (connector) — DONE, merged to dev |
| T2 | No metrics store or read API | Dashboard reads mockData.js directly in-browser; nothing persists or pre-aggregates | Phase 1 (store + API) — DONE, merged to dev |
| T3 | No AI-tool usage data | Copilot Metrics API, Copilot Studio, and Claude Code Admin API are not integrated; tool-adoption sparkline has no real backing data | Phase 2 — relocated to v2-team-velocity-playbook.md, on hold (blocked on IT secret-key provisioning for Copilot/Copilot Studio/Claude Code Admin API credentials) |
DELETED. Commit-trailer attribution (Assisted-By: copilot/claude-code) judged not the best solution; no replacement scoped yet. | |||
| T5 | No natural-language query layer | No AI Assistant/chatbot exists over the metrics store; design doc’s optional Claude Code Skill (Appendix A) is superseded by an assistant integration per this playbook’s latest revision | Phase 4 — relocated to v2-team-velocity-playbook.md |
Initial AI-tools integration scope: V1 (T3/T4) integrates exactly three AI tools — GitHub Copilot, Copilot Studio, and Claude Code. Cursor is not part of this initial integration (no usage connector, no commit-trailer value, no export ingestion); revisit as a P2 addition if adoption data shows real Cursor usage worth tracking.
PR Strategy — DONE: PR-0 through PR-2 (T0–T2), merged to dev. PR-3/PR-5 relocated, PR-4 deleted.
- PR-0 carries T0: extract the chosen “Editorial Soft” design out of the
.dc.htmlcanvas format into a plain dependency-free static page, still fed bymockData.js(unchanged data contract), plus a graphify knowledge-graph pass over the repo. Committed directly todev— no feature branch, no PR review — since this establishesdev’s initial working state. DONE. - PR-1 carries T1: the Azure DevOps connector (Section 5.1) — a scheduled, code-only script,
no LLM calls. Branches from
dev. DONE. - PR-2 carries T2: the metrics store (Section 5.2, SQLite for the pilot) and thin read API
(Section 5.3), and switches the dashboard shell from
mockData.jsto real API calls behind the same data shape, so PR-0’s UI code needs no rewrite. Branches from PR-1. DONE — PR-1/PR-2 merged todevtogether as the Phase 1 checkpoint. - PR-3 (T3) and PR-5 (T5): relocated to
docs/playbooks/v2-team-velocity-playbook.md(owner: Fatima). See “PR 3”/“PR 5” pointer sections below. - PR-4 (T4): deleted — see “PR 4” pointer section below.
Merge Sequencing
- PR-0 (T0) → committed directly to
dev. DONE. - PR-1 (T1) → DONE.
- PR-2 (T2) → DONE — PR-1 + PR-2 merged to
devtogether as the Phase 1 MVP milestone. - PR-3 (T3), PR-4 (T4), PR-5 (T5): see relocated/deleted pointer sections below — no further merge sequencing tracked in this file.
Model Guidance
| PR | Task | Recommended Model | Effort | Reason |
|---|---|---|---|---|
| PR-0 | T0 (design shell extraction + graphify) | Sonnet 5 | medium | Mechanical port of the canvas’s markup/CSS out of .dc.html binding syntax into plain JS, but needs care not to lose interaction behavior (filters, sort); plus a graphify pass |
| PR-1 | T1 (Azure DevOps connector) | Sonnet 5 | medium | New scheduled script + Azure DevOps Git REST API calls + normalization to Section 3’s metric definitions |
| PR-2 | T2 (metrics store + API) | Sonnet 5 | medium-high | New schema, ingest-time aggregation, thin API layer, and swapping the dashboard’s data source without changing its rendering code |
Model Guidance for T3/T5 now lives in v2-team-velocity-playbook.md. T4 is deleted — no guidance
needed.
2. PR Plan
| PR | Branch | Items | Branches from | Est. | Status |
|---|---|---|---|---|---|
| PR-0 | (none — direct commit) | T0 | dev (bootstrap) | 1–2 days | DONE |
| PR-1 | feature/112270-azure-devops-connector-v1-pr1 | T1 | dev | 3–4 days | DONE |
| PR-2 | feature/112271-metrics-store-thin-api-v1-pr2 | T2 | feature/112270-azure-devops-connector-v1-pr1 | 3–4 days | DONE |
| PR-3 | (relocated) | T3 | — | — | see v2-team-velocity-playbook.md |
| PR-4 | (deleted) | — | — | deleted 2026-07-23 | |
| PR-5 | (relocated) | T5 | — | — | see v2-team-velocity-playbook.md |
ADO task IDs: T0=112269, T1=112270, T2=112271, T3=112272, T4=112273 (work item deleted),
T5=112274 (see work-items/).
3. Files Touched
| File / path | PR |
|---|---|
public/index.html, public/dashboard.js, public/dashboard.css (new) | PR-0 (T0) |
graphify-out/ (new — knowledge graph generated by the graphify skill) | PR-0 (T0) |
Developer Productivity Dashboard.dc.html, support.js | Unchanged — stay as the stakeholder-review canvas; not deleted |
mockData.js | PR-0 (T0, consumed as-is), PR-2 (T2, superseded as the live data source — kept only as an offline fixture for local dev) |
connectors/ado_connector.py (new) | PR-1 (T1) |
store/schema.sql, store/db.py (new) | PR-2 (T2) |
api/server.py (new — thin read API, Section 5.3) | PR-2 (T2) |
T3/T5 file lists (connectors, assistant/, chat widget) now live in v2-team-velocity-playbook.md.
T4’s planned files (hooks/commit-trailer/) were never built — task deleted.
4. Hard Rules
- Metric definitions come only from Section 3 of the design doc (
scratch/extracted_text.txtlines 38–64) — commit count, PR throughput, AI-assisted %, churn, velocity, cycle time, tool adoption. Connectors normalize to these definitions; never invent a new metric or redefine an existing one to fit a data source’s native shape (Section 9 risk: “Metric definitions drift across tools”). - No connector, store, or API layer makes an LLM call. Section 5.1 is explicit: “No LLM calls happen in this layer — it is pure, deterministic ETL.” The only phase allowed to call an LLM is PR-5’s AI Assistant, and only on-demand, per user question.
- “AI-assisted %” must ship as a blended, labeled metric (tool-reported layer + commit-attribution layer, Section 4) — never present it as a single precise number implying per-commit certainty the data doesn’t support.
Do not build the AI-attribution commit-trailer convention (PR-4) as an org-wide rollout.Moot — PR-4/T4 deleted 2026-07-23 (commit-trailer attribution judged not the best solution). Kept here as historical context only; no replacement attribution approach is scoped yet.- Each connector is isolated and independently versioned (Section 9: “Keep each connector isolated and versioned so one vendor’s API change doesn’t break the whole pipeline”) — a Copilot API schema change must not require touching
ado_connector.py,copilot_studio_connector.py, orclaude_code_connector.py, and vice versa. - Store aggregated results, not raw API payloads (Section 6.4). Raw connector responses may be cached transiently for debugging but are not the persisted store schema.
- If PR-5’s AI Assistant is built, keep the system prompt schema-grounded and minimal (Section 6.2’s spirit) — tool definitions + a short instruction to call a tool and summarize, nothing more. Detailed schema/edge-case docs go in a separate reference file the assistant only pulls in when a question needs it, not inlined into the system prompt.
- UI framing must keep individual metrics contextualized against team/sprint averages (Section 2, Section 7.2, Section 9) — never ship a raw per-person leaderboard sort with no team baseline shown alongside.
Co-authored-by: Claudetrailer forbidden on commits. Use thecommit-msgskill.- All repos hosted on Azure DevOps (ADO), not GitHub — connectors (PR-1 onward) target the ADO Git REST API. See PR 1’s “Data Source” subsection for exact endpoints/auth.
- Branch names follow
feature/<ado-task-id>-<slug>-v1-pr<n>(§2 table) — PR-0 is the sole exception, committed directly todevwith no feature branch. - No automatic git actions. Never stage, commit, or push without explicit user approval — once implementation is complete and all tests/checks pass, stop and confirm with the user first. On approval: stage all files, commit (via
commit-msgskill), push. No PR is opened as part of this workflow.
5. Out of Scope
- Real-time/live-polling refresh — Section 5.2 is explicit that aggregation happens once, on ingest, not on every dashboard view. Scheduled (hourly cron / Azure Pipelines schedule) refresh only.
- A fully custom analytics UI framework — Section 7 doc already specifies the exact layout (top bar, KPI row, main row, team table, secondary row); PR-0 is a port of that spec, not a redesign.
- Cursor integration of any kind (usage connector, commit-trailer value, export ingestion) — initial AI-tools scope is GitHub Copilot, Copilot Studio, and Claude Code only (see Executive Summary). Also no stable public Cursor API exists today (Section 4, Section 9) even if it were in scope. Revisit as a P2 addition.
- Running the whole dashboard through the AI Assistant — Section 5.4 explicitly rules this out (“a conversational layer on top of the dashboard, not the dashboard’s engine”); the assistant in PR-5 is additive, not a replacement rendering path.
- GraphRAG or a vector-embedding index for PR-5’s MVP — the metrics store is small, structured, and already has an aggregation API (Section 5.3); a schema-grounded tool-calling assistant answers correctly without a new retrieval index. Revisit only under the P2 conditions in PR-5’s “RAG Strategy” subsection.
- Individual performance-review scoring, alerts, or ranking features — Section 2’s explicit non-goal (“not as an individual performance-review score”).
6. Per-Session Contract
Every session:
- Branch from prior PR’s branch (per §2 table) — except PR-0, which works directly on
dev. - Scoped changes only — no opportunistic cleanup of
Developer Productivity Dashboard.dc.html(it stays as the stakeholder-review artifact, untouched by these PRs). - Add a runnable check for any new non-trivial logic (connector normalization, aggregation, API route) — a small
pytesttest file for Python, or anassert-based self-check script; no test framework scaffolding beyond what the PR’s own code needs. - All checks green before commit (
pytestfor Python pieces once introduced in PR-1; plainnode --check/ manual load via a local static server for PR-0’s JS). - Once all checks are green, stop and confirm with the user before any git action — do not stage, commit, or push without explicit approval (see Hard Rule 12).
- On approval:
git add -A,commit-msgskill for the message (no Claude co-author trailer),git push -u origin <branch>(PR-0 pushes directly todev:git push origin dev). - No PR is opened — push is the last step. This contract applied to T0–T2 only; T3/T5 now
follow
v2-team-velocity-playbook.md’s contract, T4 is deleted.
PR 0 — Extract a shippable dashboard shell from the design canvas + graphify integration (T0)
Merge model: direct commit to dev — no feature branch, no PR review (bootstrap step)
ADO task: 112269
Model: Sonnet 5
Effort: medium
Problem
Developer Productivity Dashboard.dc.html is a design-review tool artifact, not
production code: it depends on support.js pulling React/ReactDOM/Babel from unpkg.com at
runtime, and uses a proprietary <x-dc>/{{ }}/sc-if template-binding syntax meant for a
design canvas editor. Section 5.3 calls for “a static/served web page (React or plain
HTML/JS)”; per Ponytail’s ladder (rung 4/6: native platform features over dependencies,
shortest working code), a plain dependency-free static page is the right size for a dashboard
whose only interactivity is filter dropdowns, sort-on-click columns, and chart rendering
already fully specified by the mockup’s markup — no React/build toolchain needed.
Because this is the first work to land on dev, it is committed directly to dev rather
than through a feature branch + PR — there is no prior dev state to protect with a review gate
yet. PR-1 onward branch from this baseline and go through the normal PR flow.
Required change
- Create
public/index.html+public/dashboard.js+public/dashboard.css: the canvas’s “Editorial Soft” markup, colors, and layout (top bar, KPI row, velocity + composition charts, team table, secondary row — Section 7.1), translated from the canvas’s{{ dash.field }}bindings into plain DOM updates driven by a small state object (project filter, tool filter, date-range key, sort key/dir) — same shape as the existingbuildDash()logic in the.dc.htmlscript block. - Keep consuming
mockData.js’sgenerateDataset()/aggregate()unchanged — this PR is shell-only; PR-2 is what swaps the data source to the real API. Import it as a plain ES module the same way the canvas script does (import('./mockData.js')). - Leave
Developer Productivity Dashboard.dc.htmlandsupport.jsin place, untouched — they remain the stakeholder-review artifact, independent of the production shell. - Update
USAGE.mdwith how to run the newpublic/shell alongside the existing canvas instructions (both need a static HTTP server per the existing CORS note). - Run the
graphifyClaude Code skill/plugin against the repo once the shell lands, to generategraphify-out/— a persistent knowledge graph of the codebase (files, components, data-shape relationships betweenmockData.js, the canvas, and the newpublic/shell). Commitgraphify-out/alongside the shell so PR-1 onward (and any future session) can query codebase relationships via graphify instead of re-deriving them from scratch each session.
Prompt — paste verbatim into Claude Code
You are implementing PR-0 of the Dev Productivity Dashboard build-out playbook(docs/playbooks/v1-dev-productivity-dashboard-playbook.md).
Read the full PR-0 section before writing any code.
This is a direct commit to dev — no feature branch, no PR review. Workdirectly on the dev branch (git checkout dev — cut it from main first ifit doesn't exist yet, per Section 0).
Scope — T0 ONLY. Create ONLY public/index.html, public/dashboard.js,public/dashboard.css, and (STEP 4 below) graphify-out/. Do not modify"Developer Productivity Dashboard.dc.html" or support.js — they stay as-is,the stakeholder-review canvas. You may update USAGE.md to document the newshell.
═══════════════════════════════════════STEP 1 — Read the canvas═══════════════════════════════════════
1. READ "Developer Productivity Dashboard.dc.html" in full, in particular the "<script type=\"text/x-dc\" data-dc-script>" Component class at the bottom of the file (buildDash(), toolColor(), renderVals()) — this is the source of truth for what data each visual element binds to.
═══════════════════════════════════════STEP 2 — Extract the shell═══════════════════════════════════════
2. WRITE public/index.html: the canvas's HTML structure and inline styles, with the {{ }} template bindings and sc-if/sc-for canvas directives replaced by plain elements with IDs/classes dashboard.js can target. Keep the AlphaBOLD visual language (warm off-white canvas, near-black text, gold #E3AD21/#CB9328 accent, Manrope font) exactly as in the source markup — this is a port, not a redesign.
3. WRITE public/dashboard.js: a plain ES module (no React, no JSX, no build step) that: - imports generateDataset and aggregate from ./mockData.js - holds filter/sort state (project, tool, date range, sort key/dir) — same fields as the canvas's state (projectFilter, toolFilter, etc.) - re-renders the KPI row, velocity chart, composition chart, team table, and repo/tool-adoption charts from aggregate()'s output whenever state changes - wires the project selector, date-range picker, tool filter pills, and sortable column headers to update state and re-render
4. WRITE public/dashboard.css: extracted inline styles from the canvas's markup, deduplicated into classes.
═══════════════════════════════════════STEP 3 — Verify═══════════════════════════════════════
5. Serve public/ with `python3 -m http.server` from that directory (or equivalent) and load it in a browser. Confirm: KPI row populates, velocity/composition charts render, team table sorts on column click, project/tool/date filters update all widgets together (Section 7.2 — shared filters, not per-widget).
6. Add a minimal assert-based self-check (e.g. public/dashboard.test.js run via `node public/dashboard.test.js` or similar, no framework) that imports aggregate() from mockData.js with a fixed filter set and asserts the shape dashboard.js depends on (teamRows, kpis, repoBars, etc.) is present — this guards the PR-0/PR-2 data-shape contract described in the playbook.
7. Update USAGE.md: add a "Production shell (public/)" section alongside the existing canvas-viewing instructions, noting it also requires an HTTP server (same CORS reason as the canvas file) for mockData.js's dynamic import.
═══════════════════════════════════════STEP 4 — Graphify integration═══════════════════════════════════════
8. Invoke the `graphify` skill/plugin against the full repo (canvas + mockData.js + the new public/ shell) to build a persistent knowledge graph of the codebase. Commit its output directory (`graphify-out/`) so later PR sessions in this playbook can query file/component relationships via graphify rather than re-deriving them from scratch.
Once implementation is complete and all tests pass, STOP. Do not stage,commit, or push anything — confirm with the user first.
On user approval only: 1. git add -A (stage all files). 2. Commit via the commit-msg skill. Suggested title: "feat: dpd PR-0 — extract shippable dashboard shell from design canvas + graphify integration (T0)" Resolves: #112269 3. git push origin dev (direct commit — no PR to open, no feature branch).
No Co-authored-by: Claude trailer.PR 1 — Azure DevOps connector (T1)
Branch: feature/112270-azure-devops-connector-v1-pr1
Branches from: dev
Model: Sonnet 5
Effort: medium
Problem
No code pulls real commit/PR/cycle-time data. Section 6.3 (“Start with Git data only … to prove the dashboard shell and UI end-to-end”) and Section 5.1 (“Small scripts … run on a schedule … call the Git host’s … Admin APIs and drop normalized JSON/rows into a lightweight database … No LLM calls happen in this layer”) define this PR’s scope precisely: a deterministic, scheduled script, Git-host only, no AI-attribution guessing (that’s PR-3/PR-4). All repos are hosted on Azure DevOps (ADO) — this connector targets ADO’s Git REST API, not GitHub.
Data Source — Azure DevOps (ADO)
Verified via Microsoft Learn.
Git API (commits, PRs, repos)
Auth
| Purpose | Endpoint |
|---|---|
| Authentication guidance (PAT vs Entra ID vs service principal) | https://learn.microsoft.com/azure/devops/integrate/get-started/authentication/authentication-guidance |
| Create/use PAT | https://learn.microsoft.com/azure/devops/organizations/accounts/use-personal-access-tokens-to-authenticate?view=azure-devops |
| REST API request pattern + auth header | https://learn.microsoft.com/rest/api/azure/devops/?view=azure-devops-rest-7.2 |
Token (PAT or Entra ID) read from an environment variable, never hardcoded.
Required change
connectors/ado_connector.py: calls the Azure DevOps Git REST API (Commits — Get Commits; Pull Requests — Get Pull Requests; Repositories — List, per the table above) for commits (to default/release branches), PRs (opened/reviewed/merged with cycle time), scoped to the org/project/repos the design doc’s mockup models (Atlas Platform,Beacon Analytics,Nimbus CRM,Foundry API,Lighthouse Mobileand their repos, permockData.js’sPROJECTS/REPOS— real org/project/repo config replaces this fixture list before Phase 1 ships, but keep the same shape: project → repos → contributors).- Normalize to Section 3’s exact definitions: commit count (merged-to-default/release only), PR throughput with cycle time (open→merge), churn (lines added+removed, supporting signal only — never surfaced as a target metric).
- No database yet (PR-2 adds the store) — this PR writes normalized rows to local JSON files
under a
connectors/output/scratch path so PR-2 has a concrete shape to ingest, and so this PR is independently testable without the store existing. - Runs via a script entrypoint suitable for cron or an Azure Pipelines schedule (Section 5.1) — no long-running process, no polling loop.
- Auth via a PAT (or Entra ID token) read from an environment variable (e.g.
ADO_PAT), never hardcoded, sent as the standard ADO REST auth header (Basic, empty username + PAT as password, or a bearer Entra ID token) per the auth endpoints above.
Prompt — paste verbatim into Claude Code
You are implementing PR-1 of the Dev Productivity Dashboard build-out playbook(docs/playbooks/v1-dev-productivity-dashboard-playbook.md).
Read the full PR-1 section (including its "Data Source — Azure DevOps (ADO)"subsection), and Section 3 (Metrics Framework) and Section 5.1 ofscratch/extracted_text.txt, before writing any code.
Branch: feature/112270-azure-devops-connector-v1-pr1 from dev.
Scope — T1 ONLY. Create ONLY connectors/ado_connector.py and its test file(tests/test_ado_connector.py). Do not touch public/ or mockData.js.
═══════════════════════════════════════STEP 1 — Read the metric definitions═══════════════════════════════════════
1. READ scratch/extracted_text.txt lines 38-64 (Section 3, Metrics Framework table) and lines 65-85 (Section 4, Data Source Feasibility — the Git-host row). These are the exact definitions to normalize to; do not invent your own commit/PR/cycle-time semantics. The design doc's Git host is Azure DevOps (ADO) for this org — use the ADO Git REST API endpoints listed in PR-1's "Data Source" subsection above, not GitHub's.
═══════════════════════════════════════STEP 2 — Build the connector═══════════════════════════════════════
2. WRITE connectors/ado_connector.py: - Accepts a list of {organization, project, repo_id, repo_name} configs (start with a small hardcoded list matching mockData.js's PROJECTS/ REPOS shape — real org/project/repo config source is a follow-up, not this PR's scope) - For each repo, calls the Azure DevOps Git REST API for: * Commits — Get Commits, merged to the default/release branch in a given date range, grouped by contributor and day * Pull Requests — Get Pull Requests, opened/reviewed/merged in that range, with cycle time (opened_at → merged_at) * lines added/removed per commit (churn — supporting signal only) - Normalizes results into plain dicts matching Section 3's granularity columns (repo, contributor, day/week/sprint as applicable) - Is idempotent and safe to re-run (upsert semantics conceptually, even though this PR writes to flat JSON not a DB yet) - Writes output to connectors/output/ado_<date>.json (gitignore this path — add connectors/output/ to .gitignore) - No LLM calls anywhere in this file. - ADO auth token (PAT or Entra ID) read from an environment variable (e.g. ADO_PAT), never hardcoded — sent per the auth header pattern in the REST API request docs linked in PR-1's "Data Source" subsection.
3. Add a script entrypoint (`if __name__ == "__main__":`) that can be invoked directly for cron/Azure Pipelines scheduling, accepting a --since/--until date range via argparse.
═══════════════════════════════════════STEP 3 — Tests═══════════════════════════════════════
4. WRITE tests/test_ado_connector.py: unit tests for the normalization logic using mocked/fixture API responses (do not hit the real Azure DevOps API in tests). Cover: commit grouping by contributor/day, PR cycle-time calculation, churn is captured but not used as a target metric anywhere in the output shape.
═══════════════════════════════════════Verification═══════════════════════════════════════
5. RUN pytest tests/ -v --tb=short. No failures.
Once implementation is complete and all tests pass, STOP. Do not stage,commit, or push anything — confirm with the user first.
On user approval only: 1. git add -A (stage all files). 2. Commit via the commit-msg skill. Suggested title: "feat: dpd PR-1 — Azure DevOps connector for commits, PRs, and cycle time (T1)" Resolves: #112270 3. git push -u origin feature/112270-azure-devops-connector-v1-pr1. No PR to open.
No Co-authored-by: Claude trailer.PR 2 — Metrics store + thin read API, dashboard goes live (T2)
Branch: feature/112271-metrics-store-thin-api-v1-pr2
Branches from: feature/112270-azure-devops-connector-v1-pr1
Model: Sonnet 5
Effort: medium-high
Problem
Nothing persists or pre-aggregates yet, and the dashboard shell built in PR-0 still reads
mockData.js’s fabricated dataset in-browser. Section 5.2 (“pre-aggregated tables …
Aggregation happens once, on ingest”) and Section 5.3 (“queries the metrics store directly
through a thin API … costs nothing in AI tokens to view”) define the target: a database plus
a small API, with aggregation done at ingest time, not on every page load.
Required change
store/schema.sql: SQLite schema (Section 5.2: “Postgres, or even SQLite for a first pilot”) with pre-aggregated tables — daily commits per person, weekly velocity per team, AI-assisted % per repo (this last one stays 0/null until PR-4; do not fabricate it).store/db.py: ingest function that reads PR-1’s connector JSON output and writes/aggregates into the schema.api/server.py: a thin read API (pick the lightest option that satisfies “thin” — a single small HTTP server, no framework beyond what’s needed for a handful of GET routes) exposing the same filter shape the dashboard already uses (project, tool, date range) and returning data shaped likemockData.js’saggregate()output, sopublic/dashboard.jsonly needs its fetch layer swapped, not its rendering logic.- Update
public/dashboard.jsto call the API instead of importingmockData.jsdirectly. KeepmockData.jsin the repo as an offline/local-dev fixture (some way to run the shell without the store — e.g. an env flag or query param) rather than deleting it.
Prompt — paste verbatim into Claude Code
You are implementing PR-2 of the Dev Productivity Dashboard build-out playbook(docs/playbooks/v1-dev-productivity-dashboard-playbook.md).
Read the full PR-2 section, and Section 5.2/5.3 of scratch/extracted_text.txt,before writing any code. Read public/dashboard.js (from PR-0) in full first —this PR must preserve its rendering logic, only swapping the data source.
Branch: feature/112271-metrics-store-thin-api-v1-pr2 from feature/112270-azure-devops-connector-v1-pr1.
Scope — T2 ONLY. Create store/schema.sql, store/db.py, api/server.py, andtheir tests. Modify ONLY the data-fetching layer of public/dashboard.js(not its rendering functions). Do not touch mockData.js's exports — itstays as the offline fixture.
═══════════════════════════════════════STEP 1 — Schema═══════════════════════════════════════
1. WRITE store/schema.sql: SQLite tables for daily commits per person/repo, weekly velocity per team/project, PR throughput with cycle time, and an ai_assisted_pct table (repo, tool, period columns — populate as 0/null for now, PR-4 fills it in). Match Section 3's granularity columns exactly (repo, contributor, project, day/week/sprint).
═══════════════════════════════════════STEP 2 — Ingest═══════════════════════════════════════
2. WRITE store/db.py: a function that reads connectors/output/ado_*.json (PR-1's output shape) and upserts into the schema — aggregation happens here, at ingest time, not in the API layer (Section 5.2).
═══════════════════════════════════════STEP 3 — Read API═══════════════════════════════════════
3. WRITE api/server.py: GET routes that accept project/tool/date-range filters and return JSON shaped like mockData.js's aggregate() return value (teamRows, kpis, repoBars, velocityPoints, columns) — read mockData.js's aggregate() function first to match its exact output shape field-for-field, so public/dashboard.js's render functions don't need to change.
═══════════════════════════════════════STEP 4 — Wire the dashboard to the live API═══════════════════════════════════════
4. In public/dashboard.js, replace the `import('./mockData.js')` + in-browser aggregate() call with a fetch() to api/server.py's routes, passing the same filter state. Keep a fallback/dev-mode path that still uses mockData.js directly (e.g. gated by a `?mock=1` query param or missing API reachability) so the shell remains runnable standalone per USAGE.md's existing instructions.
═══════════════════════════════════════STEP 5 — Tests═══════════════════════════════════════
5. WRITE tests for store/db.py (ingest correctness against a fixture connector JSON file) and api/server.py (route responses match the expected aggregate() shape for a few filter combinations).
═══════════════════════════════════════Verification═══════════════════════════════════════
6. RUN pytest tests/ -v --tb=short. No failures.7. Manually: run api/server.py, serve public/ over HTTP, load the dashboard, confirm it renders from the live API (not mockData.js) with data ingested from a sample connector JSON file.
Once implementation is complete and all tests pass, STOP. Do not stage,commit, or push anything — confirm with the user first.
On user approval only: 1. git add -A (stage all files). 2. Commit via the commit-msg skill. Suggested title: "feat: dpd PR-2 — metrics store, thin read API, dashboard wired to live data (T2)" Resolves: #112271 3. git push -u origin feature/112271-metrics-store-thin-api-v1-pr2. No PR to open.
No Co-authored-by: Claude trailer.PR 3 — Copilot, Copilot Studio, and Claude Code usage connectors (T3)
RELOCATED. Full spec, R&D, and prompt moved to
docs/playbooks/v2-team-velocity-playbook.md (owner: Fatima) — on hold, blocked on IT
provisioning the Copilot Metrics API / Copilot Studio Dataverse / Claude Code Admin API secret
keys. See that file for current status and the verbatim prompt.
PR 4 — Commit-trailer attribution pilot (T4)
DELETED (2026-07-23). Commit-trailer attribution (Assisted-By: copilot/claude-code) was
judged not the best approach for AI-attribution and will not be built. work-items/112273-commit-trailer-attribution.md
was removed. No replacement is scoped yet — AI-assisted % stays tool-reported-layer-only
(from T3) until a new attribution approach is decided.
PR 5 — AI Assistant/chatbot for ad-hoc querying (T5)
RELOCATED. Full spec, RAG strategy, and prompt moved to
docs/playbooks/v2-team-velocity-playbook.md (owner: Fatima). See that file for current status
and the verbatim prompt.
7. Verification Samples
After each phase merges, verify:
| Checkpoint | Verify |
|---|---|
| Phase 1 (PR-0 direct-to-dev + PR-1/PR-2 merged) | Dashboard loads over HTTP, renders from the real API (not mockData.js), filters/sort work end-to-end, ?mock=1 fallback still works offline |
| Any phase | Empty/not-yet-connected sources show a “Connect Copilot Metrics API” / “Connect Copilot Studio” / “Connect Claude Code Admin API” state, per Section 7.2 — never a blank chart |
PR-3/PR-4/PR-5 verification samples moved to v2-team-velocity-playbook.md (T4’s is removed —
deleted task).
8. Rollback
- PR-0 (T0, shell extraction + graphify): Since this is a direct commit to
dev(no feature branch), roll back with agit revertof the PR-0 commit(s) directly ondev. Reverting removespublic/andgraphify-out/; the.dc.htmlcanvas remains the only artifact, no production shell exists. No data-layer impact since PR-0 has no backend. - PR-1 (T1, Azure DevOps connector): Revert
connectors/ado_connector.py; PR-2’s store simply has no data to ingest yet (PR-2 can still merge independently if desired, just with an empty store). - PR-2 (T2, store + API): Revert
store/,api/, and thepublic/dashboard.jsfetch-layer change; the shell falls back tomockData.jsvia its existing dev-mode path. - PR-3/PR-5 (T3/T5): Rollback plans moved to
v2-team-velocity-playbook.md. - PR-4 (T4): N/A — task deleted before implementation; nothing to roll back.