Skip to content

fix(backlog): transition item to pr_pending when PR created via RunOneShot#160

Merged
tstapler merged 3 commits into
mainfrom
fix/backlog-pr-status-desync-runoneshot
Jul 17, 2026
Merged

fix(backlog): transition item to pr_pending when PR created via RunOneShot#160
tstapler merged 3 commits into
mainfrom
fix/backlog-pr-status-desync-runoneshot

Conversation

@tstapler

Copy link
Copy Markdown
Owner

Summary

Fixes the status-desync bug behind PR #157's linked backlog item being stuck at
review/BOUNCING instead of pr_pending — a backlog item whose PR was created
through the Review Queue's manual "Create PR" button never transitioned status,
making it invisible to ReconcilePRPending's conflict-detection reconciler.
(PR #157 itself was independently closed on 2026-07-17 — its fix had already
landed on main via unrelated commits — verified via gh pr view 157 and
diffing main against the commits cited in that closing comment.)

Context

docs/tasks/backlog-feature-improvement.md traced this exact desync but left
the root cause unidentified: "Not yet root-caused to a specific line; next
step is tracing every write path that sets a backlog item's status to
pr_pending in backlog_service_lifecycle.go."

Root cause: pushAndCreatePR (session/backlog_lifecycle.go) is the only
code path that ever writes pr_pending, and it's reached exclusively via the
automated handleReviewSessionExited(PASS) chain. The Review Queue's manual
"Create PR" button (ReviewQueuePanel.tsx) instead calls
SessionService.RunOneShot, which runs an ad hoc claude -p <prompt> in the
worktree and only ever persists the resulting PR URL onto the session
record (inst.SetGitHubPR) — it has zero knowledge of backlog items. A
backlog-linked item whose PR was created this way stayed in review forever,
accumulating unrelated in_progress<->review bounce churn and eventually
reporting BOUNCING instead of the correct pr_ready_unmerged.

Changes

  • session/backlog_lifecycle.go: new BacklogLifecycleListener.NotifyPRCreatedOutOfBand
    — stores the PR URL/number on the backlog item and transitions
    review -> pr_pending, mirroring pushAndCreatePR's own precondition-guarded
    sequence. No-op if the listener is disabled, the session isn't backlog-linked,
    or the item isn't currently review (so it never fights pushAndCreatePR in
    a race).
  • server/services/session_service.go: RunOneShot now calls
    NotifyPRCreatedOutOfBand after extracting a PR URL from the CLI output.
  • docs/registry/features/backend/session/run-one-shot.json: bumped
    lastModified for the handler change.
  • Tests: 4 new regression tests in session/backlog_lifecycle_test.go
    covering the transition, the non-backlog-session no-op, the
    non-review-status no-op, and the disabled-listener no-op.

Impact

  • Scope: session/backlog_lifecycle.go, server/services/session_service.go.
  • Breaking Changes: none.
  • Performance: negligible — one extra DB lookup only on the RunOneShot
    path when a PR URL was extracted.
  • Dependencies: none.

Testing

  • go test ./session -count=1 — pass
  • go test ./server/services -count=1 — pass
  • go vet ./session/... ./server/services/... — clean
  • golangci-lint run ./session/... ./server/services/... — 0 issues
  • gofmt -l on changed files — clean

Reviewer Notes

  • Focus areas: the precondition guard (ExpectedStatus: review) is what
    keeps this safe under a race with pushAndCreatePR — worth double-checking
    that reasoning.
  • Known limitations: RunOneShot itself still has no direct RPC-level Go
    test (pre-existing gap, docs/registry/features/backend/session/run-one-shot.json
    still shows tested: false) — the new coverage is at the
    NotifyPRCreatedOutOfBand unit level, matching how pushAndCreatePR's own
    regression tests are structured in this file.
  • Follow-up: docs/tasks/backlog-feature-improvement.md's audit trail for
    this bug lives in an unpushed local commit on a separate checkout's main
    branch (not part of this PR's history) — whoever pushes that commit should
    cross-reference this PR.

…d via RunOneShot

The Review Queue's manual "Create PR" button drives SessionService.RunOneShot,
which creates a real PR but only ever persisted the PR URL onto the session
record — it had no knowledge of backlog items at all. pushAndCreatePR (the
automated review-PASS path) is the only other place that writes pr_pending,
so any backlog item whose PR was created via the manual flow was silently
left in "review" forever, invisible to ReconcilePRPending's
FindPRPendingItems query. This is the root cause behind PR #157's linked
backlog item being stuck at status review/BOUNCING instead of pr_pending.

Add BacklogLifecycleListener.NotifyPRCreatedOutOfBand, called from RunOneShot
after a PR URL is extracted, which stores the PR fields and transitions
review -> pr_pending using the same precondition-guarded sequence as
pushAndCreatePR. No-op when the listener is disabled, the session isn't
backlog-linked, or the item isn't currently in review.

4 regression tests cover the transition, the non-backlog-session no-op, the
non-review-status no-op, and the disabled-listener no-op.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

Copy link
Copy Markdown
Contributor

✅ Registry Validation

Registry Validation
===================

Building backend scanner...
Scanning backend features...
Wrote 116 feature files to /tmp/tmp.yaAC0GHkmT/backend
Wrote 14 feature files to /tmp/tmp.yaAC0GHkmT/backend
Wrote 38 feature files to /tmp/tmp.yaAC0GHkmT/backend
Wrote 6 feature files to /tmp/tmp.yaAC0GHkmT/backend
Wrote 10 feature files to /tmp/tmp.yaAC0GHkmT/backend

=== Backend Registry Diff ===
Committed: 172  Generated: 172  Divergence: 0.0%
⚠️  116 feature(s) missing // +api: marker (markerFound: false)

✅ Registry validation passed. Divergence: 0.0%

Test Coverage: 8/172 features have testIds (4.7%)

Divergence > 2% blocks merges. Coverage reporting is advisory only.

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Go Benchmarks (Tier 1)

benchmarks/go/tier1-baseline.txt:98: missing iteration count
benchmarks/go/tier1-baseline.txt:199: missing iteration count
tier1-bench.txt:98: missing iteration count
tier1-bench.txt:198: missing iteration count
goos: linux
goarch: amd64
pkg: github.com/tstapler/stapler-squad/session
cpu: AMD EPYC 7763 64-Core Processor                
                                            │ tier1-bench.txt │
                                            │     sec/op      │
CircularBufferWrite_4KB-4                         82.09n ± 2%
CircularBufferWrite_4KB_Allocs-4                  82.25n ± 1%
CircularBufferGetRecent_4KB-4                     502.4n ± 2%
CircularBufferGetAll-4                            3.972µ ± 2%
GetTimeSinceLastMeaningfulOutput_HotPath-4        65.70n ± 0%
GetTimeSinceLastMeaningfulOutput_ColdPath-4       33.09n ± 0%
geomean                                           175.6n

                                            │ tier1-bench.txt │
                                            │      B/op       │
CircularBufferWrite_4KB-4                        0.000 ± 0%
CircularBufferWrite_4KB_Allocs-4                 0.000 ± 0%
CircularBufferGetRecent_4KB-4                  4.000Ki ± 0%
CircularBufferGetAll-4                         40.00Ki ± 0%
GetTimeSinceLastMeaningfulOutput_HotPath-4       0.000 ± 0%
GetTimeSinceLastMeaningfulOutput_ColdPath-4      0.000 ± 0%
geomean                                                     ¹
¹ summaries must be >0 to compute geomean

                                            │ tier1-bench.txt │
                                            │    allocs/op    │
CircularBufferWrite_4KB-4                        0.000 ± 0%
CircularBufferWrite_4KB_Allocs-4                 0.000 ± 0%
CircularBufferGetRecent_4KB-4                    1.000 ± 0%
CircularBufferGetAll-4                           1.000 ± 0%
GetTimeSinceLastMeaningfulOutput_HotPath-4       0.000 ± 0%
GetTimeSinceLastMeaningfulOutput_ColdPath-4      0.000 ± 0%
geomean                                                     ¹
¹ summaries must be >0 to compute geomean

                              │ tier1-bench.txt │
                              │       B/s       │
CircularBufferWrite_4KB-4          46.47Gi ± 2%
CircularBufferGetRecent_4KB-4      7.593Gi ± 2%
geomean                            18.78Gi

cpu: AMD EPYC 9V74 80-Core Processor                
                                            │ benchmarks/go/tier1-baseline.txt │
                                            │              sec/op              │
CircularBufferWrite_4KB-4                                          62.90n ± 0%
CircularBufferWrite_4KB_Allocs-4                                   62.25n ± 0%
CircularBufferGetRecent_4KB-4                                      459.4n ± 2%
CircularBufferGetAll-4                                             3.196µ ± 2%
GetTimeSinceLastMeaningfulOutput_HotPath-4                         54.41n ± 1%
GetTimeSinceLastMeaningfulOutput_ColdPath-4                        26.77n ± 1%
geomean                                                            142.5n

                                            │ benchmarks/go/tier1-baseline.txt │
                                            │               B/op               │
CircularBufferWrite_4KB-4                                         0.000 ± 0%
CircularBufferWrite_4KB_Allocs-4                                  0.000 ± 0%
CircularBufferGetRecent_4KB-4                                   4.000Ki ± 0%
CircularBufferGetAll-4                                          40.00Ki ± 0%
GetTimeSinceLastMeaningfulOutput_HotPath-4                        0.000 ± 0%
GetTimeSinceLastMeaningfulOutput_ColdPath-4                       0.000 ± 0%
geomean                                                                      ¹
¹ summaries must be >0 to compute geomean

                                            │ benchmarks/go/tier1-baseline.txt │
                                            │            allocs/op             │
CircularBufferWrite_4KB-4                                         0.000 ± 0%
CircularBufferWrite_4KB_Allocs-4                                  0.000 ± 0%
CircularBufferGetRecent_4KB-4                                     1.000 ± 0%
CircularBufferGetAll-4                                            1.000 ± 0%
GetTimeSinceLastMeaningfulOutput_HotPath-4                        0.000 ± 0%
GetTimeSinceLastMeaningfulOutput_ColdPath-4                       0.000 ± 0%
geomean                                                                      ¹
¹ summaries must be >0 to compute geomean

                              │ benchmarks/go/tier1-baseline.txt │
                              │               B/s                │
CircularBufferWrite_4KB-4                           60.65Gi ± 1%
CircularBufferGetRecent_4KB-4                       8.304Gi ± 2%
geomean                                             22.44Gi

pkg: github.com/tstapler/stapler-squad/session/detection/ratelimit
cpu: AMD EPYC 7763 64-Core Processor                
                              │ tier1-bench.txt │
                              │     sec/op      │
StripANSI_PlainText-4               6.876n ± 0%
StripANSI_WithEscapes-4             750.2n ± 1%
ProcessOutput_InactiveState-4       6.330n ± 0%
geomean                             31.96n

                              │ tier1-bench.txt │
                              │      B/op       │
StripANSI_PlainText-4              0.000 ± 0%
StripANSI_WithEscapes-4            136.0 ± 0%
ProcessOutput_InactiveState-4      0.000 ± 0%
geomean                                       ¹
¹ summaries must be >0 to compute geomean

                              │ tier1-bench.txt │
                              │    allocs/op    │
StripANSI_PlainText-4              0.000 ± 0%
StripANSI_WithEscapes-4            5.000 ± 0%
ProcessOutput_InactiveState-4      0.000 ± 0%
geomean                                       ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                              │ benchmarks/go/tier1-baseline.txt │
                              │              sec/op              │
StripANSI_PlainText-4                                5.481n ± 3%
StripANSI_WithEscapes-4                              513.1n ± 1%
ProcessOutput_InactiveState-4                        5.127n ± 0%
geomean                                              24.34n

                              │ benchmarks/go/tier1-baseline.txt │
                              │               B/op               │
StripANSI_PlainText-4                               0.000 ± 0%
StripANSI_WithEscapes-4                             136.0 ± 0%
ProcessOutput_InactiveState-4                       0.000 ± 0%
geomean                                                        ¹
¹ summaries must be >0 to compute geomean

                              │ benchmarks/go/tier1-baseline.txt │
                              │            allocs/op             │
StripANSI_PlainText-4                               0.000 ± 0%
StripANSI_WithEscapes-4                             5.000 ± 0%
ProcessOutput_InactiveState-4                       0.000 ± 0%
geomean                                                        ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/tstapler/stapler-squad/session/queue
cpu: AMD EPYC 7763 64-Core Processor                
                              │ tier1-bench.txt │
                              │     sec/op      │
ReviewQueue_ConcurrentReads-4       84.73n ± 5%
ReviewQueue_Add-4                   507.4n ± 0%
geomean                             207.3n

                              │ tier1-bench.txt │
                              │      B/op       │
ReviewQueue_ConcurrentReads-4      0.000 ± 0%
ReviewQueue_Add-4                  640.0 ± 0%
geomean                                       ¹
¹ summaries must be >0 to compute geomean

                              │ tier1-bench.txt │
                              │    allocs/op    │
ReviewQueue_ConcurrentReads-4      0.000 ± 0%
ReviewQueue_Add-4                  4.000 ± 0%
geomean                                       ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                              │ benchmarks/go/tier1-baseline.txt │
                              │              sec/op              │
ReviewQueue_ConcurrentReads-4                        63.90n ± 0%
ReviewQueue_Add-4                                    396.2n ± 2%
geomean                                              159.1n

                              │ benchmarks/go/tier1-baseline.txt │
                              │               B/op               │
ReviewQueue_ConcurrentReads-4                       0.000 ± 0%
ReviewQueue_Add-4                                   640.0 ± 0%
geomean                                                        ¹
¹ summaries must be >0 to compute geomean

                              │ benchmarks/go/tier1-baseline.txt │
                              │            allocs/op             │
ReviewQueue_ConcurrentReads-4                       0.000 ± 0%
ReviewQueue_Add-4                                   4.000 ± 0%
geomean                                                        ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/tstapler/stapler-squad/session/scrollback
cpu: AMD EPYC 7763 64-Core Processor                
                                      │ tier1-bench.txt │
                                      │     sec/op      │
CircularBuffer_ConcurrentReadWrite-4        3.974µ ± 1%
CircularBuffer_BurstAppend-4                102.6µ ± 1%
CircularBuffer_GetLastN_LargeBuffer-4       21.03µ ± 6%
CircularBuffer_GetRange_Sequential-4        14.43µ ± 5%
CircularBufferAppend-4                      102.3n ± 1%
CircularBufferGetLastN-4                    2.644µ ± 2%
CircularBufferConcurrentAppend-4            128.6n ± 1%
geomean                                     3.304µ

                                      │ tier1-bench.txt │
                                      │      B/op       │
CircularBuffer_ConcurrentReadWrite-4       6.062Ki ± 0%
CircularBuffer_BurstAppend-4               62.50Ki ± 0%
CircularBuffer_GetLastN_LargeBuffer-4      56.00Ki ± 0%
CircularBuffer_GetRange_Sequential-4       28.00Ki ± 0%
CircularBufferAppend-4                       24.00 ± 0%
CircularBufferGetLastN-4                   6.000Ki ± 0%
CircularBufferConcurrentAppend-4             32.00 ± 0%
geomean                                    3.077Ki

                                      │ tier1-bench.txt │
                                      │    allocs/op    │
CircularBuffer_ConcurrentReadWrite-4         2.000 ± 0%
CircularBuffer_BurstAppend-4                1.000k ± 0%
CircularBuffer_GetLastN_LargeBuffer-4        1.000 ± 0%
CircularBuffer_GetRange_Sequential-4         1.000 ± 0%
CircularBufferAppend-4                       1.000 ± 0%
CircularBufferGetLastN-4                     1.000 ± 0%
CircularBufferConcurrentAppend-4             1.000 ± 0%
geomean                                      2.962

                             │ tier1-bench.txt │
                             │       B/s       │
CircularBuffer_BurstAppend-4      595.1Mi ± 2%

cpu: AMD EPYC 9V74 80-Core Processor                
                                      │ benchmarks/go/tier1-baseline.txt │
                                      │              sec/op              │
CircularBuffer_ConcurrentReadWrite-4                        2.819µ ±  3%
CircularBuffer_BurstAppend-4                                83.06µ ±  1%
CircularBuffer_GetLastN_LargeBuffer-4                       15.79µ ±  1%
CircularBuffer_GetRange_Sequential-4                        11.61µ ± 13%
CircularBufferAppend-4                                      84.30n ±  1%
CircularBufferGetLastN-4                                    2.019µ ±  3%
CircularBufferConcurrentAppend-4                            106.6n ±  1%
geomean                                                     2.588µ

                                      │ benchmarks/go/tier1-baseline.txt │
                                      │               B/op               │
CircularBuffer_ConcurrentReadWrite-4                        6.062Ki ± 0%
CircularBuffer_BurstAppend-4                                62.50Ki ± 0%
CircularBuffer_GetLastN_LargeBuffer-4                       56.00Ki ± 0%
CircularBuffer_GetRange_Sequential-4                        28.00Ki ± 0%
CircularBufferAppend-4                                        24.00 ± 0%
CircularBufferGetLastN-4                                    6.000Ki ± 0%
CircularBufferConcurrentAppend-4                              32.00 ± 0%
geomean                                                     3.077Ki

                                      │ benchmarks/go/tier1-baseline.txt │
                                      │            allocs/op             │
CircularBuffer_ConcurrentReadWrite-4                          2.000 ± 0%
CircularBuffer_BurstAppend-4                                 1.000k ± 0%
CircularBuffer_GetLastN_LargeBuffer-4                         1.000 ± 0%
CircularBuffer_GetRange_Sequential-4                          1.000 ± 0%
CircularBufferAppend-4                                        1.000 ± 0%
CircularBufferGetLastN-4                                      1.000 ± 0%
CircularBufferConcurrentAppend-4                              1.000 ± 0%
geomean                                                       2.962

                             │ benchmarks/go/tier1-baseline.txt │
                             │               B/s                │
CircularBuffer_BurstAppend-4                       734.9Mi ± 1%

pkg: github.com/tstapler/stapler-squad/session/tmux
cpu: AMD EPYC 7763 64-Core Processor                
                             │ tier1-bench.txt │
                             │     sec/op      │
StripANSICodes_PlainText-4         6.875n ± 0%
StripANSICodes_WithEscapes-4       697.1n ± 1%
IsBanner_PlainText-4               485.1n ± 0%
geomean                            132.5n

                             │ tier1-bench.txt │
                             │      B/op       │
StripANSICodes_PlainText-4        0.000 ± 0%
StripANSICodes_WithEscapes-4      56.00 ± 0%
IsBanner_PlainText-4              0.000 ± 0%
geomean                                      ¹
¹ summaries must be >0 to compute geomean

                             │ tier1-bench.txt │
                             │    allocs/op    │
StripANSICodes_PlainText-4        0.000 ± 0%
StripANSICodes_WithEscapes-4      4.000 ± 0%
IsBanner_PlainText-4              0.000 ± 0%
geomean                                      ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                             │ benchmarks/go/tier1-baseline.txt │
                             │              sec/op              │
StripANSICodes_PlainText-4                          5.737n ± 0%
StripANSICodes_WithEscapes-4                        476.5n ± 1%
IsBanner_PlainText-4                                363.5n ± 1%
geomean                                             99.79n

                             │ benchmarks/go/tier1-baseline.txt │
                             │               B/op               │
StripANSICodes_PlainText-4                         0.000 ± 0%
StripANSICodes_WithEscapes-4                       56.00 ± 0%
IsBanner_PlainText-4                               0.000 ± 0%
geomean                                                       ¹
¹ summaries must be >0 to compute geomean

                             │ benchmarks/go/tier1-baseline.txt │
                             │            allocs/op             │
StripANSICodes_PlainText-4                         0.000 ± 0%
StripANSICodes_WithEscapes-4                       4.000 ± 0%
IsBanner_PlainText-4                               0.000 ± 0%
geomean                                                       ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/tstapler/stapler-squad/session/tokens
cpu: AMD EPYC 7763 64-Core Processor                
                                   │ tier1-bench.txt │
                                   │     sec/op      │
TokenParser_ProcessUserEntry-4           5.337m ± 2%
DetectCommandsInText/NoSlash-4           7.499n ± 1%
DetectCommandsInText/WithCommand-4       1.661µ ± 1%
geomean                                  4.051µ

                                   │ tier1-bench.txt │
                                   │      B/op       │
TokenParser_ProcessUserEntry-4        11.02Mi ± 0%
DetectCommandsInText/NoSlash-4          0.000 ± 0%
DetectCommandsInText/WithCommand-4      433.0 ± 0%
geomean                                            ¹
¹ summaries must be >0 to compute geomean

                                   │ tier1-bench.txt │
                                   │    allocs/op    │
TokenParser_ProcessUserEntry-4          34.00 ± 0%
DetectCommandsInText/NoSlash-4          0.000 ± 0%
DetectCommandsInText/WithCommand-4      6.000 ± 0%
geomean                                            ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                                   │ benchmarks/go/tier1-baseline.txt │
                                   │              sec/op              │
TokenParser_ProcessUserEntry-4                            4.412m ± 1%
DetectCommandsInText/NoSlash-4                            5.183n ± 5%
DetectCommandsInText/WithCommand-4                        1.171µ ± 1%
geomean                                                   2.992µ

                                   │ benchmarks/go/tier1-baseline.txt │
                                   │               B/op               │
TokenParser_ProcessUserEntry-4                         11.02Mi ± 0%
DetectCommandsInText/NoSlash-4                           0.000 ± 0%
DetectCommandsInText/WithCommand-4                       433.0 ± 0%
geomean                                                             ¹
¹ summaries must be >0 to compute geomean

                                   │ benchmarks/go/tier1-baseline.txt │
                                   │            allocs/op             │
TokenParser_ProcessUserEntry-4                           34.00 ± 0%
DetectCommandsInText/NoSlash-4                           0.000 ± 0%
DetectCommandsInText/WithCommand-4                       6.000 ± 0%
geomean                                                             ¹
¹ summaries must be >0 to compute geomean

pkg: github.com/tstapler/stapler-squad/session/unfinished
cpu: AMD EPYC 7763 64-Core Processor                
                               │ tier1-bench.txt │
                               │     sec/op      │
DiffShortstat/GitVCSReader-4         3.193m ± 1%
DiffShortstat/GoGitVCSReader-4       77.00n ± 0%
DiffShortstatCached-4                78.78n ± 2%
geomean                              2.685µ

                               │ tier1-bench.txt │
                               │      B/op       │
DiffShortstat/GitVCSReader-4      56.57Ki ± 0%
DiffShortstat/GoGitVCSReader-4      0.000 ± 0%
DiffShortstatCached-4               0.000 ± 0%
geomean                                        ¹
¹ summaries must be >0 to compute geomean

                               │ tier1-bench.txt │
                               │    allocs/op    │
DiffShortstat/GitVCSReader-4        360.0 ± 0%
DiffShortstat/GoGitVCSReader-4      0.000 ± 0%
DiffShortstatCached-4               0.000 ± 0%
geomean                                        ¹
¹ summaries must be >0 to compute geomean

cpu: AMD EPYC 9V74 80-Core Processor                
                               │ benchmarks/go/tier1-baseline.txt │
                               │              sec/op              │
DiffShortstat/GitVCSReader-4                          2.687m ± 2%
DiffShortstat/GoGitVCSReader-4                        62.82n ± 2%
DiffShortstatCached-4                                 64.21n ± 1%
geomean                                               2.213µ

                               │ benchmarks/go/tier1-baseline.txt │
                               │               B/op               │
DiffShortstat/GitVCSReader-4                       56.58Ki ± 0%
DiffShortstat/GoGitVCSReader-4                       0.000 ± 0%
DiffShortstatCached-4                                0.000 ± 0%
geomean                                                         ¹
¹ summaries must be >0 to compute geomean

                               │ benchmarks/go/tier1-baseline.txt │
                               │            allocs/op             │
DiffShortstat/GitVCSReader-4                         360.0 ± 0%
DiffShortstat/GoGitVCSReader-4                       0.000 ± 0%
DiffShortstatCached-4                                0.000 ± 0%
geomean                                                         ¹
¹ summaries must be >0 to compute geomean

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

E2E RPC Latency

list-sessions-ttfb-mean: 9ms (▲ slower +50.6%; baseline: 6ms)
list-sessions-total-mean: 13ms (▲ slower +62.7%; baseline: 8ms)

…OfBand

Four-agent parallel code review (testing, code quality, architecture,
security) on the prior commit surfaced:

- Testing: the resolveStuckLogged side effect (clearing a stale
  abandoned_review row) was never actually exercised by any of the 4 new
  tests. Added TestRecordPRCreatedOutOfBand_ClearsAbandonedReviewStuckReason_
  WhenItemWasStuck, which marks an item stuck first and asserts the row is
  gone afterward.
- Code quality: extracted the identical transition+resolve-stuck tail shared
  by pushAndCreatePR and the new method into resolveToPRPending, removing
  the duplication. Also renamed NotifyPRCreatedOutOfBand ->
  RecordPRCreatedOutOfBand — "Notify" collided in spirit with the existing
  l.notify() toast helper in this file, but this method mutates DB state,
  it doesn't just surface a message.
- Code quality (concurrency): the doc comment overstated
  TransitionBacklogItemStatus's guarantee as "exactly one of two racing
  calls wins" — verified against session/ent_repository_backlog.go and it's
  actually a read-then-write with no WHERE-clause CAS, so both could
  succeed under a true race (harmless here since both write the same
  target state, but the comment was wrong). Corrected the wording.
- Security: added workSessionUUID to the success log line so an operator
  can trace which session caused a given transition.

Not fixed here (documented in the method's doc comment as known
limitations, consistent with this codebase's existing pattern of tracking
follow-ups rather than scope-creeping a bug fix): this path doesn't call
EnablePRAutoMerge like pushAndCreatePR does (no worktree handle available),
and prURL/prNumber come from unverified freeform LLM stdout parsing
(extractPRURL) rather than a GitHub-verified check — acceptable for this
single-operator tool's threat model today.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

🎬 E2E Feature Demos

2 shard(s) recorded feature flows for this PR.

recordings shard 1
recordings shard 2

Demo preview opens directly in browser (single-file HTML). Raw WebM recordings in ZIP. Expires after 30 days.

@github-actions

Copy link
Copy Markdown
Contributor

✅ Registry Validation

Registry Validation
===================

Building backend scanner...
Scanning backend features...
Wrote 116 feature files to /tmp/tmp.23MKO7dKeX/backend
Wrote 14 feature files to /tmp/tmp.23MKO7dKeX/backend
Wrote 38 feature files to /tmp/tmp.23MKO7dKeX/backend
Wrote 6 feature files to /tmp/tmp.23MKO7dKeX/backend
Wrote 10 feature files to /tmp/tmp.23MKO7dKeX/backend

=== Backend Registry Diff ===
Committed: 172  Generated: 172  Divergence: 0.0%
⚠️  116 feature(s) missing // +api: marker (markerFound: false)

✅ Registry validation passed. Divergence: 0.0%

Test Coverage: 8/172 features have testIds (4.7%)

Divergence > 2% blocks merges. Coverage reporting is advisory only.

@github-actions

github-actions Bot commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Frontend Terminal Throughput

terminal-throughput-mean: 14 KB/s ▼ -12.1% (baseline: 16 KB/s)
terminal-throughput-p50: 16 KB/s ▼ -0.2% (baseline: 16 KB/s)

@github-actions

Copy link
Copy Markdown
Contributor

✅ Registry Validation

Registry Validation
===================

Building backend scanner...
Scanning backend features...
Wrote 116 feature files to /tmp/tmp.zU8qx4Dtsd/backend
Wrote 14 feature files to /tmp/tmp.zU8qx4Dtsd/backend
Wrote 38 feature files to /tmp/tmp.zU8qx4Dtsd/backend
Wrote 6 feature files to /tmp/tmp.zU8qx4Dtsd/backend
Wrote 10 feature files to /tmp/tmp.zU8qx4Dtsd/backend

=== Backend Registry Diff ===
Committed: 172  Generated: 172  Divergence: 0.0%
⚠️  111 feature(s) missing // +api: marker (markerFound: false)

✅ Registry validation passed. Divergence: 0.0%

Test Coverage: 8/172 features have testIds (4.7%)

Divergence > 2% blocks merges. Coverage reporting is advisory only.

@github-actions

Copy link
Copy Markdown
Contributor

📊 Feature E2E Coverage

Feature coverage report unavailable

Run make e2e-report locally to view the full Allure report.

@tstapler
tstapler merged commit 0fd35e7 into main Jul 17, 2026
22 checks passed
@tstapler
tstapler deleted the fix/backlog-pr-status-desync-runoneshot branch July 17, 2026 11:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant