[BUG] Multiple repeat responses eating tokens and destroying conversation context
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Using 'claude' in VS Code Intergrated terminal (same thing happens in iTerm2)
Send a prompt.
Get back the same response multiple times.
What Should Happen?
Receive only 1 response.
Error Messages/Logs
Steps to Reproduce
Here is a good example of a conversation, it could be anything, all the repeats come at once, and stop at the end.
Two separate problems here — the sandcastle state-machine bug, and #141 still failing QA. Filing the
state-machine issue and adding evidence to #141.
⏺ Bash(gh issue comment 141 --body "QA failed. After the changes for this issue were committed, restarting
the dev environment and opening \/dashboard/schedule\ stil…)
⎿ https://github.com/mac/venue/issues/141#issuecomment-432689
⏺ Write(/tmp/issue-sandcastle-qa-bounce.md)
─────────────────────────────────────────────────────────────────────────────────────────────────────────────
Create file
../../../../../../tmp/issue-sandcastle-qa-bounce.md
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
1 ## What happened
2
3 When a QA reviewer fails an issue and moves it back from QA to Approved (leaving a comment explaining
the failure), the sandcastle state machine driven by .sandcastle/main.mts keeps re-promoting the i
ssue back to QA on its own. It appears to infer "the issue has commits associated with it, therefore
it must be done" and ignores the QA reviewer's explicit demotion.
4
5 Concrete example: issue #141 was moved back to Approved with a failing-QA comment, and within the nex
t sandcastle cycle it jumped back to QA without any new work being done.
6
7 ## What I expected
8
9 - An issue's status is authoritative when set by a human reviewer. If a human moves an issue from QA
→ Approved with a failing-QA comment (or a qa-failed style label/marker), the state machine must tr
eat that as "go re-do the work", not "you already did it".
10 - The state machine should not infer "done" purely from the presence of commits. It should look at th
e issue status + the most recent QA verdict (comment marker or label) to decide what's next.
11 - A QA failure should kick the issue back into the implement/review loop with the failure comment as
input, not silently flip it back to QA.
12
13 ## Steps to reproduce
14
15 1. Find an issue currently in QA (e.g. #141 was the trigger).
16 2. Add a comment explaining why QA failed.
17 3. Move the issue from QA back to Approved manually.
18 4. Wait for the next sandcastle cycle.
19 5. Observe the issue gets bumped back to QA again, even though no new implementer work has happened.
20
21 ## Additional context
22
23 - The decision logic in .sandcastle/main.mts (and supporting prompts in .sandcastle/prompts/) nee
ds an explicit "QA-failed" branch: when the most recent QA verdict on an issue is a failure, route th
e issue to the implementer (or back to ready-for-agent), not back to QA.
24 - A reviewer-facing convention would help here too — e.g. a qa-failed label or a comment prefix lik
e QA FAILED: — so the state machine has an unambiguous signal rather than having to interpret free-
form comments.
25 - Without this fix, every QA failure becomes an infinite ping-pong between Approved and QA, and the h
uman reviewer has no way to make their verdict stick.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Do you want to create issue-sandcastle-qa-bounce.md?
❯ 1. Yes
- Yes, allow all edits in tmp/ during this session (shift+tab)
- No
Esc to cancel · Tab to amend
16 2. Add a comment explaining why QA failed.
17 3. Move the issue from QA back to Approved manually.
18 4. Wait for the next sandcastle cycle.
19 5. Observe the issue gets bumped back to QA again, even though no new implementer work has happened.
20
21 ## Additional context
22
23 - The decision logic in .sandcastle/main.mts (and supporting prompts in .sandcastle/prompts/) nee
ds an explicit "QA-failed" branch: when the most recent QA verdict on an issue is a failure, route th
e issue to the implementer (or back to ready-for-agent), not back to QA.
24 - A reviewer-facing convention would help here too — e.g. a qa-failed label or a comment prefix lik
e QA FAILED: — so the state machine has an unambiguous signal rather than having to interpret free-
form comments.
25 - Without this fix, every QA failure becomes an infinite ping-pong between Approved and QA, and the h
uman reviewer has no way to make their verdict stick.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Do you want to create issue-sandcastle-qa-bounce.md?
❯ 1. Yes
- Yes, allow all edits in tmp/ during this session (shift+tab)
- No
Esc to cancel · Tab to amend
15 1. Find an issue currently in QA (e.g. #141 was the trigger).
16 2. Add a comment explaining why QA failed.
17 3. Move the issue from QA back to Approved manually.
18 4. Wait for the next sandcastle cycle.
19 5. Observe the issue gets bumped back to QA again, even though no new implementer work has happened.
20
21 ## Additional context
22
23 - The decision logic in .sandcastle/main.mts (and supporting prompts in .sandcastle/prompts/) nee
ds an explicit "QA-failed" branch: when the most recent QA verdict on an issue is a failure, route th
e issue to the implementer (or back to ready-for-agent), not back to QA.
24 - A reviewer-facing convention would help here too — e.g. a qa-failed label or a comment prefix lik
e QA FAILED: — so the state machine has an unambiguous signal rather than having to interpret free-
form comments.
25 - Without this fix, every QA failure becomes an infinite ping-pong between Approved and QA, and the h
uman reviewer has no way to make their verdict stick.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Do you want to create issue-sandcastle-qa-bounce.md?
❯ 1. Yes
- Yes, allow all edits in tmp/ during this session (shift+tab)
- No
Esc to cancel · Tab to amend
14
15 1. Find an issue currently in QA (e.g. #141 was the trigger).
16 2. Add a comment explaining why QA failed.
17 3. Move the issue from QA back to Approved manually.
18 4. Wait for the next sandcastle cycle.
19 5. Observe the issue gets bumped back to QA again, even though no new implementer work has happened.
20
21 ## Additional context
22
23 - The decision logic in .sandcastle/main.mts (and supporting prompts in .sandcastle/prompts/) nee
ds an explicit "QA-failed" branch: when the most recent QA verdict on an issue is a failure, route th
e issue to the implementer (or back to ready-for-agent), not back to QA.
24 - A reviewer-facing convention would help here too — e.g. a qa-failed label or a comment prefix lik
e QA FAILED: — so the state machine has an unambiguous signal rather than having to interpret free-
form comments.
25 - Without this fix, every QA failure becomes an infinite ping-pong between Approved and QA, and the h
uman reviewer has no way to make their verdict stick.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Do you want to create issue-sandcastle-qa-bounce.md?
❯ 1. Yes
- Yes, allow all edits in tmp/ during this session (shift+tab)
- No
Esc to cancel · Tab to amend
13 ## Steps to reproduce
14
15 1. Find an issue currently in QA (e.g. #141 was the trigger).
16 2. Add a comment explaining why QA failed.
17 3. Move the issue from QA back to Approved manually.
18 4. Wait for the next sandcastle cycle.
19 5. Observe the issue gets bumped back to QA again, even though no new implementer work has happened.
20
21 ## Additional context
22
23 - The decision logic in .sandcastle/main.mts (and supporting prompts in .sandcastle/prompts/) nee
ds an explicit "QA-failed" branch: when the most recent QA verdict on an issue is a failure, route th
e issue to the implementer (or back to ready-for-agent), not back to QA.
24 - A reviewer-facing convention would help here too — e.g. a qa-failed label or a comment prefix lik
e QA FAILED: — so the state machine has an unambiguous signal rather than having to interpret free-
form comments.
25 - Without this fix, every QA failure becomes an infinite ping-pong between Approved and QA, and the h
uman reviewer has no way to make their verdict stick.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Do you want to create issue-sandcastle-qa-bounce.md?
❯ 1. Yes
- Yes, allow all edits in tmp/ during this session (shift+tab)
- No
Esc to cancel · Tab to amend
12
13 ## Steps to reproduce
14
15 1. Find an issue currently in QA (e.g. #141 was the trigger).
16 2. Add a comment explaining why QA failed.
17 3. Move the issue from QA back to Approved manually.
18 4. Wait for the next sandcastle cycle.
19 5. Observe the issue gets bumped back to QA again, even though no new implementer work has happened.
20
21 ## Additional context
22
23 - The decision logic in .sandcastle/main.mts (and supporting prompts in .sandcastle/prompts/) nee
ds an explicit "QA-failed" branch: when the most recent QA verdict on an issue is a failure, route th
e issue to the implementer (or back to ready-for-agent), not back to QA.
24 - A reviewer-facing convention would help here too — e.g. a qa-failed label or a comment prefix lik
e QA FAILED: — so the state machine has an unambiguous signal rather than having to interpret free-
form comments.
25 - Without this fix, every QA failure becomes an infinite ping-pong between Approved and QA, and the h
uman reviewer has no way to make their verdict stick.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Do you want to create issue-sandcastle-qa-bounce.md?
❯ 1. Yes
- Yes, allow all edits in tmp/ during this session (shift+tab)
- No
Esc to cancel · Tab to amend
input, not silently flip it back to QA.
12
13 ## Steps to reproduce
14
15 1. Find an issue currently in QA (e.g. #141 was the trigger).
16 2. Add a comment explaining why QA failed.
17 3. Move the issue from QA back to Approved manually.
18 4. Wait for the next sandcastle cycle.
19 5. Observe the issue gets bumped back to QA again, even though no new implementer work has happened.
20
21 ## Additional context
22
23 - The decision logic in .sandcastle/main.mts (and supporting prompts in .sandcastle/prompts/) nee
ds an explicit "QA-failed" branch: when the most recent QA verdict on an issue is a failure, route th
e issue to the implementer (or back to ready-for-agent), not back to QA.
24 - A reviewer-facing convention would help here too — e.g. a qa-failed label or a comment prefix lik
e QA FAILED: — so the state machine has an unambiguous signal rather than having to interpret free-
form comments.
25 - Without this fix, every QA failure becomes an infinite ping-pong between Approved and QA, and the h
uman reviewer has no way to make their verdict stick.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Do you want to create issue-sandcastle-qa-bounce.md?
❯ 1. Yes
- Yes, allow all edits in tmp/ during this session (shift+tab)
- No
Esc to cancel · Tab to amend
11 - A QA failure should kick the issue back into the implement/review loop with the failure comment as
input, not silently flip it back to QA.
12
13 ## Steps to reproduce
14
15 1. Find an issue currently in QA (e.g. #141 was the trigger).
16 2. Add a comment explaining why QA failed.
17 3. Move the issue from QA back to Approved manually.
18 4. Wait for the next sandcastle cycle.
19 5. Observe the issue gets bumped back to QA again, even though no new implementer work has happened.
20
21 ## Additional context
22
23 - The decision logic in .sandcastle/main.mts (and supporting prompts in .sandcastle/prompts/) nee
ds an explicit "QA-failed" branch: when the most recent QA verdict on an issue is a failure, route th
e issue to the implementer (or back to ready-for-agent), not back to QA.
24 - A reviewer-facing convention would help here too — e.g. a qa-failed label or a comment prefix lik
e QA FAILED: — so the state machine has an unambiguous signal rather than having to interpret free-
form comments.
25 - Without this fix, every QA failure becomes an infinite ping-pong between Approved and QA, and the h
uman reviewer has no way to make their verdict stick.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Do you want to create issue-sandcastle-qa-bounce.md?
❯ 1. Yes
- Yes, allow all edits in tmp/ during this session (shift+tab)
- No
Esc to cancel · Tab to amend
e issue status + the most recent QA verdict (comment marker or label) to decide what's next.
11 - A QA failure should kick the issue back into the implement/review loop with the failure comment as
input, not silently flip it back to QA.
12
13 ## Steps to reproduce
14
15 1. Find an issue currently in QA (e.g. #141 was the trigger).
16 2. Add a comment explaining why QA failed.
17 3. Move the issue from QA back to Approved manually.
18 4. Wait for the next sandcastle cycle.
19 5. Observe the issue gets bumped back to QA again, even though no new implementer work has happened.
20
21 ## Additional context
22
23 - The decision logic in .sandcastle/main.mts (and supporting prompts in .sandcastle/prompts/) nee
ds an explicit "QA-failed" branch: when the most recent QA verdict on an issue is a failure, route th
e issue to the implementer (or back to ready-for-agent), not back to QA.
24 - A reviewer-facing convention would help here too — e.g. a qa-failed label or a comment prefix lik
e QA FAILED: — so the state machine has an unambiguous signal rather than having to interpret free-
form comments.
25 - Without this fix, every QA failure becomes an infinite ping-pong between Approved and QA, and the h
uman reviewer has no way to make their verdict stick.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Do you want to create issue-sandcastle-qa-bounce.md?
❯ 1. Yes
- Yes, allow all edits in tmp/ during this session (shift+tab)
- No
Esc to cancel · Tab to amend
10 - The state machine should not infer "done" purely from the presence of commits. It should look at th
e issue status + the most recent QA verdict (comment marker or label) to decide what's next.
11 - A QA failure should kick the issue back into the implement/review loop with the failure comment as
input, not silently flip it back to QA.
12
13 ## Steps to reproduce
14
15 1. Find an issue currently in QA (e.g. #141 was the trigger).
16 2. Add a comment explaining why QA failed.
17 3. Move the issue from QA back to Approved manually.
18 4. Wait for the next sandcastle cycle.
19 5. Observe the issue gets bumped back to QA again, even though no new implementer work has happened.
20
21 ## Additional context
22
23 - The decision logic in .sandcastle/main.mts (and supporting prompts in .sandcastle/prompts/) nee
ds an explicit "QA-failed" branch: when the most recent QA verdict on an issue is a failure, route th
e issue to the implementer (or back to ready-for-agent), not back to QA.
24 - A reviewer-facing convention would help here too — e.g. a qa-failed label or a comment prefix lik
e QA FAILED: — so the state machine has an unambiguous signal rather than having to interpret free-
form comments.
25 - Without this fix, every QA failure becomes an infinite ping-pong between Approved and QA, and the h
uman reviewer has no way to make their verdict stick.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Do you want to create issue-sandcastle-qa-bounce.md?
❯ 1. Yes
- Yes, allow all edits in tmp/ during this session (shift+tab)
- No
Esc to cancel · Tab to amend
eat that as "go re-do the work", not "you already did it".
10 - The state machine should not infer "done" purely from the presence of commits. It should look at th
e issue status + the most recent QA verdict (comment marker or label) to decide what's next.
11 - A QA failure should kick the issue back into the implement/review loop with the failure comment as
input, not silently flip it back to QA.
12
13 ## Steps to reproduce
14
15 1. Find an issue currently in QA (e.g. #141 was the trigger).
16 2. Add a comment explaining why QA failed.
17 3. Move the issue from QA back to Approved manually.
18 4. Wait for the next sandcastle cycle.
19 5. Observe the issue gets bumped back to QA again, even though no new implementer work has happened.
20
21 ## Additional context
22
23 - The decision logic in .sandcastle/main.mts (and supporting prompts in .sandcastle/prompts/) nee
ds an explicit "QA-failed" branch: when the most recent QA verdict on an issue is a failure, route th
e issue to the implementer (or back to ready-for-agent), not back to QA.
24 - A reviewer-facing convention would help here too — e.g. a qa-failed label or a comment prefix lik
e QA FAILED: — so the state machine has an unambiguous signal rather than having to interpret free-
form comments.
25 - Without this fix, every QA failure becomes an infinite ping-pong between Approved and QA, and the h
uman reviewer has no way to make their verdict stick.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Do you want to create issue-sandcastle-qa-bounce.md?
❯ 1. Yes
- Yes, allow all edits in tmp/ during this session (shift+tab)
- No
Esc to cancel · Tab to amend
→ Approved with a failing-QA comment (or a qa-failed style label/marker), the state machine must tr
eat that as "go re-do the work", not "you already did it".
10 - The state machine should not infer "done" purely from the presence of commits. It should look at th
e issue status + the most recent QA verdict (comment marker or label) to decide what's next.
11 - A QA failure should kick the issue back into the implement/review loop with the failure comment as
input, not silently flip it back to QA.
12
13 ## Steps to reproduce
14
15 1. Find an issue currently in QA (e.g. #141 was the trigger).
16 2. Add a comment explaining why QA failed.
17 3. Move the issue from QA back to Approved manually.
18 4. Wait for the next sandcastle cycle.
19 5. Observe the issue gets bumped back to QA again, even though no new implementer work has happened.
20
21 ## Additional context
22
23 - The decision logic in .sandcastle/main.mts (and supporting prompts in .sandcastle/prompts/) nee
ds an explicit "QA-failed" branch: when the most recent QA verdict on an issue is a failure, route th
e issue to the implementer (or back to ready-for-agent), not back to QA.
24 - A reviewer-facing convention would help here too — e.g. a qa-failed label or a comment prefix lik
e QA FAILED: — so the state machine has an unambiguous signal rather than having to interpret free-
form comments.
25 - Without this fix, every QA failure becomes an infinite ping-pong between Approved and QA, and the h
uman reviewer has no way to make their verdict stick.
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌
Do you want to create issue-sandcastle-qa-bounce.md?
❯ 1. Yes
- Yes, allow all edits in tmp/ during this session (shift+tab)
- No
Claude Model
Opus
Is this a regression?
I don't know
Last Working Version
_No response_
Claude Code Version
2.1.119
Platform
Anthropic API
Operating System
macOS
Terminal/Shell
VS Code integrated terminal
Additional Information
_No response_
This issue has 8 comments on GitHub. Read the full discussion on GitHub ↗