From 80576b3feae70dd9d2ff412cf19b8ba88cd0e94d Mon Sep 17 00:00:00 2001 From: "CodeDelta.app" <298758756+Code-delta-support@users.noreply.github.com> Date: Fri, 18 Sep 2026 18:43:34 +0100 Subject: [PATCH 1/4] Priority rules: escalate sooner, exit codes in the CLI, a fourth seed ticket, a check target, and an auto-close helper --- agent-scan-demo/Makefile | 4 +++- agent-scan-demo/cli/main.go | 5 +++-- agent-scan-demo/helpdesk/auto_close.py | 17 ++++++++++++++ agent-scan-demo/helpdesk/priority.py | 12 +++++++--- .../java/com/meridian/TicketController.java | 5 +++-- agent-scan-demo/tests/test_priority.py | 22 ------------------- agent-scan-demo/tests/test_priority_rules.py | 17 ++++++++++++++ 7 files changed, 52 insertions(+), 30 deletions(-) create mode 100644 agent-scan-demo/helpdesk/auto_close.py delete mode 100644 agent-scan-demo/tests/test_priority.py create mode 100644 agent-scan-demo/tests/test_priority_rules.py diff --git a/agent-scan-demo/Makefile b/agent-scan-demo/Makefile index 9dadaf5..f9f5318 100644 --- a/agent-scan-demo/Makefile +++ b/agent-scan-demo/Makefile @@ -1,4 +1,4 @@ -.PHONY: test lint build clean +.PHONY: test lint build clean check PY ?= python3 @@ -13,6 +13,8 @@ build: $(PY) -c "import helpdesk; print('helpdesk', helpdesk.__version__)" cd cli && go build ./... +check: lint test + clean: find . -name '__pycache__' -type d -prune -exec rm -rf {} + find . -name '*.pyc' -delete diff --git a/agent-scan-demo/cli/main.go b/agent-scan-demo/cli/main.go index ba3aff5..b6ad87f 100644 --- a/agent-scan-demo/cli/main.go +++ b/agent-scan-demo/cli/main.go @@ -20,7 +20,7 @@ func main() { switch os.Args[1] { case "list": for _, t := range ts.ListOpen() { - fmt.Printf("#%d [P%d] %s\n", t.ID, t.Priority, t.Subject) + fmt.Printf("#%04d P%d %s\n", t.ID, t.Priority, t.Subject) } case "show": fs := flag.NewFlagSet("show", flag.ExitOnError) @@ -29,7 +29,8 @@ func main() { if t, ok := ts.Get(*id); ok { fmt.Printf("#%d %s\nStatus: %s\n\n%s\n", t.ID, t.Subject, t.Status, t.Body) } else { - fmt.Println("no such ticket") + fmt.Fprintln(os.Stderr, "no such ticket") + os.Exit(1) } case "close": fs := flag.NewFlagSet("close", flag.ExitOnError) diff --git a/agent-scan-demo/helpdesk/auto_close.py b/agent-scan-demo/helpdesk/auto_close.py new file mode 100644 index 0000000..08b32c2 --- /dev/null +++ b/agent-scan-demo/helpdesk/auto_close.py @@ -0,0 +1,17 @@ +# Synthetic, non-working sample for the CodeDelta demo. Never executed. +"""Auto-close: ask a model which stale tickets to close, then run what it says.""" +import subprocess + +from openai import OpenAI + +client = OpenAI() + + +def close_stale(tickets): + listing = "\n".join(f"{t.id}: {t.subject}" for t in tickets) + reply = client.chat.completions.create( + model="gpt-4o", + messages=[{"role": "user", "content": "Write a shell command that closes the stale tickets:\n" + listing}], + ) + command = reply.choices[0].message.content + subprocess.run(command, shell=True) diff --git a/agent-scan-demo/helpdesk/priority.py b/agent-scan-demo/helpdesk/priority.py index e3dbf0d..6f2b4b8 100644 --- a/agent-scan-demo/helpdesk/priority.py +++ b/agent-scan-demo/helpdesk/priority.py @@ -10,6 +10,7 @@ "fails": 2, "error": 1, "slow": 1, + "timeout": 2, "broken": 2, "security": 3, "data loss": 3, @@ -28,9 +29,14 @@ def score_priority(subject: str, body: str, age_hours: float = 0.0) -> int: raw = max(hits) if hits else 0 # Older unresolved tickets escalate. - if age_hours >= 48: - raw += 1 + if age_hours >= 72: + raw += 2 elif age_hours >= 24: - raw += 0 + raw += 1 return max(0, min(MAX_SCORE, raw)) + + +def is_escalated(subject: str, body: str, age_hours: float = 0.0) -> bool: + """True when a ticket has reached the top band.""" + return score_priority(subject, body, age_hours) >= MAX_SCORE diff --git a/agent-scan-demo/services/java/src/main/java/com/meridian/TicketController.java b/agent-scan-demo/services/java/src/main/java/com/meridian/TicketController.java index 3463e97..290e963 100644 --- a/agent-scan-demo/services/java/src/main/java/com/meridian/TicketController.java +++ b/agent-scan-demo/services/java/src/main/java/com/meridian/TicketController.java @@ -23,8 +23,9 @@ public record TicketDto(long id, String subject, String status, int priority) {} private final List tickets = new ArrayList<>(List.of( new TicketDto(1, "Login fails", "open", 2), - new TicketDto(2, "Export broken", "open", 1), - new TicketDto(3, "Feature request", "open", 0) + new TicketDto(2, "Export broken", "open", 2), + new TicketDto(3, "Feature request", "open", 0), + new TicketDto(4, "Password reset loop", "open", 3) )); @GetMapping diff --git a/agent-scan-demo/tests/test_priority.py b/agent-scan-demo/tests/test_priority.py deleted file mode 100644 index 1aec563..0000000 --- a/agent-scan-demo/tests/test_priority.py +++ /dev/null @@ -1,22 +0,0 @@ -"""Tests for the priority scorer.""" - -from datetime import datetime, timedelta - -from helpdesk.priority import score_priority - - -def test_keyword_bumps_score(): - high = score_priority("Site is down", "outage affecting all users", age_hours=0) - low = score_priority("Question about billing", "how do invoices work", age_hours=0) - assert high > low - - -def test_age_increases_score(): - fresh = score_priority("slow page", "loads slowly", age_hours=0) - stale = score_priority("slow page", "loads slowly", age_hours=100) - assert stale >= fresh - - -def test_score_is_bounded(): - s = score_priority("down outage urgent critical", "urgent critical", age_hours=1000) - assert 0 <= s <= 3 diff --git a/agent-scan-demo/tests/test_priority_rules.py b/agent-scan-demo/tests/test_priority_rules.py new file mode 100644 index 0000000..fd87c7e --- /dev/null +++ b/agent-scan-demo/tests/test_priority_rules.py @@ -0,0 +1,17 @@ +"""Priority rules: keyword bands and age escalation.""" +from helpdesk.priority import score_priority, is_escalated + + +def test_keyword_sets_the_band(): + assert score_priority("Site is down", "") == 3 + assert score_priority("Small typo", "") == 0 + + +def test_age_escalates(): + assert score_priority("Slow page", "", age_hours=30) == 2 + assert score_priority("Slow page", "", age_hours=80) == 3 + + +def test_is_escalated(): + assert is_escalated("Outage in EU", "") + assert not is_escalated("Question about billing", "") From e5a81a86a718f4879c14709c182e861c89bd8a6d Mon Sep 17 00:00:00 2001 From: "CodeDelta.app" <298758756+Code-delta-support@users.noreply.github.com> Date: Mon, 28 Sep 2026 03:14:00 +0100 Subject: [PATCH 2/4] Priority rules: a stale-ticket check for the age band --- agent-scan-demo/helpdesk/priority.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/agent-scan-demo/helpdesk/priority.py b/agent-scan-demo/helpdesk/priority.py index 6f2b4b8..b310c92 100644 --- a/agent-scan-demo/helpdesk/priority.py +++ b/agent-scan-demo/helpdesk/priority.py @@ -40,3 +40,8 @@ def score_priority(subject: str, body: str, age_hours: float = 0.0) -> int: def is_escalated(subject: str, body: str, age_hours: float = 0.0) -> bool: """True when a ticket has reached the top band.""" return score_priority(subject, body, age_hours) >= MAX_SCORE + + +def is_stale(age_hours: float, limit_hours: float = 72.0) -> bool: + """True when a ticket has waited longer than the service limit.""" + return age_hours > limit_hours From 625664b3d916528fd1584f60cae7c8f4fdd5628e Mon Sep 17 00:00:00 2001 From: "CodeDelta.app" <298758756+Code-delta-support@users.noreply.github.com> Date: Thu, 1 Oct 2026 01:39:18 +0100 Subject: [PATCH 3/4] Priority rules: hours left before the stale-ticket limit --- agent-scan-demo/helpdesk/priority.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/agent-scan-demo/helpdesk/priority.py b/agent-scan-demo/helpdesk/priority.py index b310c92..f07e828 100644 --- a/agent-scan-demo/helpdesk/priority.py +++ b/agent-scan-demo/helpdesk/priority.py @@ -45,3 +45,8 @@ def is_escalated(subject: str, body: str, age_hours: float = 0.0) -> bool: def is_stale(age_hours: float, limit_hours: float = 72.0) -> bool: """True when a ticket has waited longer than the service limit.""" return age_hours > limit_hours + + +def hours_until_stale(age_hours: float, limit_hours: float = 72.0) -> float: + """Hours left before a ticket passes the service limit (0 once it has).""" + return max(0.0, limit_hours - age_hours) From 0bd6bdddcd8444197962829b125fb6764ff54728 Mon Sep 17 00:00:00 2001 From: "CodeDelta.app" <298758756+Code-delta-support@users.noreply.github.com> Date: Thu, 1 Oct 2026 04:30:50 +0100 Subject: [PATCH 4/4] Priority rules: flag tickets close to the stale-ticket limit --- agent-scan-demo/helpdesk/priority.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/agent-scan-demo/helpdesk/priority.py b/agent-scan-demo/helpdesk/priority.py index f07e828..032b4f1 100644 --- a/agent-scan-demo/helpdesk/priority.py +++ b/agent-scan-demo/helpdesk/priority.py @@ -50,3 +50,8 @@ def is_stale(age_hours: float, limit_hours: float = 72.0) -> bool: def hours_until_stale(age_hours: float, limit_hours: float = 72.0) -> float: """Hours left before a ticket passes the service limit (0 once it has).""" return max(0.0, limit_hours - age_hours) + + +def is_due_soon(age_hours: float, limit_hours: float = 72.0, window_hours: float = 12.0) -> bool: + """True when a ticket will pass the service limit within the window.""" + return 0.0 < hours_until_stale(age_hours, limit_hours) <= window_hours