The run's PR TITLE names what it delivers, not the run id — the shared parent when there is one
sessionPrTitle produces Motir auto run 20260807-141522 — 4 work items.
A title is read in a LIST — the repo's open pull requests, a notification, a review queue — where it is the only thing shown and its whole job is to help someone decide whether to open it. This one says a machine did something, four times. It is unreadable in exactly the place a title is read.
The body was fixed by 11.5.27, which assembles it from the agents' commits. The title was scoped out of that card because it needs something the loop does not have.
⚠️ RE-SCOPED 2026-08-08 — the parent SOURCE is settled, and it is not a read this card makes.
⚠️ CORRECTION, 2026-08-08 (later, mid-
motir runon MOTIR-2446): the re-scope's stated JUSTIFICATION below was FALSE. Its OUTCOME stands and this card is unchanged by the correction. A bulk read did exist:WorkItemRefcarriesparentKey(lib/api/v1/workItems/schema.ts→workItemRefSchema) and is returned as a page byGET /api/v1/sprints/{sprintId}/work-itemsandGET /api/v1/projects/{projectKey}/backlog(RankedPageEnvelope & { items: WorkItemRef[] }), both onorigin/mainsince 2026-08-04 (94a65035#1814,1d7b7780#1819), withlistSprintWorkItemsalready bound in the CLI client. So the ORIGINAL criterion was satisfiable at one request per run. The re-plan reached the right answer anyway — the dispatch-prompt route costs zero requests, cheaper than the sprint listing — so nothing here needs redoing. The false clause is preserved below as the record of what was believed; see MOTIR-2446 andnotes.html#243.
The original acceptance criterion was "the parent read happens ONCE per run at close-out, asserted on the request count". No such read exists.(struck:parentKeyis on three generated components and every operation returning one is addressed by a single{key}; the three collection rows a loop could read in bulk (ReadyItem,WorkItemSummary, the search page) all omit it. Parents for a four-card run is four requests.WorkItemRefis itself one of the bulk rows — see the correction above.)So the source moved: MOTIR-2445 puts
parentKeyonDispatchPromptDto— where the server already resolves it and already renders it as prose — and this card reads it off the prompt it ALREADY fetches per item. The request cost is zero, and the criterion below is restated to say so. That remains the best available route (it beats the sprint listing on cost), which is why the correction above changes nothing about this card.The rejected alternatives, for the record: reading
getWorkItemper carried card taxes every run with a request per item to build a string; regexing the prompt's- Parent:line costs nothing but couples the CLI to prose the server may rewrite, degrading every title to the fallback with nothing failing.
What to build
When every card the run carried shares a PARENT, name it: MOTIR-1855 · @motir/cli migrates onto /api/v1 — 4 work items, or whatever shape reads best in a list. When they do not share one — a run that drained across several stories — fall back to today's form, because a title that names one of four parents is worse than one that names none.
The parent for each carried card is dispatch.parentKey, already in hand: dispatchOne receives the DispatchPrompt and the loop keeps a record per item. Carry it onto DispatchRecord and let sessionPrTitle decide from the set.
Scope BOUNDARY
sessionPrTitle, DispatchRecord, and the one line that carries parentKey from the prompt into it. It does NOT change the body (11.5.27's). It does NOT change closeOutRepos' orchestration or the gh pr create helper. It does NOT add or read any endpoint — MOTIR-2445 ships the field and this card consumes it. It does NOT add a field to any collection row.
Acceptance criteria
- A run whose cards share a parent produces a title naming that parent, asserted.
- A run whose cards span several parents falls back to today's form, asserted — the mixed case is the one a naive implementation gets wrong by naming the first card's parent.
- A run carrying a single card names that card, not its parent: for one item the card IS the deliverable.
- The title costs NO additional request. The parent arrives on the dispatch prompt the loop already fetches per item — asserted on the request count, which must be unchanged from a run before this card. (This criterion names its operation:
GET /api/v1/work-items/{key}/dispatch-prompt→DispatchPrompt.parentKey, already fetched per item. That citation is what the original criterion lacked.) - A card whose
parentKeyisnull(a top-level item in the set) collapses the run to the fallback form rather than being ignored — a set containing an unparented card does not "share a parent". - The title stays within a length a list renders without truncation mattering — state the budget in the code rather than discovering it in GitHub's UI.
Context refs
packages/cli/src/autoLoop.ts—sessionPrTitle;DispatchRecordfor what the run carried.packages/cli/src/commands/auto.ts—dispatchOne(holds theDispatchPrompt),closeOutRepos.- MOTIR-2445 — the field this reads; blocks this card.
- MOTIR-2446 — the planning-bug record, and the correction to this note's justification.
- 11.5.27 — the body; this card is its counterpart and they should read as one artefact.
- Story: MOTIR-1855.