Saved queries
The six questions this database is built to answer. Each runs unchanged on SQLite and Postgres.
1. Acceptance criteria with no linked commits or no linked tests2. Commits not tied to any task3. Cycle time4. Requirements changed after the code for one of their criteria merged5. Review turnaround by reviewer6. Full trace for one requirement
3. Cycle time: from story start to the merge of the last PR carrying its work.
SQL
-- 3. Cycle time: from story start to the merge of the last PR carrying its work.
-- ((julianday(b) - julianday(a)) * 24.0) is expanded per dialect by queries/saved.py.
WITH story_merges AS (
SELECT t.story_id,
MAX(pr.merged_at) AS last_merge,
COUNT(DISTINCT pr.id) AS prs
FROM tasks t
JOIN commit_tasks ct ON ct.task_id = t.id
JOIN pull_request_commits prc ON prc.commit_id = ct.commit_id
JOIN pull_requests pr ON pr.id = prc.pull_request_id
WHERE pr.merged_at IS NOT NULL
GROUP BY t.story_id
)
SELECT f.key AS feature,
s.key AS story,
s.title,
s.status,
s.started_at,
sm.last_merge,
sm.prs,
ROUND(CAST(((julianday(sm.last_merge) - julianday(s.started_at)) * 24.0) AS NUMERIC), 1) AS cycle_hours,
ROUND(CAST(((julianday(sm.last_merge) - julianday(s.started_at)) * 24.0) / 24.0 AS NUMERIC), 1) AS cycle_days
FROM stories s
JOIN features f ON f.id = s.feature_id
JOIN story_merges sm ON sm.story_id = s.id
WHERE s.started_at IS NOT NULL
ORDER BY cycle_hours DESC;
17 rows
| feature | story | title | status | started_at | last_merge | prs | cycle_hours | cycle_days |
|---|---|---|---|---|---|---|---|---|
| FEAT-HTTPX-01 | ST-HTTPX-101 | Graceful migration of SSL settings | done | 2024-11-01T14:00:00Z | 2025-09-11T10:59:20Z | 5 | 7533.0 | 313.9 |
| FEAT-HTTPX-01 | ST-HTTPX-102 | Proxy support improvements | in_progress | 2024-10-20T14:00:00Z | 2025-06-02T19:29:52Z | 2 | 5405.5 | 225.2 |
| FEAT-CLICK-02 | ST-CLICK-202 | Help output is complete and reproducible | done | 2026-05-20T14:00:00Z | 2026-08-09T17:51:57Z | 3 | 1947.9 | 81.2 |
| FEAT-CLICK-02 | ST-CLICK-204 | Safer testing utilities | done | 2026-05-01T14:00:00Z | 2026-07-20T17:43:21Z | 2 | 1923.7 | 80.2 |
| FEAT-CLICK-01 | ST-CLICK-102 | Styled text renders correctly in prompts, wrapping and stripping | done | 2026-05-10T15:00:00Z | 2026-07-10T03:14:25Z | 4 | 1452.2 | 60.5 |
| FEAT-REQ-01 | ST-REQ-102 | Harden URL and header parsing | done | 2026-03-20T14:00:00Z | 2026-05-10T21:41:25Z | 4 | 1231.7 | 51.3 |
| FEAT-REQ-02 | ST-REQ-201 | Ship inline types with the package | done | 2026-04-25T14:00:00Z | 2026-06-08T17:33:26Z | 4 | 1059.6 | 44.1 |
| FEAT-REQ-01 | ST-REQ-101 | Accept file-like wrappers that proxy attributes | done | 2026-05-05T14:00:00Z | 2026-06-09T15:45:59Z | 3 | 841.8 | 35.1 |
| FEAT-CLICK-02 | ST-CLICK-201 | Warn about parameter names Click 9.0 will reject | in_review | 2026-09-01T14:00:00Z | 2026-10-04T22:19:53Z | 2 | 800.3 | 33.3 |
| FEAT-CLICK-02 | ST-CLICK-203 | Built-in PowerShell completion | done | 2026-06-15T14:00:00Z | 2026-07-16T23:56:43Z | 2 | 753.9 | 31.4 |
| FEAT-REQ-02 | ST-REQ-203 | Security hygiene | done | 2026-04-10T14:00:00Z | 2026-05-11T19:24:21Z | 2 | 749.4 | 31.2 |
| FEAT-CLICK-01 | ST-CLICK-103 | Editor and progress bar polish | done | 2026-08-01T14:00:00Z | 2026-08-20T02:50:19Z | 3 | 444.8 | 18.5 |
| FEAT-HTTPX-02 | ST-HTTPX-202 | Retire the _utils.py grab-bag module | done | 2024-10-28T14:00:00Z | 2024-11-15T11:42:52Z | 4 | 429.7 | 17.9 |
| FEAT-CLICK-01 | ST-CLICK-101 | Pager respects the user's PAGER and LESS settings | done | 2026-08-10T14:00:00Z | 2026-08-19T15:20:27Z | 4 | 217.3 | 9.1 |
| FEAT-REQ-02 | ST-REQ-202 | Header and response types match runtime behaviour | done | 2026-05-10T14:00:00Z | 2026-05-14T16:16:25Z | 4 | 98.3 | 4.1 |
| FEAT-HTTPX-02 | ST-HTTPX-203 | Decoder robustness | in_progress | 2024-11-18T14:00:00Z | 2024-11-22T11:42:51Z | 1 | 93.7 | 3.9 |
| FEAT-HTTPX-02 | ST-HTTPX-201 | WHATWG-aligned percent escaping | done | 2024-10-25T14:00:00Z | 2024-10-28T17:38:16Z | 3 | 75.6 | 3.2 |