Repository navigation
[ticket-004] fix(planfile): dedupe WUP incident tickets by failure signature - #23
Conversation
…gnature Fingerprinting by exact failure message let volatile details (latency values, timestamps) spawn sibling tickets for one incident — 136 registry entries in c2004, 43 for connect-scenario/probe-latency alone. Dedupe now mutes on any open ticket sharing the (service, stage, status) signature and suppresses re-filing for refile_cooldown_seconds (default 24h) after the signature ticket reaches a terminal status. Closed observations are cached per entry (terminal statuses are immutable), so steady-state cost stays one `ticket show` per event. refile_cooldown_seconds=0 restores immediate re-filing. Co-authored-by: Koru Agent <agent@coru.dev>
There was a problem hiding this comment.
Validator approval after policy checks for exact head 9c9b443a44c983e6c99cd2ff134fc10c42091f7a.
Ticket: ticket-004
Correlation ID: local-semcod-wup-pr-23-ticket-004
Model: openai/cursor-auto
Reviewed diff chunks: 2
Advisory LLM verdict: APPROVE
Advisory summary: Reviewed all 2 diff chunk(s). Chunk 2 of 2: Introduces signature-based incident deduplication, a configurable cooldown period (refile_cooldown_seconds), and helper methods for parsing ticket statuses. Also includes extensive test coverage for the new behavior. | The diff chunk correctly implements the signature-based ticket deduplication logic and cooldown handling. The _signature_mute method properly checks existing entries for open tickets or recently closed tickets based on the cooldown period, and the _parse_instant method safely parses timestamps.
Advisory findings: none
The LLM output above is advisory and was not used as the approval trust root.
Semantic review prerequisite: not_required; policy 676cb4516bbfed2a000e40b9b1b6e4a430ecc761ec546aeb53d721a1905cfdd7.
Actual PR impact radar
Exact range: 8832bcb92b4eba10a9e8057ac70fbf8f65e66065...9c9b443a44c983e6c99cd2ff134fc10c42091f7a
Change digest: 9eecb4a890334247a36d7313c024700e4c7ae7a25e6ca9b21b3bc28dc20f0e90
Score: 52/100 (M), estimated 60 min, split recommended: true
Affected services/components: repository-wide/unclassified
Machine-readable radar JSONL and SVG
{"actual_change":{"additions":253,"base_sha":"8832bcb92b4eba10a9e8057ac70fbf8f65e66065","binary_files":0,"categories":{"code":3,"configuration":1,"docs":1,"tests":1},"change_digest":"9eecb4a890334247a36d7313c024700e4c7ae7a25e6ca9b21b3bc28dc20f0e90","comparison":"8832bcb92b4eba10a9e8057ac70fbf8f65e66065...9c9b443a44c983e6c99cd2ff134fc10c42091f7a","deletions":21,"file_count":6,"files":["project/ticket-004/README.md","project/ticket-004/intent.json","tests/test_planfile_reporter_dedupe.py","wup/config.py","wup/models/config.py","wup/planfile_reporter.py"],"head_sha":"9c9b443a44c983e6c99cd2ff134fc10c42091f7a","service_count":0,"services":[]},"assessment_mode":"observed-pr","axes":{"coupling":4,"delivery":2,"scope":3,"uncertainty":3,"validation":1},"complexity":"M","confidence":0.9,"diagnostics":["RADAR-ACCEPTANCE-MISSING","RADAR-BUDGET-EXCEEDED"],"estimate":{"budget_minutes":30,"minutes":60,"within_budget":false},"impact":{"components":["connect-scenario","project","tests","wup"],"files":["connect-scenario/probe-latency","project/ticket-004/README.md","project/ticket-004/intent.json","tests/test_planfile_reporter_dedupe.py","wup/config.py","wup/models/config.py","wup/planfile_reporter.py"],"public_interfaces":[],"runtime_dependencies":0},"schema":"subactor.ticket-radar/v1","score":52,"split":{"parts":[{"estimated_minutes":13,"name":"Implement connect-scenario","scope":["connect-scenario"]},{"estimated_minutes":13,"name":"Implement project","scope":["project"]},{"estimated_minutes":13,"name":"Implement tests","scope":["tests"]},{"estimated_minutes":13,"name":"Implement wup","scope":["wup"]},{"estimated_minutes":15,"name":"Validate and project to trackers","scope":["tests","planfile","github/gitlab/jira projections"]}],"reason":"estimated_minutes_exceed_budget","recommended":true},"standards":[{"id":"wellmanifest/dsl","revision":"6c60fc4e0dd1f1bb74f46a7745e28019908d1203","version":"0.1.0-dev"},{"id":"wellmanifest/ticket-lifecycle","revision":"5bf581907a87b46a13a73e6c033d3abe4d9a306f","version":"0.1.0-dev"},{"id":"wellmanifest/git-lifecycle","revision":"7d77d4b7af57e69bc75c3a0290b3a4805c5c4438","version":"0.2.0-dev"},{"id":"wellmanifest/logs","revision":"48c284ef7a069055c0bcb6b900147ce5e65f8b43","version":"0.3.0"}],"ticket_ref":"ticket-004"}<svg xmlns="http://www.w3.org/2000/svg" width="128" height="128" viewBox="0 0 128 128" role="img"><title>ticket-004: [ticket-004] fix(planfile): dedupe WUP incident tickets by failure signature</title><rect width="128" height="128" rx="12" fill="#f8fafc"/><g stroke-width="1"><polygon points="64,55 72,61 69,71 59,71 56,61" fill="none" stroke="#d7dde5"/><polygon points="64,47 80,59 74,78 54,78 48,59" fill="none" stroke="#d7dde5"/><polygon points="64,38 89,56 79,85 49,85 39,56" fill="none" stroke="#d7dde5"/><polygon points="64,30 97,53 84,92 44,92 31,53" fill="none" stroke="#d7dde5"/><polygon points="64,21 105,51 89,99 39,99 23,51" fill="none" stroke="#d7dde5"/><line x1="64" y1="64" x2="64" y2="21" stroke="#aab4c0"/><line x1="64" y1="64" x2="105" y2="51" stroke="#aab4c0"/><line x1="64" y1="64" x2="89" y2="99" stroke="#aab4c0"/><line x1="64" y1="64" x2="39" y2="99" stroke="#aab4c0"/><line x1="64" y1="64" x2="23" y2="51" stroke="#aab4c0"/></g><polygon points="64,38 97,53 79,85 59,71 48,59" fill="#fb923c" fill-opacity="0.45" stroke="#c2410c" stroke-width="2"/><circle cx="64" cy="64" r="3" fill="#c2410c"/><g font-family="sans-serif" font-size="7" fill="#334155"><text x="64" y="11" text-anchor="middle">SCO</text><text x="114" y="48" text-anchor="middle">COU</text><text x="95" y="107" text-anchor="middle">UNC</text><text x="33" y="107" text-anchor="middle">VAL</text><text x="14" y="48" text-anchor="middle">DEL</text></g><text x="64" y="124" text-anchor="middle" font-family="sans-serif" font-size="8" fill="#0f172a">M · 60m</text></svg>DECISION D-004-2557
TICKET ticket-004
HEAD_SHA 9c9b443a44c983e6c99cd2ff134fc10c42091f7a
CORRELATION_ID local-semcod-wup-pr-23-ticket-004
ACTOR agent:ifuri-validator-agent[bot]
APPLIED_RULE P-CORE-015
INPUT author_login = "tom-sapletta-com"
INPUT observed_checks = ["onedev/local-verify=PASS"]
INPUT required_checks = ["onedev/local-verify"]
INPUT required_checks_source = "protected registry (env/request)"
INPUT reviewer_login = "ifuri-validator-agent[bot]"
INPUT semantic_review_assessment = {"schema":"subactor.validator/semantic-review-assessment/v1","subject":{"repository":"semcod/wup","pull_request":23,"head_sha":"9c9b443a44c983e6c99cd2ff134fc10c42091f7a","base_sha":"31a7552b9fb772004cb69e1dea149f4ab00ecf5c","diff_sha256":"b9b7a6576b71163e56dfa3695ca67389921c41b52f75f9da78fdd33f5165959c"},"policy":{"policy_schema":"subactor.validator/semantic-review-policy/v1","policy_version":1,"policy_sha256":"676cb4516bbfed2a000e40b9b1b6e4a430ecc761ec546aeb53d721a1905cfdd7","required":false,"critical_paths":[],"observed_paths":["project/ticket-004/README.md","project/ticket-004/intent.json","tests/test_planfile_reporter_dedupe.py","wup/config.py","wup/models/config.py","wup/planfile_reporter.py"]},"grounding":"full-diff-not-per-finding-proof","execution_authority":false,"status":"not_required","reason":null,"review_sha256":null,"unresolved":[]}
INPUT superseded_checks = []
INPUT ticket_radar_receipt = {"schema":"subactor.ticket-radar/v1","base_sha":"8832bcb92b4eba10a9e8057ac70fbf8f65e66065","head_sha":"9c9b443a44c983e6c99cd2ff134fc10c42091f7a","change_digest":"9eecb4a890334247a36d7313c024700e4c7ae7a25e6ca9b21b3bc28dc20f0e90","score":52,"complexity":"M","estimated_minutes":60,"split_recommended":true,"services":[],"authority":"ADVISORY","promotion":"FORBIDDEN"}
VERDICT APPROVE AUTHORITY DETERMINISTIC
REJECTED REQUEST_CHANGES BECAUSE NO_UNSAFE_CHANGE_REASON_FOUND
ADVISORY llm_verdict = "APPROVE" MODEL "openai/cursor-auto"
ASSERT VERDICT_AUTHORITY != "ADVISORY"
Summary
(service, stage, status)signature, not only the exact message fingerprint — volatile message details (latency values, timestamps) previously spawned sibling tickets for one incident (c2004 registry: 136 fingerprints, 43 forconnect-scenario/probe-latencyalone).planfile.refile_cooldown_seconds(default 24h) measured from the ticket'supdated_at; the observedclosed_atis cached per dedupe entry (terminal statuses are immutable).refile_cooldown_seconds=0restores the previous immediate re-file behaviour; lookup errors remain conservative (unreadable tickets keep muting).Test plan
tests/test_planfile_reporter_dedupe.py— 12 tests, incl. open-sibling mute with different message, cooldown mute, cachedclosed_at, zero-cooldown refile