diff --git a/skills/backlog-triage/references/classification.md b/skills/backlog-triage/references/classification.md index 481a7ca..79ecb90 100644 --- a/skills/backlog-triage/references/classification.md +++ b/skills/backlog-triage/references/classification.md @@ -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: diff --git a/skills/backlog-triage/references/relationships.md b/skills/backlog-triage/references/relationships.md index 3477805..0ac36ca 100644 --- a/skills/backlog-triage/references/relationships.md +++ b/skills/backlog-triage/references/relationships.md @@ -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. diff --git a/skills/backlog-triage/references/stale.md b/skills/backlog-triage/references/stale.md index 4fdea96..5382bc8 100644 --- a/skills/backlog-triage/references/stale.md +++ b/skills/backlog-triage/references/stale.md @@ -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. diff --git a/skills/backlog-triage/scripts/triage-collect.js b/skills/backlog-triage/scripts/triage-collect.js index af01003..4d8df01 100755 --- a/skills/backlog-triage/scripts/triage-collect.js +++ b/skills/backlog-triage/scripts/triage-collect.js @@ -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) { @@ -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, diff --git a/skills/backlog-triage/scripts/triage-collect.test.js b/skills/backlog-triage/scripts/triage-collect.test.js index 8695046..4309d03 100644 --- a/skills/backlog-triage/scripts/triage-collect.test.js +++ b/skills/backlog-triage/scripts/triage-collect.test.js @@ -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); @@ -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"); diff --git a/skills/backlog-triage/scripts/triage-report.js b/skills/backlog-triage/scripts/triage-report.js index f50154d..6b9bd88 100755 --- a/skills/backlog-triage/scripts/triage-report.js +++ b/skills/backlog-triage/scripts/triage-report.js @@ -7,9 +7,9 @@ const { readSnapshot } = require("./triage-stale.js"); const ANCHOR_PATTERN = //; 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]"; diff --git a/skills/backlog-triage/scripts/triage-report.test.js b/skills/backlog-triage/scripts/triage-report.test.js index c055612..8f2cf29 100644 --- a/skills/backlog-triage/scripts/triage-report.test.js +++ b/skills/backlog-triage/scripts/triage-report.test.js @@ -356,7 +356,7 @@ describe("triage-report integration chain", () => { assert.match(markdown, //); assert.match(markdown, //); assert.match(markdown, //); - 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.