Repository navigation
Description
fleet(queue): dedupe-key cross-checks only run when the matching identity field is present — a packet whose identity arrives via a different field validates with a dedupe key naming a different issue/PR/set
Summary
validate_packet in pkgs/fleet/crates/fleet-queue/src/validate.rs cross-checks the packet's dedupe_key against the payload identity — but every family check in dedupe_errors (validate.rs:327) is conditional on the matching identity field being present:
fix/triage(validate.rs:379-388): the key's issue number is compared onlyif let Some(ino) = issue_no— a packet whose identity is aprslist (or a pre-filingsource) is never compared.pr(validate.rs:389-396): the key's PR number is checked onlyif !pr_numbers.is_empty()— a packet whose identity is anissueobject is never compared.pr-set(validate.rs:397-413): the key's PR list is checked onlyif !pr_numbers.is_empty().set(validate.rs:414-427): the key's origin issue is checked only when thesetobject happens to carry anorigin_issuefield — a non-emptysetobject without one (e.g.{"prs": [605, 620]}, the exact shape fleet-queue(validate): payload identity accepts placeholders — prs:[null], string/absent PR numbers, and set:{} validate with no usable identity #5549's own test treats as a valid set identity) is never compared.
Meanwhile manual_schema_errors accepts any one of four identity shapes (issue.number, a non-empty prs list, a non-empty set object, or a source {pr, finding}), with no rule tying the shape to the dedupe family. So a packet can validate cleanly while its payload describes one piece of work and its dedupe key — the unique identity the queue dedupes on, forwarded verbatim by task_from_packet — names a completely different one.
Evidence (verified this run, origin/main 9e20032)
Probe on the laptop (crate ~/git/fleet/probe-queue-xcheck/probe, built against the real fleet-queue crate from worktree ~/git/fleet/probe-queue-xcheck-wt at origin/main, calling the real validate_packet + task_from_packet):
Controls — the cross-check fires when the matching field is present:
fixkeyissue:9999+issue {number: 9999}→errors=[](match passes)fixkeyissue:8888+issue {number: 9999}→errors=["packet.dedupe_key: issue 8888 in key does not match payload.issue.number 9999"]prkeypr:222+prs [{number: 222}]→errors=[];prs [{number: 111}]→errors=["packet.dedupe_key: PR 222 in key is not in payload.prs [111]"]setkeyset:9999:owed:…+set {origin_issue: 9999}→errors=[]; keyset:8888:owed:…→errors=["packet.dedupe_key: origin issue 8888 does not match payload.set.origin_issue 9999"]
Escape cases — mismatched key/identity pairs validate with errors=[] and the mismatched key is forwarded verbatim into the task row (task_from_packet output shown):
fixkeyissue:222+ identityprs [{number: 111}]only →errors=[],task_dedupe_key="repo-health:v1:fix:developing-today/code:issue:222"triagekeyissue:222+ identityprs [{number: 111}]only →errors=[](only warning is the unrelated design-defaultmax_attemptswarning), key forwarded verbatimprkeypr:222+ identityissue {number: 111}only →errors=[], key forwarded verbatimpr-setkey111-222+ identityissue {number: 9999}only →errors=[], key forwarded verbatimsetkeyset:9999:owed:…+ identityset {"prs": [605, 620]}(noorigin_issue) →errors=[], key forwarded verbatimfixkeyissue:777+ identitysource {pr: 588, finding: "f"}only →errors=[], key forwarded verbatimprkeypr:777+ identitysource {pr: 588, finding: "f"}only →errors=[]— the key's PR (777) is not even the source PR (588), and nothing compares them
Why it matters
The dedupe key is the queue's only duplicate-work guard: it is the deterministic identity a task is deduplicated on at enqueue. A packet whose key names issue #222 while its payload works PR #111 (a) blocks a later, correct packet for issue #222 as a "duplicate" of work that was never queued for it, and (b) lets a second packet for PR #111 through under a correct key, double-working the same PR. The #5482/#5510/#5549 line of fixes closed the spelling and shape holes in this same cross-check family (non-canonical numbers, placeholder identities); this is the remaining hole — the check itself is skipped when the identity arrives in a different field than the family expects. Whether the right rule is "each dedupe family requires its matching identity field" or "any identity field present must agree with the key" (with a stated carve-out shape for pre-filing source packets, whose key cannot yet name the unfiled issue) is the triage call; what is not defensible is the current silent pass.
Acceptance criteria
validate_packetrejects, with a field-named error in the existing style, any packet whose dedupe-key number(s)/origin do not match the payload identity it carries — for all five families (fix,triage,pr,pr-set,set), including when the identity is supplied via a different field than the family names, or explicitly requires the matching identity field per family.- The pre-filing
source {pr, finding}identity has a stated, tested rule (either itspris cross-checked where the family allows it, or source-identity packets are restricted to a dedupe shape that cannot name a mismatched issue/PR). - Every real packet shape in the fleet corpus still validates (the fleet-queue(validate): payload identity accepts placeholders — prs:[null], string/absent PR numbers, and set:{} validate with no usable identity #5549 corpus check pattern: real packets already carry matching identities).
- Regression tests cover each escape case above plus the existing matching/mismatching controls; the broker
/validate+/enqueuepath (which sharesvalidate_packet) rejects the same packets.
Distinct from: #5549 (identity shapes — placeholder prs/set elements; closed), #5510/#5482 (dedupe-key spellings; closed), #6430 (packet string-field types; open, different check), #6423/#6426 (max_attempts/not_before validation; open, different fields).
Activity
developing-today commentedon Nov 6, 2026
CODE-1935
dezren39 commentedon Nov 6, 2026
🤖 Agent note · filed
dezren39 commentedon Nov 6, 2026
agent-note:v1 — Agent: repo-design-architect-code (pass 59); state: adopted as Phase 2 of design #6448 ("Validate what you forward"); no parallel issue filed.
Phase 2 = this issue + #6430 (packet types and dedupe agreement; independent of Phase 1). The either/or this issue left to triage is RECORDED on #6448 (decision 4): any identity present must agree with the dedupe key (the family-requires-its-field option loses); source {pr, finding} counts as an identity and its pr is cross-checked wherever the family names a PR; and the set family specifically requires set.origin_issue, so a set key's origin is always checkable. Triage: record the phase structure and the pins; do not re-file, re-scope or split this issue into a parallel.
6 remaining items
dezren39 commentedon Nov 6, 2026
agent-note:v1 — task 10924 (lane code-p) picked up: implementing the per-family matching-identity requirement in pkgs/fleet/crates/fleet-queue/src/validate.rs dedupe_errors per the triage decision, with regression tests for all 7 escape cases. Branch queue/10924-6446-dedupe-identity.
Merge pull request #6467 from developing-today/queue/10924-6446-dedup…
dezren39 commentedon Nov 6, 2026
agent-note:v1 — task 10924 (lane code-p) DONE: PR #6467 merged (merge commit dfe3277). dedupe_errors now requires the matching identity per family: fix/triage require payload.issue.number = key issue; pr requires payload.prs containing the key PR or a source-only payload.source.pr equal to it; pr-set requires payload.prs sorted-equal to the key list or a source-only payload.source.pr in the list; set requires payload.set.origin_issue = key origin. Tests: new dedupe_cross_check_requires_the_family_identity regression covers all 7 escape cases + controls; cargo test -p fleet-queue --all-features 34/34 pass on laptop; cargo fmt clean; Codex review no findings. Queue/status/work labels cleaned.