Skip to main content

max / makenotwork

1.5 KB · 44 lines History Blame Raw
1 # painhours
2
3 The painhours urgency model for Rust: a 0-100 heat score computed from how much
4 something hurts, how broadly it hits, and how long it has been sitting there.
5
6 Nothing stores a priority. Rank by the score; use the band only for color.
7
8 ## The model
9
10 ```text
11 raw = pain^1.5 * scale^2.0 * age_weeks^1.5
12 painhours = round(100 * (1 - e^(-raw/266)))
13 ```
14
15 `pain` and `scale` are 1-5 guesstimates. Each exponent tunes one factor
16 independently: `scale` drives the ranking, `pain` gives severity a secondary
17 pull, and the exponent on age is the anti-starvation lever that decides how fast
18 a narrow problem climbs rather than languishing forever.
19
20 Band cutoffs on the score: Critical at 75, High at 50, Medium at 20, Low below.
21
22 ## Use
23
24 ```rust
25 use chrono::Utc;
26 use painhours::{Priority, age_weeks, painhours};
27
28 // Age is measured to an anchor you choose. Pass `Utc::now()` while the item is
29 // live; pass the resolution instant once it is terminal, so closed items stop
30 // climbing the list.
31 let weeks = age_weeks(created_at, Utc::now());
32 let score = painhours(pain, scale, weeks);
33 let band = Priority::from_painhours(score);
34 ```
35
36 The crate is the scoring model and nothing else. It has no opinion about what
37 your record type is, what statuses it has, or where you store it.
38
39 ## Consumers
40
41 `MNW/wam` (tickets) and GoingsOn (problems), so one ranked list can span both.
42 Changing a constant here reranks both, which is the point: duplicating the tuning
43 would let the rankings drift.
44