Found during this round's full acceptance pass: WF2 had the same
timeouts/bounded-retries gap as WF1 (timeout was already set, but Retry
On Fail was disabled). Fixed live (3 tries, 1000ms wait), published, and
synced the repo definition + manifest checksum.
User explicitly authorized issuing the RAGcore credential directly this
round. Retried via the admin UI (Platform Admin role) after the earlier
raw-API attempt; both fail with an opaque server-side rejection carrying
a trace ID. Documents this as a RAGcore-side blocker, not a Fleet Ops gap.
Vehicle Return Orchestration had no explicit timeout and Retry On Fail
disabled on its outbound HTTP call, a gap against the acceptance
checklist's timeouts/bounded-retries requirement. Fixed live (3 tries,
1000ms wait, 15s timeout, matching WF2's existing convention) and
synced the repo definition + manifest checksum.
New central "Fleet Ops — Workflow Error Handler" workflow (Error
Trigger -> safe-report Code node -> POST to the new /workflow-error
endpoint), wired as the Error Workflow on both existing workflows with
no recursive loop on itself. Live-validated end-to-end against the
real Fleet Ops server (register + idempotent re-register), and via a
genuine induced failure on the scheduled-scan workflow (broken URL,
confirmed failure, reverted, confirmed healthy).
Fixed two real bugs found during live testing: Code node needed
"Run Once for Each Item" (not "All Items") for $json binding, and
every HTTP body field had a stray trailing space from the n8n
code-editor's bracket auto-close that broke datetime/enum validation.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Move the two live-validated workflows into n8n/workflows/ (credential-
based auth referenced by name only, no secret values), add a manifest
covering all 4 canonical workflows and a read-only drift-check script
against n8n's Public API. Retire the pre-integration root-level starter
files that still carried the literal-token pattern, and repoint the
Unraid deploy scripts, Makefile targets and runbook at the new files.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
The original docs described two n8n workflows but the repository only ever
shipped one (return-processing); the sketched second workflow (knowledge
sync) depends on RAGcore, which isn't connected here, so it stays deferred.
Add POST /api/v1/integrations/n8n/scheduled-scan (X-Service-Token
protected, same pattern as the return callback), calling the same
run_scan() the manual "Run quality scan" UI action uses and recording a
service-actor data_quality_scan_run audit event. run_scan() already only
creates an issue for a condition without one open, so overlapping triggers
do no duplicate domain work.
n8n/mobilityops-scheduled-quality-scan.json (hourly schedule + manual test
trigger, both feeding the same HTTP call) ships "active": false so it can't
fire anywhere until deliberately published. Verified live against the
local n8n instance via the Manual test trigger: full green execution, and
the resulting data_quality_scan_run audit event (actor_type=service,
actor_label="n8n scheduled scan") confirms the real round trip, not just a
contract test. deploy/unraid/setup-scheduled-scan.sh mirrors the existing
return-workflow publish script for the shared Unraid n8n.
Outbox dispatcher (background thread, FOR UPDATE SKIP LOCKED claim, exponential backoff, no transaction held during HTTP I/O). n8n callback endpoint with shared-secret auth and idempotency by event ID. Automation nav + UI with manual retry. 49 backend tests passing, ruff clean. Fixed a crash-on-redelivery bug in seeded outbox payloads and made the dispatcher defensive against malformed payloads. Verified the full live round trip against a real n8n instance: return -> outbox -> dispatcher -> n8n workflow -> callback -> succeeded, including the S5 failed-retry demo scenario.