From 354724726dcf0a23138c16005621dbcd6e132b07 Mon Sep 17 00:00:00 2001 From: David Bond Date: Tue, 10 Nov 2026 11:29:00 +0000 Subject: [PATCH] fix: classify a ticket as an investigation from its title or labels, not its description Fixes #7. One investigation word in a business case no longer moves an Improvement into the investigation tiers. Labels and title wording still do. No Yoda parity fixture changes. --- .../InvestigationClassificationTests.cs | 51 +++++++++++++++++++ .../Rubrics/panoramicdata-ticket-quality.json | 2 +- 2 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 PanoramicData.IssueAssessment.Tests/Rubrics/InvestigationClassificationTests.cs diff --git a/PanoramicData.IssueAssessment.Tests/Rubrics/InvestigationClassificationTests.cs b/PanoramicData.IssueAssessment.Tests/Rubrics/InvestigationClassificationTests.cs new file mode 100644 index 0000000..967f748 --- /dev/null +++ b/PanoramicData.IssueAssessment.Tests/Rubrics/InvestigationClassificationTests.cs @@ -0,0 +1,51 @@ +using PanoramicData.IssueAssessment.Mapping; +using PanoramicData.IssueAssessment.Rubrics; + +namespace PanoramicData.IssueAssessment.Tests.Rubrics; + +/// +/// Issue #7: an investigation is named by its title or a label, never by one word in the description. +/// +public class InvestigationClassificationTests : TestBase +{ + private static readonly IssueAssessor Assessor = new(BuiltInRubrics.PanoramicDataTicketQuality); + + private const string ImprovementWithBusinessCase = + "h2. Summary\r\nShow run durations on the schedule list.\r\n\r\n" + + "h2. Business case\r\nSupport cannot assess where the time goes without opening each run.\r\n\r\n" + + "h2. Current behaviour\r\nDurations are only on the run page.\r\n\r\n" + + "h2. Requirements\r\n# Add a duration column.\r\n"; + + [Fact] + public async Task InvestigationWordOnlyInDescription_IsNotAnInvestigation() + => (await IsInvestigationAsync("Show run durations on the schedule list", ImprovementWithBusinessCase, [])).Should().BeFalse(); + + [Theory] + [InlineData("investigation")] + [InlineData("research")] + [InlineData("spike")] + public async Task InvestigationLabel_IsStillAnInvestigation(string label) + => (await IsInvestigationAsync("Show run durations on the schedule list", ImprovementWithBusinessCase, [label])).Should().BeTrue(); + + [Fact] + public async Task InvestigationWordInTitle_IsStillAnInvestigation() + => (await IsInvestigationAsync("Investigate why run durations drift", ImprovementWithBusinessCase, [])).Should().BeTrue(); + + private static async Task IsInvestigationAsync(string title, string description, List labels) + { + NormalizedIssue issue = new() + { + Key = "MS-1", + Project = "MS", + Title = title, + Description = description, + IssueType = "Improvement", + Status = "In Progress", + Platform = "Jira", + Labels = [.. labels], + }; + using JsonDocument document = issue.ToJsonDocument(); + AssessmentReport report = AssessmentReport.From(await Assessor.AssessAsync(document, CancellationToken)); + return report.Flags["isInvestigation"]; + } +} diff --git a/PanoramicData.IssueAssessment/Rubrics/panoramicdata-ticket-quality.json b/PanoramicData.IssueAssessment/Rubrics/panoramicdata-ticket-quality.json index 7b11847..6ade539 100644 --- a/PanoramicData.IssueAssessment/Rubrics/panoramicdata-ticket-quality.json +++ b/PanoramicData.IssueAssessment/Rubrics/panoramicdata-ticket-quality.json @@ -28,7 +28,7 @@ { "type": "not", "condition": { "type": "ref", "name": "isBug" } }, { "type": "textMatches", - "source": { "paths": [ "$.title", "$.description" ] }, + "source": { "paths": [ "$.title" ] }, "patterns": [ "\\binvestigate\\b", "\\bresearch\\b", "\\bspike\\b", "\\banalysis\\b", "\\bexplore\\b", "\\bfeasibility\\b", "\\bproof\\s+of\\s+concept\\b", "\\bpoc\\b", "\\bstudy\\b", "\\bevaluate\\b", "\\bassess\\b" ] } ]