Contracts: signals carry session cost, harness use, and stalled as no activity
workspace_signals gains what harness sessions cost (per week, and each pull request's share), each person's first use of each harness (for practices spreading through a team), and stalled now means no activity in three days rather than open over a week. Part of #157
- G1t-Session:
- ses_01m57128wre9bvvj1y4z4b8dk0
3 files+44−40/3 viewed
| 72 | 72 | // --- Adding up batches ------------------------------------------------------------ | |
| 73 | 73 | ||
| 74 | 74 | export function emptySignals(): WorkspaceSignals { | |
| 75 | − | return { weeks: [], days: [], waiting: [], pulls: [], pullsCapped: false, authors: [], items: [], milestones: [] }; | |
| 75 | + | return { weeks: [], days: [], waiting: [], pulls: [], pullsCapped: false, authors: [], harnesses: [], items: [], milestones: [] }; | |
| 76 | 76 | } | |
| 77 | 77 | ||
| 78 | 78 | /** The batches' answers as one: rows are per repository, so they add; items and milestones once each. */ | |
| ⋯ | |||
| 86 | 86 | all.waiting.push(...batch.waiting); | |
| 87 | 87 | all.pulls.push(...batch.pulls); | |
| 88 | 88 | all.authors.push(...batch.authors); | |
| 89 | + | all.harnesses.push(...(batch.harnesses ?? [])); | |
| 89 | 90 | all.pullsCapped ||= batch.pullsCapped; | |
| 90 | 91 | for (const item of batch.items) items.set(item.number, item); | |
| 91 | 92 | for (const milestone of batch.milestones) milestones.set(milestone.number, milestone); | |
| ⋯ | |||
| 110 | 111 | reviewed: 0, | |
| 111 | 112 | reviewSeconds: 0, | |
| 112 | 113 | stalled: 0, | |
| 114 | + | sessionCostUsd: 0, | |
| 113 | 115 | }); | |
| 114 | 116 | ||
| 115 | 117 | /** Every week in `starts`, quiet ones too, for the repositories in `only` (every one when not given). */ | |
| ⋯ | |||
| 126 | 128 | week.reviewed += row.reviewed; | |
| 127 | 129 | week.reviewSeconds += row.reviewSeconds; | |
| 128 | 130 | week.stalled += row.stalled; | |
| 131 | + | week.sessionCostUsd += row.sessionCostUsd ?? 0; | |
| 129 | 132 | } | |
| 130 | 133 | return starts.map((start) => byStart.get(start)!); | |
| 131 | 134 | } | |
| 48 | 48 | /// changes, as Insights counts them), and the seconds each waited. | |
| 49 | 49 | pub reviewed: u32, | |
| 50 | 50 | pub review_seconds: f64, | |
| 51 | − | /// Pull requests open when the week ended (now, for the current week) | |
| 52 | − | /// that had been open over seven days by then. | |
| 51 | + | /// Pull requests open when the week ended (now, for the current week), | |
| 52 | + | /// opened at least three days before, with no activity in the three | |
| 53 | + | /// days before it ended: no push, comment, review, timeline event, | |
| 54 | + | /// check or session entry. | |
| 53 | 55 | pub stalled: u32, | |
| 56 | + | /// What the harness sessions started in the week cost, as they | |
| 57 | + | /// reported it (estimated at list price from their token usage). | |
| 58 | + | pub session_cost_usd: f64, | |
| 54 | 59 | } | |
| 55 | 60 | ||
| 56 | 61 | /// One repository's UTC day. Days with nothing in them are left out. | |
| ⋯ | |||
| 104 | 109 | /// The work item it is for, and that item's milestone. | |
| 105 | 110 | pub item: Option<u32>, | |
| 106 | 111 | pub milestone: Option<u32>, | |
| 112 | + | /// Its share of what the harness sessions tied to it cost: each | |
| 113 | + | /// session's cost split evenly among the pull requests it is tied to. | |
| 114 | + | pub session_cost_usd: f64, | |
| 115 | + | } | |
| 116 | + | ||
| 117 | + | /// One person's use of one harness in one repository: when they first | |
| 118 | + | /// started a session with it there, and how many they have started. | |
| 119 | + | #[derive(Clone, Default, Deserialize, Serialize)] | |
| 120 | + | #[serde(default, rename_all(serialize = "camelCase"))] | |
| 121 | + | pub struct SignalHarness { | |
| 122 | + | pub repo_id: String, | |
| 123 | + | pub owner_id: String, | |
| 124 | + | pub owner_name: String, | |
| 125 | + | /// claude_code, codex, cursor, copilot or other. | |
| 126 | + | pub harness: String, | |
| 127 | + | pub first_at: String, | |
| 128 | + | pub sessions: u32, | |
| 107 | 129 | } | |
| 108 | 130 | ||
| 109 | 131 | /// One person's merged pull requests in one repository, over its whole history. | |
| ⋯ | |||
| 153 | 175 | pub pulls: Vec<SignalPull>, | |
| 154 | 176 | pub pulls_capped: bool, | |
| 155 | 177 | pub authors: Vec<SignalAuthor>, | |
| 178 | + | /// People's harnesses, root sessions only (a subagent is its parent's). | |
| 179 | + | pub harnesses: Vec<SignalHarness>, | |
| 156 | 180 | pub items: Vec<SignalItem>, | |
| 157 | 181 | pub milestones: Vec<SignalMilestone>, | |
| 158 | 182 | } | |
| 1859 | 1859 | /** The first UTC day `pulls` reaches back to: at most 400 days before `until`. */ | |
| 1860 | 1860 | since: string; | |
| 1861 | 1861 | }; | |
| 1862 | − | /** One repository's week from UTC day `start`; empty weeks are left out. `stalled`: open when the week ended (now, for this week), and open over seven days by then. */ | |
| 1862 | + | /** | |
| 1863 | + | * One repository's week from UTC day `start`; empty weeks are left out. | |
| 1864 | + | * `stalled`: open when the week ended (now, for this week), opened three | |
| 1865 | + | * days or more before, and no activity (push, comment, review, timeline | |
| 1866 | + | * event, check, session entry) in the three days before it ended. | |
| 1867 | + | * `sessionCostUsd`: what the harness sessions started in the week cost, | |
| 1868 | + | * estimated at list price from the token usage they reported. | |
| 1869 | + | */ | |
| 1863 | 1870 | export type SignalWeek = { | |
| 1864 | 1871 | repoId: string; | |
| 1865 | 1872 | start: string; | |
| ⋯ | |||
| 1872 | 1879 | reviewed: number; | |
| 1873 | 1880 | reviewSeconds: number; | |
| 1874 | 1881 | stalled: number; | |
| 1882 | + | sessionCostUsd: number; | |
| 1875 | 1883 | }; | |
| 1876 | 1884 | export type SignalDay = { repoId: string; day: string; opened: number; merged: number; agentMerged: number; reworked: number; reviews: number; sessions: number }; | |
| 1877 | 1885 | /** An open pull request no one has reviewed, oldest first; `blocks`: the open work items waiting on its work item. */ | |
| ⋯ | |||
| 1888 | 1896 | mergedAt: string | null; | |
| 1889 | 1897 | item: number | null; | |
| 1890 | 1898 | milestone: number | null; | |
| 1899 | + | /** Its share of its harness sessions' cost: each session's split evenly among the pull requests it is tied to. */ | |
| 1900 | + | sessionCostUsd: number; | |
| 1891 | 1901 | }; | |
| 1902 | + | /** One person's use of one harness in one repository, root sessions only. */ | |
| 1903 | + | export type SignalHarness = { repoId: string; ownerId: string; ownerName: string; harness: string; firstAt: string; sessions: number }; | |
| 1892 | 1904 | /** One person's merged pull requests in one repository over its history; `recent`: in the 90 days ending with `until`. */ | |
| 1893 | 1905 | export type SignalAuthor = { repoId: string; ownerId: string; ownerName: string; firstMergedAt: string; lastMergedAt: string; merged: number; recent: number }; | |
| 1894 | 1906 | export type SignalItem = { number: number; title: string; state: string; milestone: number | null }; | |
| ⋯ | |||
| 1900 | 1912 | pulls: SignalPull[]; | |
| 1901 | 1913 | pullsCapped: boolean; | |
| 1902 | 1914 | authors: SignalAuthor[]; | |
| 1915 | + | harnesses: SignalHarness[]; | |
| 1903 | 1916 | items: SignalItem[]; | |
| 1904 | 1917 | milestones: SignalMilestone[]; | |
| 1905 | 1918 | }; | |
Comments
Sign in to comment.