| name | issue-triage |
| description | For TizenFX issues that lack the `ai-task` label and have no assignee, posts an English first-pass technical answer plus a CODEOWNERS-based reviewer mention. Comments only ā never assigns, never edits labels, never modifies code. |
TizenFX Issue Triage Pipeline
Overview
For open issues in samsung/TizenFX that have not been claimed by a human owner and are not already in the AI execution queue (ai-task label):
- Post a first-pass technical response in English summarising the issue and offering an initial analysis or pointer.
- Identify the most likely code area, look up
.github/CODEOWNERS, and mention the matching reviewer(s) so they can self-assign.
This skill never:
- modifies code,
- creates PRs or branches,
- assigns issues (
gh issue edit --add-assignee),
- adds or removes labels,
- closes issues.
It only comments. All decisions stay with the humans involved.
All comments are written in English and prefixed with š¤ [AI Triage] so future runs can skip already-triaged issues.
Repository
- Repo: samsung/TizenFX (GitHub)
- CLI:
gh CLI (authenticated)
- CODEOWNERS path:
.github/CODEOWNERS in the repo working tree
Constants
MAX_ISSUES_PER_RUN = 5
STALE_THRESHOLD_DAYS = 90 # Issues with updatedAt older than this are skipped
DEFAULT_FALLBACK = @JoonghyunCho # When CODEOWNERS lookup fails
COMMENT_PREFIX = š¤ [AI Triage]
Pipeline Flow
āŖ Discover triage candidates
ā ā Apply skip filters
ā ā” For each survivor (max 5):
a. Fetch issue body + comments
b. Identify likely code area
c. CODEOWNERS lookup
d. Draft first-pass technical response
e. Post comment (mention only ā no assign, no label)
Stage āŖ: Discover Open Triage Candidates
gh issue list --repo samsung/TizenFX --state open \
--json number,title,createdAt,updatedAt,assignees,labels,author \
--jq '[.[]
| select((.labels // []) | map(.name) | index("ai-task") | not)
| select((.assignees // []) | length == 0)]
| sort_by(.updatedAt) | reverse'
- Drops issues with
ai-task label (handled by refactor-execute)
- Drops issues with any assignee (someone is already on it)
- Sorted by
updatedAt descending (most recently active first)
Stage ā : Apply Skip Filters
Filter the candidate list down further. In order, drop an issue when any of these holds:
-
Already triaged by AI ā issue has at least one comment whose body starts with š¤ [AI Triage].
gh issue view {N} --repo samsung/TizenFX --comments \
--json comments --jq '.comments[] | select(.body | startswith("š¤ [AI Triage]"))' \
| head -1
Non-empty result ā skip.
-
Stale ā updatedAt is older than STALE_THRESHOLD_DAYS (90 days).
- Compute:
(now - updatedAt) in days. If > 90, skip.
- Reason: Re-engaging a long-dormant thread creates noise; re-activation is a human decision.
-
Author is a bot ā author.login ends with [bot] or matches a known bot list (dependabot, renovate, github-actions).
- Skip; bots typically don't need triage answers.
After filters, take up to MAX_ISSUES_PER_RUN (5) issues, oldest-updatedAt-first among the survivors so we drain the older ones first.
Stage ā”a: Fetch Issue Detail
For each selected issue:
gh issue view {N} --repo samsung/TizenFX --comments \
--json title,body,comments,labels,author
Read all comments (not only the body) so we don't repeat what someone has already answered.
Stage ā”b: Identify Likely Code Area
Goal: produce a list of candidate repo paths for CODEOWNERS lookup.
Heuristics (apply all that match):
- Explicit code references in body ā file paths like
src/Tizen.Sensor/..., Tizen.NUI.Layout, fully-qualified class names like BluetoothErrorFactory.
- Title keywords ā namespace fragments (
NUI, Sensor, Bluetooth, Application) map to src/Tizen.NUI/, src/Tizen.Sensor/, etc.
- Code blocks ā
using Tizen.Foo; reveals the namespace, which maps to a src/Tizen.Foo/ directory (verify by ls src/Tizen.Foo* if uncertain).
If no path can be inferred, emit a single placeholder candidate of (unknown) and proceed to Stage ā”c with the fallback owner.
Cap candidate paths at 3 to keep CODEOWNERS lookup focused ā the most-mentioned path wins ties.
Stage ā”c: CODEOWNERS Lookup
Read .github/CODEOWNERS from the local repo working tree (already synced by the launcher).
Standard CODEOWNERS semantics:
- Each non-comment, non-empty line:
<path-pattern> @owner1 @owner2 ...
- Last matching rule wins (per GitHub's CODEOWNERS spec).
- Inline
# comments are stripped ā @user1 #@user2 means owner is @user1 only.
Algorithm:
- Parse CODEOWNERS into ordered list of
(pattern, owners[]) tuples.
- For each candidate path from Stage ā”b:
- Walk the rule list in reverse and pick the first rule whose pattern matches the path. (= last-match-wins.)
- Collect the owner set.
- Combine owner sets across candidate paths; deduplicate; cap at 3 owners to prevent mass-pinging.
- Fallback ā if no rule matched any candidate path, mention
DEFAULT_FALLBACK (= @JoonghyunCho) and note in the comment that auto-routing failed.
Stage ā”d: First-Pass Technical Response
The comment is English and structured. Default template:
š¤ [AI Triage]
**Summary**
{1-2 sentence restatement of the filer's question or reported behaviour. Show that the AI understood the issue.}
**Initial analysis**
{2-6 sentences of substantive technical content:
- For "how do I" questions ā a concrete answer or pointer to an API / sample.
- For bug reports ā a hypothesis about the cause and what the reporter could try
(logs, repro steps, version checks).
- For feature requests ā acknowledge feasibility constraints if obvious (e.g.,
"This requires native daemon support and is out of scope for the .NET binding").
If the issue is too ambiguous to analyse meaningfully, ask **one** specific
clarifying question instead of guessing.}
**Likely area & reviewer**
- Code area: `{src/Tizen.Foo/}` (or "unable to determine" if unknown)
- Suggested reviewer(s): {@user1 @user2}
---
*This is an automated first-pass triage. The mentioned maintainer(s) have not been
assigned ā they will pick up the issue if appropriate. If the routing is wrong,
please re-direct or remove the mention.*
If the fallback owner was used:
**Likely area & reviewer**
- Code area: unable to determine from issue contents
- @JoonghyunCho ā auto-routing via CODEOWNERS could not match a specific area;
flagging you for manual triage.
Tone constraints:
- No promises ("This will be fixed in vNN") ā AI cannot commit on maintainers' behalf.
- No follow-up reminders or pings to the filer.
- No condescension; assume the filer made a good-faith report.
- Don't speculate beyond the evidence ā if uncertain, say "this looks like X but I'm not sure" rather than asserting.
Stage ā”e: Post the Comment
gh issue comment {N} --repo samsung/TizenFX --body-file triage_comment.md
After posting, do nothing else ā no labels, no assignees, no follow-up. Move to the next issue.
Constraints (hard rules)
- At most
MAX_ISSUES_PER_RUN (5) issues per run. Exit unconditionally after that.
- Never call
gh issue edit (no labels, no assignees, no state changes).
- Never open or modify code files in the repo. This skill is comment-only.
- Never post a second
š¤ [AI Triage] comment on the same issue.
- If
gh exits non-zero on any sub-step for an issue, log it, skip that issue, and continue with the next survivor ā do not retry indefinitely.
Result Report
At the end of the run, print a short structured report:
### Stage āŖ: Candidates discovered
{N issues considered}
### Stage ā : Survivors after filters
{N issues passed: ai-task=excluded, assignee=excluded, already-triaged=excluded, stale=excluded, bot-author=excluded}
### Stage ā”: Triage actions
- #{num} ā mentioned @{owner}, area `{path}`, status: posted
- #{num} ā fallback to @JoonghyunCho (no CODEOWNERS match), status: posted
- #{num} ā skipped (gh comment posting failed: {reason})
### Outcome
- Triaged: {N}
- Skipped: {N}
- Failed: {N}