No queue row is not an SMTP failure
- No queued notification
- The intended actor did not cross recipient selection and queue insertion. SMTP credentials, SPF, DKIM and mailbox rules have not participated yet.
- Ticket assignee
Notification::ASSIGN_TECHis target value 2. It queries the ITIL actor relation withtype=CommonITILActor::ASSIGNand checksuse_notification.- Linked-item technician
Notification::ITEM_TECH_IN_CHARGEis target value 5. For tickets, it reads each object linked throughItem_Ticketand then looks for that object'susers_id_tech.
Browser-local routing tool
Find the first GLPI technician boundary
No email address, ticket content, user ID, SMTP credential, message identifier or mailbox data is requested or transmitted.
- First boundary
- Next action
- Exit condition
- Safety rule
What GLPI 11.0.8 source actually separates
Notification.php defines ASSIGN_TECH=2 and ITEM_TECH_IN_CHARGE=5 as different recipient constants. Their names are similar, but they do not share a data source.
For target 2, NotificationTargetCommonITILObject::addSpecificTargets() calls addLinkedUserByType(CommonITILActor::ASSIGN). That function queries the ticket user-link table, reads use_notification and alternative_email, and then adds eligible users to the recipient list.
For target 5, addItemTechnicianInCharge() calls addUserByField('users_id_tech', true). On a ticket, getObjectItem() populates target_object from Item_Ticket linked objects, not from glpi_tickets_users.
If the intended recipient is the technician assigned to the ticket, changing target 5 to query ticket actors would collapse two recipient concepts. The lower-risk configuration is target 2; a code fix should instead correct any default target or UI-label mapping that persists target 5 for the ticket-assignee label.
Run one bounded control
- Record the New Ticket notification's USER_TYPE target ID. Do not publish the notification ID, actor ID or email address.
- For a ticket assignee control, select the UI recipient that persists
items_id=2. Use one active technician withtype=ASSIGN,use_notification=1and a valid default or alternative email. - Create one controlled ticket and inspect recipient selection immediately before
addToRecipientsList. - Assert one technician-specific row is inserted into
glpi_queuednotificationsbefore the mail worker runs. - Only after that row exists, follow worker, transport, provider and receiving-server evidence.
-- Read-only configuration check; substitute the private notification ID locally.
SELECT type, items_id, is_exclusion
FROM glpi_notificationtargets
WHERE notifications_id = :notification_id
ORDER BY type, items_id;
Expected for an assigned ticket technician:
type = Notification::USER_TYPE
items_id = Notification::ASSIGN_TECH -- 2
Regression contract for the upstream fix
- Create a ticket with no linked asset and two assigned technician actors: one with
use_notification=1, one withuse_notification=0. Target 2 must select only the eligible actor once. - Create a separate ticket linked to an asset with
users_id_tech. Target 5 must select the linked asset technician and must not silently substitute the ticket assignee. - Assert the New Ticket default and UI label for “Technician in charge of the Ticket” persist target 2, while any linked-item label persists target 5.
- Assert one recipient produces one queued row before SMTP. A zero-row failure should expose a bounded recipient-selection diagnostic instead of a transport error.
- Keep the two tests independent so future migrations cannot make a similarly worded label swap their stored constants.
Continue from worker execution to provider and receiver evidence without entering an address, ticket or credential.