# wam (Whack-a-Mole) A ticket store for ongoing, time-sensitive problems, driven from the terminal. One binary exposes two surfaces over a single SQLite database: a CLI and an HTTP API for programmatic ingest. The HTTP API is the point of the tool — automated sources (the MNW server, PoM, backup jobs) file problems into it. wam tracks *problems*; GoingsOn tracks *solutions* (todos). They stay separate: the plan is a lightweight bridge that promotes a wam ticket into a GoingsOn task to solve it, rather than merging the two. See the GoingsOn `wam` and `teams` tasks for the direction. ## Urgency without a priority field Tickets do not store a priority. Each ticket carries two 1-to-5 guesstimates, `pain` (how much it hurts a hit user) and `scale` (how broadly it hits), and wam computes a 0-to-100 painhours heat score from those two plus the ticket's age: ```text raw = pain^PAIN_EXP * scale^SCALE_EXP * age_weeks^AGE_EXP painhours = round(100 * (1 - e^(-raw / K))) ``` Scale drives the ranking, pain gives severity a secondary pull, and age is the anti-starvation lever so a narrow bug still climbs over time. The Low/Medium/High/ Critical band is derived from the score, not stored. The tuning constants and their calibration live in `src/types.rs`. ## Build and run ``` cargo run -p wam # list open tickets (default) cargo run -p wam -- create -t "title" # create a ticket from the CLI cargo run -p wam -- list # list tickets cargo run -p wam -- serve --token XXX # run the HTTP ingest API (bearer-auth) ``` Run without a subcommand for the open-ticket list. Run with a subcommand for one-shot CLI use. ## Auth The HTTP API runs on the tailnet and fails closed: it never serves without a shared bearer token, so `Authorization: Bearer ` is required on every request and peer sync presents the same token. The token is resolved in order from `--token`, the `WAM_TOKEN` env var, a token persisted beside the database (`/token`), or, failing all of those, a freshly generated one that is saved with `0600` permissions and printed once at startup. When a token is auto-generated, copy it into `WAM_TOKEN` on every producer (MNW server, PoM, the offsite-sync scripts) and peer. ## Layout - `src/cli.rs` the clap subcommands and export formats. - `src/api.rs` the axum HTTP endpoints + bearer auth. - `src/db.rs` SQLite storage (bundled rusqlite, WAL mode). Each instance has a node id, the seam for future multi-user use. - `src/types.rs` the ticket model and the painhours scoring. ## Storage A single SQLite database in the platform data directory. WAL mode is on, so concurrent readers work today; multi-writer conflict resolution is a future item. ## License See the workspace `LICENSE`.