Skip to main content

max / makenotwork

2.7 KB · 68 lines History Blame Raw
1 # wam (Whack-a-Mole)
2
3 A ticket store for ongoing, time-sensitive problems, driven from the terminal.
4 One binary exposes two surfaces over a single SQLite database: a CLI and an HTTP
5 API for programmatic ingest. The HTTP API is the point of the tool — automated
6 sources (the MNW server, PoM, backup jobs) file problems into it.
7
8 wam tracks *problems*; GoingsOn tracks *solutions* (todos). They stay separate:
9 the plan is a lightweight bridge that promotes a wam ticket into a GoingsOn task
10 to solve it, rather than merging the two. See the GoingsOn `wam` and `teams`
11 tasks for the direction.
12
13 ## Urgency without a priority field
14
15 Tickets do not store a priority. Each ticket carries two 1-to-5 guesstimates,
16 `pain` (how much it hurts a hit user) and `scale` (how broadly it hits), and wam
17 computes a 0-to-100 painhours heat score from those two plus the ticket's age:
18
19 ```text
20 raw = pain^PAIN_EXP * scale^SCALE_EXP * age_weeks^AGE_EXP
21 painhours = round(100 * (1 - e^(-raw / K)))
22 ```
23
24 Scale drives the ranking, pain gives severity a secondary pull, and age is the
25 anti-starvation lever so a narrow bug still climbs over time. The Low/Medium/High/
26 Critical band is derived from the score, not stored. The tuning constants and
27 their calibration live in `src/types.rs`.
28
29 ## Build and run
30
31 ```
32 cargo run -p wam # list open tickets (default)
33 cargo run -p wam -- create -t "title" # create a ticket from the CLI
34 cargo run -p wam -- list # list tickets
35 cargo run -p wam -- serve --token XXX # run the HTTP ingest API (bearer-auth)
36 ```
37
38 Run without a subcommand for the open-ticket list. Run with a subcommand for
39 one-shot CLI use.
40
41 ## Auth
42
43 The HTTP API runs on the tailnet and fails closed: it never serves without a
44 shared bearer token, so `Authorization: Bearer <token>` is required on every
45 request and peer sync presents the same token. The token is resolved in order
46 from `--token`, the `WAM_TOKEN` env var, a token persisted beside the database
47 (`<data-dir>/token`), or, failing all of those, a freshly generated one that is
48 saved with `0600` permissions and printed once at startup. When a token is
49 auto-generated, copy it into `WAM_TOKEN` on every producer (MNW server, PoM, the
50 offsite-sync scripts) and peer.
51
52 ## Layout
53
54 - `src/cli.rs` the clap subcommands and export formats.
55 - `src/api.rs` the axum HTTP endpoints + bearer auth.
56 - `src/db.rs` SQLite storage (bundled rusqlite, WAL mode). Each instance has a
57 node id, the seam for future multi-user use.
58 - `src/types.rs` the ticket model and the painhours scoring.
59
60 ## Storage
61
62 A single SQLite database in the platform data directory. WAL mode is on, so
63 concurrent readers work today; multi-writer conflict resolution is a future item.
64
65 ## License
66
67 See the workspace `LICENSE`.
68