feat(MAPCO-11432): count an attempt when a ticket is handed back - #9
Open
razbroc wants to merge 1 commit into
Open
feat(MAPCO-11432): count an attempt when a ticket is handed back#9razbroc wants to merge 1 commit into
razbroc wants to merge 1 commit into
Conversation
Adds `JiraPort.setLabels` and `handBackTicket`, the one binding both `AbortPort` (MAPCO-11435) and `ReleasePort` (MAPCO-11434) are meant to use. The attempt counter is the only thing that ends a loop. The poll filters on agent-ready, an empty assignee and the label at ATTEMPT_CAP, so a ticket handed back without a bumped counter matches again on the next tick, is claimed again and is paid for again. Nothing could write that label before this. Counting happens before releasing, which is the reverse of how it reads. Unassigning is what makes a ticket visible to the poll and it is the last thing releaseTicket does, so the counter has to already be there. A label write that fails therefore stops the hand-back: held and In Progress is recovered by the boot-time orphan sweep, whereas available and uncounted is a re-burn loop. `setLabels` overwrites the whole set, so callers pass what they want kept. `countAttempt` clamps at the cap — writing past it would make the ticket pollable again rather than tightening anything.
|
🎫 Related Jira Issue: MAPCO-11432 |
8 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #8 — review that first, and this PR retargets as the stack merges.
This is the attempt-counter half of MAPCO-11432 only. The boot-time orphan release is not here. It is split out because both MAPCO-11434 and MAPCO-11435 are blocked on it: each defines a port (
ReleasePort,AbortPort) whose contract is "release and count", and nothing in the repository could write that label.Adds
JiraPort.setLabelsandhandBackTicket— the one binding both ports are meant to use, so there is one implementation rather than two that drift.Why the counter is load-bearing
buildPollQueryfilters onagent-ready, an empty assignee, and the label atATTEMPT_CAP. So a ticket handed back without a bumped counter matches the poll again on the very next tick, is claimed again, and is paid for again — one ticket able to eat the whole daily allowance.ATTEMPT_CAPcannot express "tried twice" unless something writes it down, and until this PR nothing could.Unassigning is what makes a ticket visible to the poll, and it is the last thing
releaseTicketdoes. So the counter has to already be on the ticket before that happens. Counting afterwards leaves a window where the ticket is available and uncounted, and if the count then fails the window never closes.Which means a failed label write stops the hand-back entirely. The ticket stays held by the bot and In Progress, which the poll query skips, and the boot-time orphan sweep is what recovers it. Held-and-uncounted is recoverable; available-and-uncounted is a re-burn loop. There is a test asserting the write order is exactly
labels → comment → transition → assign, and another asserting that a failing label write produces no Jira writes at all.releaseTicketitself is unchanged and still does not count — it is also the release used by paths that must not, like the hand-straight-back inrunCycle, which does no work and spends nothing.Two sharp edges in the label write
setLabelsoverwrites the whole set. That is whatjira_update_issueoffers, and the caller has to have read the existing labels anyway to compute the next counter. The consequence: anything absent from the array is removed, so a caller must pass what it wants kept.countAttemptpreserves every non-counter label,agent-readyincluded — enrolment is a human's decision and an overspend is not a reason to revoke it.countAttemptclamps at the cap. Writingagent-attempted-3on a ticket already at a cap of 2 would not tighten anything — the query excludes the label exactly at the cap, so a higher number would make the ticket poll-visible again and hand it straight back to the worker for ever. A ticket at the cap is already invisible, so leaving its counter where it is loses nothing.fieldsis a JSON string, likeassigneeFields— passing an object updates nothing and still reports success, which is why it is its own named, tested function.Acceptance criteria (MAPCO-11432)
constants.tsandattempt.ts; the operator-facing JQL is not in the README yet.Follow-up
The boot-time orphan release is now unblocked — it needs the sweep at process start plus a seam test, and this PR gives it the label write it depends on.
Refs: MAPCO-11432