@@ -73,11 +73,12 @@ Identity model:
7373- Parse queue bodies of the form:
7474
7575``` text
76- <uuid> <shell-escaped arguments>
76+ <uuid>:<timestamp> <shell-escaped arguments>
7777```
7878
79- - Match only the first UUID-width bytes of the body against configured job
80- UUIDs.
79+ - Match the UUID prefix against configured job UUIDs.
80+ - Require a 12-15 digit numeric timestamp after the UUID and colon.
81+ - Deduplicate matching queue triggers by ` <uuid>:<timestamp> ` for 140 seconds.
8182- Preserve job arguments with spaces by parsing shell-escaped argument text.
8283- Log an error for malformed or unknown UUID bodies, and log an info event when
8384 a job is triggered from a queue.
@@ -272,9 +273,12 @@ Rules:
272273- Bodies shorter than 36 bytes are invalid.
273274- Only bytes `[0:36]` are considered for job selection.
274275- The UUID prefix must parse as a UUID.
275- - UUID-only payloads are valid and mean the job has zero arguments.
276- - If the body has more data, byte 36 must be a single ASCII space.
277- - Argument text begins at byte 37.
276+ - Byte 36 must be a single ASCII colon.
277+ - A numeric timestamp of 12-15 digits must follow the colon.
278+ - Timestamp-only payloads are valid and mean the job has zero arguments.
279+ - If the body has more data after the timestamp, the next byte must be a single
280+ ASCII space.
281+ - Argument text begins after that space.
278282- Empty argument text means zero arguments.
279283- The argument parser tokenizes shell-escaped words without command execution,
280284 variable expansion, globbing, or file access.
@@ -286,13 +290,27 @@ Rules:
286290Examples :
287291
288292` ` ` text
289- 1104df4c-feeb-43ab-8c85-83663288cea9 alpha two\ words
290- 1104df4c-feeb-43ab-8c85-83663288cea9 'alpha beta' gamma
293+ 1104df4c-feeb-43ab-8c85-83663288cea9:17642656976077
294+ 1104df4c-feeb-43ab-8c85-83663288cea9:17642656976077 alpha two\ words
295+ 1104df4c-feeb-43ab-8c85-83663288cea9:17642656976077 'alpha beta' gamma
291296` ` `
292297
293298The existing `resources/gcloud/scripts/queue-job.sh` POC matches this contract
294- by using `printf "%q "` for each argument and sending the payload as
295- ` text/plain` .
299+ by calculating the timestamp with `echo "$(( $(date +%s%N) / 100000 ))"`,
300+ using `printf "%q "` for each argument, and sending the payload as `text/plain`.
301+
302+ # # Queue Trigger Deduplication
303+
304+ The engine records each `<uuid>:<timestamp>` pair for 140 seconds after the
305+ UUID maps to a configured job. During that retention window, another queue
306+ payload with the same UUID and timestamp is acknowledged and discarded before a
307+ second pipeline is started.
308+
309+ Deduplication is intentionally in the engine queue handler, not in queue
310+ providers, so all provider backends share the same behavior. The dedupe key is
311+ stored only in memory and is cleaned opportunistically as new queue messages are
312+ handled. The timestamp is only an idempotency token; it is not interpreted as a
313+ wall-clock freshness check.
296314
297315# # Job Matching And Pipeline Start
298316
@@ -308,15 +326,18 @@ Flow:
3083262. Parse and validate the queue body.
3093273. Lookup the normalized UUID in the current enabled-job UUID map.
3103284. If no job matches, log `Error` and return `QueueAck`.
311- 5. Parse shell-escaped arguments.
312- 6. Validate supplied arguments against the job's `Arguments` matchers :
329+ 5. Record the `<uuid>:<timestamp>` dedupe key for 140 seconds.
330+ 6. If the dedupe key is already present, log `Info` and return `QueueAck`
331+ without starting another pipeline.
332+ 7. Parse shell-escaped arguments.
333+ 8. Validate supplied arguments against the job's `Arguments` matchers :
313334 - Too few arguments is an error.
314335 - Existing behavior for extra arguments is preserved.
315336 - Invalid argument values log `Error`.
316337 - Queue triggers never prompt for missing arguments.
317- 7 . Log `Info` that job `<name>` was triggered from queue provider `<provider>`.
318- 8 . Start the job pipeline with a new pipeline type, `queuedJob`.
319- 9 . Return `QueueAck` once the pipeline has been accepted for execution.
338+ 9 . Log `Info` that job `<name>` was triggered from queue provider `<provider>`.
339+ 10 . Start the job pipeline with a new pipeline type, `queuedJob`.
340+ 11 . Return `QueueAck` once the pipeline has been accepted for execution.
320341
321342The worker should be built like a scheduled job worker :
322343
@@ -390,15 +411,19 @@ Google resource alignment:
390411 ` job-triggers` and subscription `job-triggers-pull`.
391412- ` resources/gcloud/scripts/create-job-webhook-resources.sh` deploys a Cloud
392413 Function with a UUID-bearing URL and publisher service account.
393- - ` resources/gcloud/scripts/webhook/index.js` publishes the raw request body.
394- - ` resources/gcloud/scripts/queue-job.sh` sends the body contract expected by
395- the engine.
414+ - ` resources/gcloud/scripts/webhook/index.js` validates the raw request body
415+ has the required UUID, timestamp, and argument separator shape before
416+ publishing it.
417+ - ` resources/gcloud/scripts/queue-job.sh` calculates a 14-digit timestamp and
418+ sends the body contract expected by the engine.
396419
397420# # Security Notes
398421
399422- Queue provider config is engine/provider config, not extension config.
400423- ` UUIDTrigger` values are bearer trigger secrets and should normally be stored
401424 in `conf/variables/<environment>.yaml` under `Secrets`.
425+ - Queue timestamps are idempotency tokens paired with a UUID trigger. They are
426+ not authorization material.
402427- Logs must never print configured UUIDs or full queue bodies.
403428- Unknown UUIDs should log only a short diagnostic such as provider name,
404429 provider message ID, and body length.
@@ -414,6 +439,7 @@ Google resource alignment:
414439First-slice semantics are accepted-trigger acknowledgment :
415440
416441- Ack after the engine validates the queue body and accepts the job pipeline.
442+ - Ack duplicate UUID/timestamp pairs after discarding the duplicate.
417443- Ack malformed bodies and unknown UUIDs after logging an error.
418444- Retry only when the engine is shutting down or temporarily unable to make a
419445 routing decision.
@@ -431,7 +457,8 @@ Implications:
431457# ## 1) Change Summary
432458
433459- Slice name : job queue provider facility.
434- - Goal : allow remote queues to trigger configured jobs by UUID and arguments.
460+ - Goal : allow remote queues to trigger configured jobs by UUID/timestamp
461+ prefixes and arguments.
435462- Out of scope : completion-coupled queue retries, user-scheduled jobs, extension
436463 queue APIs, and connector-based queue routing.
437464
@@ -447,7 +474,8 @@ Expected implementation files and directories:
447474- `bot/config_validate.go` : ` conf/queues/*.yaml` validation.
448475- `bot/tasks.go` : ` Job.UUIDTrigger` .
449476- `bot/taskconf.go` : UUID trigger parsing, validation, duplicate detection.
450- - `bot/queue_runtime.go` : provider lifecycle and engine queue message handler.
477+ - `bot/queue_runtime.go` : provider lifecycle, queue body parsing, dedupe cache,
478+ and engine queue message handler.
451479- `bot/bot_process.go` : startup and shutdown placement.
452480- `bot/run_pipelines.go`, `bot/constants.go`, `bot/pipelinetype_string.go` :
453481 queued-job pipeline source.
@@ -487,6 +515,8 @@ What changes:
487515- Root config can enable queue providers.
488516- Jobs can declare `UUIDTrigger`.
489517- Queue providers poll external systems and submit queue messages to the engine.
518+ - Queue bodies carry a UUID/timestamp prefix, and the engine deduplicates
519+ matching triggers with the same prefix for 140 seconds.
490520- The engine starts matching jobs from queue messages with a `queuedJob`
491521 pipeline type.
492522
@@ -532,8 +562,8 @@ What does not change:
532562- Race risks : reload while queue item is being matched; provider shutdown while
533563 a message callback is active; duplicate queue delivery from provider restart.
534564- Mitigations : immutable config snapshots, provider stop channels, retry during
535- shutdown, idempotent job design guidance , and unit tests for reload/shutdown
536- behavior.
565+ shutdown, engine-side UUID/timestamp dedupe , and unit tests for
566+ reload/shutdown behavior.
537567
538568# ## 8) Backward Compatibility
539569
@@ -548,10 +578,12 @@ What does not change:
548578Focused tests :
549579
550580- Config validation accepts `conf/queues/gcloud.yaml` with `QueueConfig`.
551- - Root `QueueConfig` is rejected with a migration-style error.
581+ - Root `QueueConfig` is rejected with a configuration-placement error.
552582- ` QueueProviders` parses and normalizes provider names.
553583- ` UUIDTrigger` accepts valid UUIDs and rejects invalid or duplicate values.
554584- Queue body parsing preserves arguments with spaces.
585+ - Queue body parsing requires a 12-15 digit timestamp after the UUID.
586+ - Duplicate UUID/timestamp pairs are discarded for 140 seconds.
555587- Unknown UUID logs an error and returns `QueueAck`.
556588- Shutdown returns `QueueRetry`.
557589- Queue-triggered jobs start with `automaticTask=true`, expected args, and
@@ -581,8 +613,7 @@ Manual verification:
581613- `aidocs/SCHEDULER_FLOW.md` : no behavior change, but cross-reference queued
582614 jobs if helpful.
583615- `aidocs/COMPONENT_MAP.md` : add `queues/`, `conf/queues/`, and this document.
584- - `aidocs/V3_COMPATIBILITY_CONTRACT.md` : no required change unless config
585- migration guidance changes.
616+ - `aidocs/V3_COMPATIBILITY_CONTRACT.md` : no required change.
586617- `conf/README.md` : add `queues/<provider>.yaml`.
587618- `resources/gcloud/README.md` : document queue resource scripts and curl flow.
588619
0 commit comments