{"id":50792875,"url":"https://github.com/cryptojones/triage","last_synced_at":"2026-06-12T12:02:25.609Z","repository":{"id":358188807,"uuid":"1240392921","full_name":"CryptoJones/Triage","owner":"CryptoJones","description":"Meta-scheduler that watches signals and reorders its own priority queue.","archived":false,"fork":false,"pushed_at":"2026-05-16T07:15:46.000Z","size":121,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-16T07:29:17.863Z","etag":null,"topics":["apache-2","cli","nebraska","priority-queue","scheduler","stdlib-only","xkcd-2347"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/CryptoJones.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-16T04:49:06.000Z","updated_at":"2026-05-16T07:15:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/CryptoJones/Triage","commit_stats":null,"previous_names":["cryptojones/triage"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/CryptoJones/Triage","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CryptoJones%2FTriage","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CryptoJones%2FTriage/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CryptoJones%2FTriage/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CryptoJones%2FTriage/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/CryptoJones","download_url":"https://codeload.github.com/CryptoJones/Triage/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/CryptoJones%2FTriage/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34243053,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apache-2","cli","nebraska","priority-queue","scheduler","stdlib-only","xkcd-2347"],"created_at":"2026-06-12T12:01:46.528Z","updated_at":"2026-06-12T12:02:25.557Z","avatar_url":"https://github.com/CryptoJones.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n```\n╔══════════════════════════════════════════════════════════════╗\n║                                                              ║\n║                    T  R  I  A  G  E                          ║\n║                                                              ║\n║          meta-scheduler that watches its own queue           ║\n║                                                              ║\n╚══════════════════════════════════════════════════════════════╝\n```\n\n**A self-aware priority queue.** Signals push facts about the world;\nrules turn facts into priority deltas; the queue reorders itself on\nevery tick. You set the goals — Triage decides the order, and tells\nyou exactly why.\n\n[![License](https://img.shields.io/badge/License-Apache_2.0-blue.svg?logo=apache)](LICENSE)\n[![Stdlib only](https://img.shields.io/badge/deps-stdlib_only-success?logo=python\u0026logoColor=white)](pyproject.toml)\n[![Codeberg](https://img.shields.io/badge/Codeberg-CryptoJones%2FTriage-2185D0?logo=codeberg\u0026logoColor=white)](https://codeberg.org/CryptoJones/Triage)\n[![GitHub](https://img.shields.io/badge/GitHub-CryptoJones%2FTriage-181717?logo=github\u0026logoColor=white)](https://github.com/CryptoJones/Triage)\n\n**Read this in:** **English** ·\n[Español](README.es.md) ·\n[Français](README.fr.md) ·\n[Deutsch](README.de.md) ·\n[Italiano](README.it.md) ·\n[Português](README.pt.md) ·\n[Nederlands](README.nl.md) ·\n[Polski](README.pl.md) ·\n[Čeština](README.cs.md) ·\n[Svenska](README.sv.md) ·\n[Norsk](README.no.md) ·\n[Dansk](README.da.md) ·\n[Suomi](README.fi.md) ·\n[Română](README.ro.md) ·\n[Magyar](README.hu.md) ·\n[Türkçe](README.tr.md) ·\n[Català](README.ca.md)\n\n\u003c/div\u003e\n\n\u003e Mirrored on both [GitHub](https://github.com/CryptoJones/Triage) and\n\u003e [Codeberg](https://codeberg.org/CryptoJones/Triage). Issues filed on\n\u003e either forge are welcome; commits land on both.\n\n---\n\n## What you see\n\n```\n╔════════════════════════════════════════════════════════╗\n║                  T R I A G E   v0.11.1                 ║\n╚════════════════════════════════════════════════════════╝\n  ID               PRI  BAR    SUBJECT\n  ════════════  ══════  ═════  ════════════════════════════════════════\n  7cfa440bc639  [ 101]  █████  Fix the linter        ← blocker auto-bumped\n  f35d7cea6b7d  [ 100]  █████  Add feature X         ← blocked-by linter\n  19c80b807ddd  [  35]  █▒░░░  Rotate cert           ← deadline pressure\n  abc123456789  [   2]  ░░░░░  Routine cleanup\n```\n\nIn a real terminal the banner is bright magenta, the priorities are\ncolor-banded (high = yellow, mid = green, low = dim cyan), and the\npriority bars fill in proportionally. The default `bbs` theme is\nunapologetically 1990s.\n\n---\n\n## How it works\n\n```\n                   ┌─────────────────────┐\n   signals  ─────► │   Signal sources    │  (cron-window, github-ci, ...)\n                   └──────────┬──────────┘\n                              ▼\n                   ┌─────────────────────┐\n                   │  ~/.triage/state/   │  (append-only JSONL per source)\n                   └──────────┬──────────┘\n                              ▼\n   tick     ─────► ┌─────────────────────┐ ─────► reordered queue\n                   │  Triage scheduler   │        + per-task audit log\n                   └──────────┬──────────┘\n                              ▼\n                   ┌─────────────────────┐\n   tasks    ─────► │     triage CLI      │\n                   └─────────────────────┘\n```\n\n1. **Signal sources** push facts (`cron-window`, `github-ci`, future\n   `runpod-cost`, `github-pr`...).\n2. **Rules** turn facts into priority deltas\n   (`base_score`, `deadline_decay`, `cron_window_active`,\n   `ci_failing`, `blocker_transitive`).\n3. **The queue reorders** on every `triage tick`.\n4. **Every reorder is explainable** — `triage why \u003cid\u003e` shows\n   exactly which rules contributed which deltas, so the order is\n   never a black box.\n\nSee [`DESIGN.md`](DESIGN.md) for the full architecture, the rule\ncatalog, and the roadmap.\n\n---\n\n## Install\n\n```bash\ngit clone https://github.com/CryptoJones/Triage      # or codeberg.org/CryptoJones/Triage\ncd Triage\npip install -e .\n```\n\nPure Python stdlib. No runtime dependencies. Tested on 3.10 / 3.11 / 3.12.\n\n---\n\n## Usage\n\n### Tasks\n\n```bash\ntriage add \"Fix the auth bug\" --base-score 10\ntriage add \"Rotate the staging cert\" --deadline 2026-05-20T00:00:00Z\ntriage add \"Weekday-only chore\" --cron-window \"* 9-17 * * 1-5\"\ntriage add \"Watch CI\"          --tag \"gh-ci:CryptoJones/Triage@main\"\ntriage add \"Wait on linter\"    --blocked-by \u003clinter-task-id\u003e\n\ntriage list                     # current priority order\ntriage show \u003cid\u003e                # the raw task record (JSON)\ntriage why  \u003cid\u003e                # which rules contributed which deltas\ntriage rm   \u003cid\u003e                # remove\n```\n\n### Reorder + poll\n\n```bash\ntriage tick                     # recompute priorities; print new order\ntriage poll github-ci           # invoke a network-bound signal source\n```\n\n`tick` is cheap, local, and idempotent — call it from cron, a shell\nloop, or Claude Code's `ScheduleWakeup`. `poll` is for signal sources\nthat hit the network (you pay for those explicitly).\n\n### Language\n\nTriage speaks several languages. Set the language with the `--lang`\nflag or the usual environment variables:\n\n```bash\ntriage --lang es list           # one-shot\nTRIAGE_LANG=es triage list      # per-shell\ntriage lang                     # list available languages\ntriage lang --check             # release-gate: report any locale drift\n```\n\nSupported languages: English, Español, Français, Deutsch, Italiano,\nPortuguês, Nederlands, Polski, Čeština, Svenska, Norsk, Dansk, Suomi,\nRomână, Magyar, Türkçe, Català. Unknown languages fall back to English.\n\n### Event log (for external agents)\n\nEvery CLI invocation appends a single JSON line to a log file so an\nexternal agent can `tail -f` and parse Triage's behavior:\n\n```bash\ntail -f /var/log/triage.log | jq .   # if the file is owned by your user\n```\n\nSample entries:\n\n```json\n{\"ts\":\"2026-05-16T06:16:18+00:00\",\"event\":\"add\",\"task_id\":\"9e8040d267d9\",\"subject\":\"Investigate slow query\",\"base_score\":10,\"tags\":[],\"deadline\":null,\"blocked_by\":[]}\n{\"ts\":\"2026-05-16T06:16:18+00:00\",\"event\":\"tick\",\"ranked_count\":2,\"emitted_cron_signals\":0,\"top\":[{\"id\":\"ad2006db3c12\",\"priority\":35,\"subject\":\"Rotate cert\"},...],\"warnings\":[]}\n{\"ts\":\"2026-05-16T06:16:19+00:00\",\"event\":\"poll\",\"source\":\"github-ci\",\"emitted\":1,\"warnings\":[]}\n{\"ts\":\"2026-05-16T06:16:20+00:00\",\"event\":\"rm\",\"task_id\":\"9e8040d267d9\"}\n```\n\nConfiguration:\n\n| Mechanism                  | What it does                                                     |\n|----------------------------|------------------------------------------------------------------|\n| `--log-file PATH` flag     | Per-invocation log path.                                         |\n| `TRIAGE_LOG_FILE=PATH` env | Per-shell log path.                                              |\n| Default                    | `/var/log/triage.log`. Falls back to `~/.triage/triage.log` if `/var/log` isn't writable (warns once on stderr). |\n| `--no-log` flag            | Disable logging for this invocation.                             |\n| `TRIAGE_NO_LOG=1` env      | Disable logging globally for the shell.                          |\n\nTo use the standard `/var/log` path without sudo on every call:\n\n```bash\nsudo touch /var/log/triage.log\nsudo chown $(id -un):$(id -gn) /var/log/triage.log\n```\n\nLogging is a strict one-way side channel — errors during write are\nswallowed so the CLI's primary behavior is never disrupted.\n\n### Themes\n\n```bash\ntriage theme                    # list available themes\ntriage theme --name bbs         # render sample rows\ntriage --theme modern list      # one-shot theme override\nTRIAGE_THEME=mono triage list   # per-shell theme\n```\n\n| Theme    | Aesthetic                                                              |\n|----------|------------------------------------------------------------------------|\n| `bbs`    | **Default.** 1990s BBS: bright magenta, double-line box (`╔═╗`), block bars. |\n| `modern` | Subtle palette, single-line boxes (`┌─┐`), dot-fill bars (`█▒·`).    |\n| `mono`   | No color, ASCII-only (`+-+`, `#=.`) — safe for pipes / dumb terminals. |\n\nColor follows the standards:\n\n- Auto-disabled when stdout isn't a TTY.\n- `NO_COLOR=1` disables color (per [no-color.org](https://no-color.org/)).\n- `FORCE_COLOR=1` enables color on non-TTY.\n- `--no-color` flag = explicit per-invocation kill switch.\n\n### Diagnostics\n\n`triage doctor` is the one-screen environment summary — paste its\noutput into a bug report and the maintainer has everything they\nneed to reproduce your setup:\n\n```\n$ triage doctor\ntriage v0.11.0    (python 3.14.4)\n  locale:  en   source=LANG   available=17   drift=0\n  store:   /home/you/.triage   exists=True\n  log:     /var/log/triage.log\n```\n\nAdd `--json` for machine-parseable output. The `source` field\nreports which locale-resolution signal won (`TRIAGE_LANG` /\n`LC_ALL` / `LC_MESSAGES` / `LANG` / `locale.getlocale()` /\n`default`), and `drift` is the count of locales out of sync with\nthe English baseline (run `triage lang --check` for the details).\n\n---\n\n## Related projects\n\nTriage is one piece of a small ecosystem. The pieces compose:\n\n| Repo | Role |\n|------|------|\n| [**claude_skill-Triage**](https://github.com/CryptoJones/claude_skill-Triage) | Claude Code skills repo. Ships `TaskPriorityReorder` (**manual override** — \"bump X to top\") today; will host the `triage` skill (**signal-driven recommender** — \"what should I do next?\") in a future release. |\n| [**TriageMCP**](https://github.com/CryptoJones/TriageMCP) | **MCP server** wrapping Triage's API for AI agents. Eight tools (`list_tasks`, `add_task`, `tick`, `why_task`, `status`, `remove_task`, `inject_signal`, `get_task`) over stdio. Drop it into `~/.claude/mcp.json` and an agent can read + write your priority queue directly. |\n| [**RunPodBoss**](https://github.com/CryptoJones/RunPodBoss) | Credit-balance guardrail for RunPod. Integrates with Triage via `extra_notify_command` — when a billing threshold trips, RunPodBoss pushes a manual signal into Triage so the \"drain idle pods\" task floats to the top of your queue. Setup recipe in [`docs/runpodboss-integration.md`](docs/runpodboss-integration.md). |\n\nAll four share Triage's stable-id-plus-recomputable-priority primitive\nand live on dual mirrors (GitHub + Codeberg).\n\n---\n\n## Status\n\n| Version | Feature                                                       | Status   |\n|---------|---------------------------------------------------------------|----------|\n| v0.1    | scaffold, three rules, cron-window signal, CLI                | shipped  |\n| v0.2    | `blocker_transitive` propagation + cycle detection            | shipped  |\n| v0.3    | `github-ci` signal source + `ci_failing` rule + `triage poll` | shipped  |\n| v0.4    | BBS-style ANSI theme system + `triage theme` subcommand       | shipped  |\n| v0.5    | `runpod-cost` signal source + `cost_pressure` rule            | shipped  |\n| v0.6    | JSONL event log writer for external agents                    | shipped  |\n| v0.7    | `github-pr` stale-PR signal source + `rule_stale_pr`          | shipped  |\n| v0.8    | `triage signal` CLI + `manual_bump` rule + RunPodBoss eval    | shipped  |\n| v0.8.1  | `triage status` one-screen at-a-glance summary                | shipped  |\n| v0.9    | i18n foundation — `--lang` flag + en/es/fr baseline           | shipped  |\n| v0.10   | i18n complete — 17 locales + `triage lang --check` regression detector | shipped  |\n| v0.11   | Post-i18n polish — `locale.getlocale()` fallback, `lang --json`, CI gate, model-layer `_()`, status version stamp | shipped  |\n| v0.11.1 | `triage doctor` env-diagnostics subcommand                    | shipped  |\n| —       | Claude Code `triage` skill (in `claude_skill-Triage` repo)    | planned  |\n| —       | `triage watch` long-running mode + systemd unit               | planned  |\n\n---\n\n## License\n\nApache 2.0. See [LICENSE](LICENSE).\n\nProudly Made in Nebraska. Go Big Red! 🌽 https://xkcd.com/2347/\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcryptojones%2Ftriage","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcryptojones%2Ftriage","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcryptojones%2Ftriage/lists"}