+ Page not found +
+ +Sorry, but the page you were trying to get to, does not exist. You +may want to try searching this site using the sidebar + + or using our API Reference page + +to find what you were looking for.
+ +diff --git a/README.md b/README.md index e295979..2ce5c64 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,26 @@ Optional: | `TRIAGEBOT_PORT` | `8080` | Nova HTTP listener | | `TRIAGEBOT_METRICS_PORT` | `9568` | Prometheus /metrics; set to `""` to disable | | `TRIAGEBOT_AGENT_MODEL` | per-backend | Override agent model | +| `TRIAGEBOT_POLICY_PATH` | `priv/TRIAGE.md` | Filesystem path to the triage-policy file fed to every agent | + +### Triage policy + +Every triage run is fed a shared **repository triage context** before the +issue: the contents of a triage-policy file plus the repo's label +taxonomy. The policy teaches the agents how *this* project triages - +what the categories mean, the severity rubric, which labels to use, +escalation rules - and agents follow it where it conflicts with their +built-in defaults. + +The policy ships in the release at `priv/TRIAGE.md`; edit that file and +redeploy, or point `TRIAGEBOT_POLICY_PATH` at another file. A missing +file is fine - agents fall back to their built-in defaults. To reload +without a redeploy, call `triagebot_config:refresh_triage_policy()` from +a remote shell. + +Each issue also carries its high-signal GitHub fields into the context: +contributor association (e.g. `FIRST_TIME_CONTRIBUTOR`), reaction count, +comment count, milestone, and assignees. ### 3. Local development with PAT @@ -141,8 +161,10 @@ That's it. - Spawn-and-forget async (BEAM process per webhook) so the response returns 202 immediately while triage runs in the background - GitHub App or PAT auth (via `gakudan_tickets_github` v0.1.2+) -- Repo-context awareness: classifier + scoper can read repo files; - label_proposer picks from the repo's actual label taxonomy +- Repo-context awareness: a bundled triage policy (`priv/TRIAGE.md`) + + the repo's actual label taxonomy + each issue's contributor/reaction/ + milestone signals are fed to every agent; classifier + scoper can also + read repo files on demand - Prometheus `/metrics` via `gakudan_metrics` - 20-case CT suite covering the runner helpers, agent callbacks, tool shapes, and dynamic prompt building diff --git a/doc/.build b/doc/.build new file mode 100644 index 0000000..7ef757f --- /dev/null +++ b/doc/.build @@ -0,0 +1,25 @@ +404.html +api-reference.html +dist/html-HBZYRXZS.js +dist/html-erlang-7YNYEB7F.css +dist/lato-latin-400-normal-W7754I4D.woff2 +dist/lato-latin-700-normal-2XVSBPG4.woff2 +dist/lato-latin-ext-400-normal-N27NCBWW.woff2 +dist/lato-latin-ext-700-normal-Q2L5DVMW.woff2 +dist/remixicon-QPNJX265.woff2 +dist/search_data-4AA356A9.js +dist/sidebar_items-463C534A.js +index.html +search.html +triagebot_classifier.html +triagebot_config.html +triagebot_context.html +triagebot_dashboard_auth.html +triagebot_dup_detector.html +triagebot_label_proposer.html +triagebot_repo_context_tool.html +triagebot_runner.html +triagebot_scoper.html +triagebot_search_tool.html +triagebot_summariser.html +triagebot_webhook_controller.html diff --git a/doc/404.html b/doc/404.html new file mode 100644 index 0000000..6a02443 --- /dev/null +++ b/doc/404.html @@ -0,0 +1,141 @@ + + +
+ + + + + + + + + +Sorry, but the page you were trying to get to, does not exist. You +may want to try searching this site using the sidebar + + or using our API Reference page + +to find what you were looking for.
+ +First agent in the triage pipeline. Reads the issue body and emits a +classification line.
Runtime configuration for triagebot, sourced from env vars.
Builds the run input sent to the gakudan triage pipeline.
HTTP Basic auth gate for the triagebot live dashboard.
Third agent. Uses the search_issues tool to look for likely duplicates
+of the current issue.
Fourth agent. Reads the issue + all prior triage turns and proposes a +set of labels, drawn from the repo's label taxonomy in the shared +repository triage context.
gakudan tool that fetches a file from the configured GitHub repo,
+giving the triage agents a way to ground themselves in repo-specific
+context (CLAUDE.md, README.md, CONTRIBUTING.md, the file an
+issue links to, etc.).
Bridges a verified webhook event to a gakudan triage run.
Second agent. Reads the issue + classifier output and assesses severity +and scope.
gakudan tool that searches the configured GitHub repo for issues +matching a query, returning a short text summary the LLM can read.
Fifth and final agent. Reads everything above and produces the comment +that gets posted to the issue.
Nova controller for GitHub webhook deliveries.
'+((s=t.lambda(e,e))!=null?s:"")+`
+`},9:function(t,e,n,r,i){var s,o=t.lookupProperty||function(a,l){if(Object.prototype.hasOwnProperty.call(a,l))return a[l]};return((s=(o(n,"isArray")||e&&o(e,"isArray")||t.hooks.helperMissing).call(e??(t.nullContext||{}),e!=null?o(e,"results"):e,{name:"isArray",hash:{},fn:t.program(10,i,0),inverse:t.program(12,i,0),data:i,loc:{start:{line:23,column:2},end:{line:29,column:14}}}))!=null?s:"")+` +The search functionality is full-text based. Here are some tips:
+ +foo bar) are searched as OR* anywhere (such as fo*) as wildcard+ before a word (such as +foo) to make its presence required- before a word (such as -foo) to make its absence required: to search on a particular field (such as field:word). The available fields are title, doc and typeWORD^NUMBER (such as foo^2) to boost the given wordWORD~NUMBER (such as foo~2) to do a search with edit distance on wordTo quickly go to a module, type, or function, use the autocompletion feature in the sidebar search.
+`},10:function(t,e,n,r,i){var s,o=t.lookupProperty||function(a,l){if(Object.prototype.hasOwnProperty.call(a,l))return a[l]};return"Sorry, we couldn't find anything for "+t.escapeExpression((s=(s=o(n,"value")||(e!=null?o(e,"value"):e))!=null?s:t.hooks.helperMissing,typeof s=="function"?s.call(e??(t.nullContext||{}),{name:"value",hash:{},data:i,loc:{start:{line:24,column:48},end:{line:24,column:57}}}):s))+`.
+`},12:function(t,e,n,r,i){var s,o=t.lookupProperty||function(a,l){if(Object.prototype.hasOwnProperty.call(a,l))return a[l]};return(s=o(n,"if").call(e??(t.nullContext||{}),e!=null?o(e,"value"):e,{name:"if",hash:{},fn:t.program(13,i,0),inverse:t.program(15,i,0),data:i,loc:{start:{line:25,column:2},end:{line:29,column:2}}}))!=null?s:""},13:function(t,e,n,r,i){var s,o=t.lookupProperty||function(a,l){if(Object.prototype.hasOwnProperty.call(a,l))return a[l]};return"Invalid search: "+t.escapeExpression((s=(s=o(n,"errorMessage")||(e!=null?o(e,"errorMessage"):e))!=null?s:t.hooks.helperMissing,typeof s=="function"?s.call(e??(t.nullContext||{}),{name:"errorMessage",hash:{},data:i,loc:{start:{line:26,column:23},end:{line:26,column:39}}}):s))+`.
+`},15:function(t,e,n,r,i){return`Please type something into the search bar to perform a search.
+ `},compiler:[8,">= 4.3.0"],main:function(t,e,n,r,i){var s,o=e??(t.nullContext||{}),a=t.lookupProperty||function(l,u){if(Object.prototype.hasOwnProperty.call(l,u))return l[u]};return`First agent in the triage pipeline. Reads the issue body and emits a +classification line.
+Runtime configuration for triagebot, sourced from env vars.
Reads everything from the environment at startup, stashes the resolved
+GitHub source_ref in persistent_term so the search tool (which runs
+inside a turn-worker process spawned by gakudan) can read it without a
+GenServer round-trip.
Required env vars:
GitHub auth (one of):
LLM backend (one of):
Optional:
set to "" to disable) claude-sonnet-4-6 for Anthropic,
+ gemini-2.5-flash for Gemini) read at startup and fed to every agent.
+ Defaults to the bundled priv/TRIAGE.md so
+ the policy ships with the release. Absent
+ file is fine - agents fall back to their
+ built-in defaults.Re-fetch the repo's labels from GitHub and update the cached value. +Useful from a remote shell when the repo's label taxonomy changes +between deploys.
Re-fetch the triage-policy file from GitHub and update the cached value. +Useful from a remote shell when the policy changes between deploys.
Return the configured repo's labels (as fetched at startup). Each
+label is #{name, description, color}. Empty list if the fetch
+failed - the agents fall back to their built-in vocabulary in that
+case.
Return the repo's triage-policy file contents (as fetched at startup), +or an empty binary if no policy file was found. The policy is fed to +every triage agent via the run input.
-spec agent_model() -> binary().+ +
-spec github_source() -> map().+ +
-spec metrics_port() -> inet:port_number() | undefined.+ +
-spec port() -> inet:port_number().+ +
-spec refresh_repo_labels() -> ok | {error, term()}.+ +
Re-fetch the repo's labels from GitHub and update the cached value. +Useful from a remote shell when the repo's label taxonomy changes +between deploys.
+-spec refresh_triage_policy() -> ok | {error, term()}.+ +
Re-fetch the triage-policy file from GitHub and update the cached value. +Useful from a remote shell when the policy changes between deploys.
+Return the configured repo's labels (as fetched at startup). Each
+label is #{name, description, color}. Empty list if the fetch
+failed - the agents fall back to their built-in vocabulary in that
+case.
-spec setup() -> ok.
+
+ -spec triage_policy() -> binary().+ +
Return the repo's triage-policy file contents (as fetched at startup), +or an empty binary if no policy file was found. The policy is fed to +every triage agent via the run input.
+-spec webhook_secret() -> binary().+ +
Builds the run input sent to the gakudan triage pipeline.
The input is a single message every agent reads: a shared +repository-context preamble (the triage policy + the repo's label +taxonomy) followed by the issue itself, enriched with the high-signal +fields GitHub puts in the raw issue payload - contributor association, +reactions, comment count, milestone, and assignees.
Keeping the policy and label vocabulary here, in the shared input, means +they live in one place rather than being duplicated across every agent's +system prompt.
+-spec build_input(gakudan_tickets:ticket()) -> binary().+ +
-spec format_ticket(gakudan_tickets:ticket()) -> binary().+ +
HTTP Basic auth gate for the triagebot live dashboard.
Credentials come from TRIAGEBOT_DASHBOARD_USER / TRIAGEBOT_DASHBOARD_PASSWORD.
Closed by default: if either is unset the dashboard denies everything (503), so +it is never accidentally exposed. The username and password are compared in +constant time. Gates both the view routes and the HITL controls.
+-spec check(cowboy_req:req()) -> {true, map()} | {false, 401 | 503, map(), binary()}.+ +
Third agent. Uses the search_issues tool to look for likely duplicates
+of the current issue.
Fourth agent. Reads the issue + all prior triage turns and proposes a +set of labels, drawn from the repo's label taxonomy in the shared +repository triage context.
+gakudan tool that fetches a file from the configured GitHub repo,
+giving the triage agents a way to ground themselves in repo-specific
+context (CLAUDE.md, README.md, CONTRIBUTING.md, the file an
+issue links to, etc.).
The active GitHub source_ref is read from triagebot_config
+(persistent_term) because tools run inside a turn-worker process with
+no parameter for per-run context.
File contents are truncated to ?MAX_BYTES to keep prompt size
+bounded; the LLM sees a clear suffix when truncation happened.
Bridges a verified webhook event to a gakudan triage run.
dispatch/2 is invoked from the webhook controller. It spawns a
+detached Erlang process so the controller can return 202 immediately
+while the LLM-bound work continues in the background.
Only issue_opened and issue_labeled events are processed. Other
+events (closed, edited, etc.) are ignored at the runner level to keep
+LLM cost predictable and avoid re-triaging on every edit.
If the issue already carries the triaged label, we skip - this gives
+human maintainers a manual override (label, fix, push, no bot retriage)
+and protects against the bot looping on its own label updates.
-spec dispatch(atom(), gakudan_tickets:ticket()) -> ok.+ +
-spec run_triage(gakudan_tickets:ticket()) -> ok.+ +
Second agent. Reads the issue + classifier output and assesses severity +and scope.
+gakudan tool that searches the configured GitHub repo for issues +matching a query, returning a short text summary the LLM can read.
The active GitHub source_ref is read from triagebot_config
+(persistent_term) because gakudan tools run inside a turn-worker
+process spawned by the run state machine, with no parameter for
+per-run context.
Fifth and final agent. Reads everything above and produces the comment +that gets posted to the issue.
+Nova controller for GitHub webhook deliveries.
Reads the raw body (needed for HMAC), verifies the signature against the
+configured shared secret, parses the event, and hands off to
+triagebot_runner for async processing.
Returns:
Nova's handle_status does not accept a trailing Req in 3-tuple form;
+that slot is ExtraHeaders :: map(). We use the bare {status, Code}
+form to let Nova render with its own Req.