feat(jobs): a resumed job does not re-send what it delivered #746
No reviewers
Labels
No labels
move-to-repo
coilyco-bridge-deploy
move-to-repo
coilyco-flight-deck-agent-compose
move-to-repo
coilyco-gaming-eco-app
move-to-repo
coilysiren-inbox
move-to-repo
unknown
🔒⚠️📦⚠️🔒 SANDBOXED 🔒⚠️📦⚠️🔒
autonomy
async-consult
autonomy
epic
autonomy
headless
autonomy
live-collab
c#
priority
P0
priority
P1
priority
P2
priority
P3
priority
P4
role/ai
role/creator
role/design
role/director
role/engineer
role/exec
role/human
role/ops
role/qa
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
coilyco-gaming/sirens-echo!746
Loading…
Reference in a new issue
No description provided.
Delete branch "feat/an-emitted-message-is-not-emitted-twice"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
RecordEffectandEffectAppliedhad no production caller, sojob.Effectswas empty for every job that ran and a re-execution repeated everything. That was harmless while a job's only output was a status line. It stopped being harmless when #356 and #742 gave a job ten ordered messages to say.A job that emits ten messages and then resumes emits some of them twice, and the member reads the same paragraph again.
What ships
Each message records an effect keyed by position,
content:N. A re-execution checks before sending and skips what was delivered.The effect is recorded after the send, deliberately. Recording first would skip a message the origin never received, and a truncated answer is worse than a repeated paragraph.
TestAFailedSendRecordsNoEffectholds that, and reversing the order fails it.A replay still delivers what the first run did not reach, so a crash mid-answer is resumed rather than frozen.
What it does not do, which matters for reading this honestly
agent.go:311builds aMemoryJobStoreunlessJobStoreDiris set, and deploy#464 records both lanes running the in-memory store today. So this guards in-process re-execution now, and nothing across a restart until deploy sets a directory. It is written to be inert rather than required:TestContentWorksWithoutAStoreasserts the path still works with no store at all.I would rather ship a guard that is honest about its reach than describe it as durable idempotency.
This closes two rows of 621, not four
RecordEffectandEffectAppliedleaveunwiredCapabilities.CommandFromPromptandIsGrantDenialstay: those are still the deletion judgement #621 was filed for.The guard another seat built caught the wiring and told me exactly what to do:
That is the repository working as designed, and it is the reason this change did not land with a stale table.
Verification
ward exec gatePASS on all six steps.Two mutations, both compiling:
TestAReplayedMessageIsNotSentTwiceandTestAReplayStillDeliversWhatTheFirstRunDidNotTestAFailedSendRecordsNoEffectcloses #745