Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions skills/backlog-triage/references/classification.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ duplicate_threshold: 0.75
- `closed_issue_limit` caps how many recent closed issues are collected for snapshot v2 enrichment.
- `stale_days` and `duplicate_threshold` are collected as config-as-data for downstream scripts (`triage-stale`, `triage-relate`); `triage-collect` does not apply them yet.

## Snapshot shape

Each snapshot has an explicit schema marker:

```json
{
"schema_version": 2,
"generated": "2026-04-18T01:30:00.000Z",
"repo": "owner/name",
"config_path": "backlog/triage-config.yml",
"issues": []
}
```

`schema_version: 2` means default issue entries include `closing_prs`, while `comments` and top-level `closed_issues` remain opt-in enrichment fields.

## Per-issue snapshot shape

Each entry in `snapshot.issues` has:
Expand Down
10 changes: 6 additions & 4 deletions skills/backlog-triage/references/relationships.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,13 @@ Evidence payloads vary by kind:
}
```

## Deferred to #73
## Deferred follow-ups

These signals are intentionally out of scope for `#62` because the current snapshot schema does not include the required fields:
The snapshot collector now has the raw fields for these signals, but `triage-relate.js` does not emit them yet:

- `comments`-based mention scan
- Reason: the snapshot currently carries `issue.body` only, so comment text is unavailable without extending the snapshot in `#73`.
- Requires: `--with-comments` snapshot enrichment and a clear edge shape that distinguishes issue-body evidence from comment evidence.
- `merged-pr-link` edge kind
- Reason: PR linkage depends on `closing_prs` metadata that is also deferred to the `#73` snapshot extension.
- Requires: interpreting per-issue `closing_prs` without turning every linked PR into a close recommendation.

Tracked in #189.
8 changes: 5 additions & 3 deletions skills/backlog-triage/references/stale.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ Each candidate includes a non-empty `evidence` object.

For `invalid`, only `matchedLabel` and `labels` change accordingly.

## Deferred to #73 / follow-up
## Deferred follow-ups

- `PR already merged`: deferred to #73 because the current snapshot does not include `closing_prs` linkage.
- `Duplicate of closed`: deferred to #73 because the current snapshot does not include closed-issue state for duplicate targets.
- `PR already merged`: collector v2 includes `closing_prs`, but stale analysis still needs a conservative rule before suggesting closure.
- `Duplicate of closed`: `--with-closed-issues` can include bounded closed-issue context, but stale analysis still needs a tested title/body matching rule before suggesting merge-or-close actions.
- `Referenced code removed`: deferred because the current snapshot has no code-removal evidence and no follow-up implementation is defined yet.

The first two signals are tracked in #190.
2 changes: 2 additions & 0 deletions skills/backlog-triage/scripts/triage-collect.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ const GRAPHQL_PAGE_SIZE = 100;
const DEFAULT_CLOSED_ISSUE_DAYS = 180;
const DEFAULT_CLOSED_ISSUE_LIMIT = 200;
const DEFAULT_COMMENT_FETCH_CONCURRENCY = 5;
const SNAPSHOT_SCHEMA_VERSION = 2;
const OPEN_ISSUES_QUERY = `
query($owner: String!, $name: String!, $pageSize: Int!, $endCursor: String) {
repository(owner: $owner, name: $name) {
Expand Down Expand Up @@ -528,6 +529,7 @@ function isProgressIssue(issue) {

function buildSnapshot({ issues, repo, generated, configPath = CONFIG_PATH, config, closedIssues }) {
const snapshot = {
schema_version: SNAPSHOT_SCHEMA_VERSION,
generated,
repo,
config_path: configPath,
Expand Down
2 changes: 2 additions & 0 deletions skills/backlog-triage/scripts/triage-collect.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,7 @@ describe("collectSnapshot", () => {
assert.equal(fs.existsSync(expectedPath), true);

const written = JSON.parse(fs.readFileSync(expectedPath, "utf-8"));
assert.equal(written.schema_version, 2);
assert.equal(written.repo, "sungjunlee/dev-backlog");
assert.equal(written.config_path, "backlog/triage-config.yml");
assert.equal(written.issues.length, 1);
Expand Down Expand Up @@ -400,6 +401,7 @@ describe("collectSnapshot", () => {
});

assert.equal(result.snapshot.repo, "sungjunlee/dev-backlog");
assert.equal(result.snapshot.schema_version, 2);
assert.equal(calls[0].command, "git");
assert.deepEqual(calls[0].args, ["remote", "get-url", "origin"]);
assert.equal(calls[1].command, "gh");
Expand Down
4 changes: 2 additions & 2 deletions skills/backlog-triage/scripts/triage-report.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ const { readSnapshot } = require("./triage-stale.js");
const ANCHOR_PATTERN = /<!--\s*triage:([\w-]+)\s+#(\d+)(?:\s+(.*?))?\s*-->/;
const DEFAULT_REPORT_DIR = path.join("backlog", "triage");
const DEFERRED_RELATIONSHIPS_MARKER =
"_(PR-merged edges deferred — requires snapshot v2 `closing_prs`; tracked in #73)_";
"_(PR/comment relationship signals deferred — collector fields exist; analyzer rules tracked in #189)_";
const DEFERRED_OBSOLETE_MARKER =
"_(closing-PR-already-merged and duplicate-of-closed signals deferred — requires snapshot v2; tracked in #73)_";
"_(closing-PR-already-merged and duplicate-of-closed signals deferred — collector fields exist; stale rules tracked in #190)_";

function usage() {
return "Usage: triage-report.js --snapshot PATH [--relate PATH] [--stale PATH] [--out PATH] [--json]";
Expand Down
2 changes: 1 addition & 1 deletion skills/backlog-triage/scripts/triage-report.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -356,7 +356,7 @@ describe("triage-report integration chain", () => {
assert.match(markdown, /<!-- triage:close #104 reason="inactive\/stale: no activity for 107 days; exceeds stale_days threshold \(60\); no milestone assigned" -->/);
assert.match(markdown, /<!-- triage:close #105 reason="labeled wontfix; explicit wontfix signal" -->/);
assert.match(markdown, /<!-- triage:close #106 reason="labeled invalid; explicit invalid signal" -->/);
assert.match(markdown, /PR-merged edges deferred/);
assert.match(markdown, /PR\/comment relationship signals deferred/);
assert.match(markdown, /closing-PR-already-merged and duplicate-of-closed signals deferred/);

// Classification groups must match Done Criteria: theme / label / age.
Expand Down
Loading