Inspiration Friday, 17:40 WIB, peak dispatch time at a logistics company in East Java. A small "cleanup" to the ETA-quote service ships. CI is green and every endpoint returns 200 OK, but the service now reads the clock in UTC and labels it WIB, so pickups are scheduled seven hours in the past. Couriers get impossible jobs; customers notice before engineers do. (Illustrative scenario drawn from the author's experience as CTO of a logistics company.)

Code generation is solved. Delivery isn't. We asked: what if agents owned everything after the code is written, and judged a change by the business rules it must keep, not by the HTTP status it returns?

What it does LastMile treats every change like a parcel moving through checkpoints. A human opens an issue or a merge request; Duo flows and the pipeline do the rest, and post a tracking card on the issue.

Dispatcher flow (plan + create): reads an issue, writes acceptance criteria / risk class / branch plan as an issue note, then implements the change with tests and opens an MR. Inspector flow (verify + secure): started by CI on every MR pipeline — even a red one. Reads failing jobs, Duo Code Review findings and lastmile.policy.yml, pushes a fix to the MR branch, and sets a verdict label (lastmile::cleared or lastmile::needs-human). Deterministic merge gate (release): a CI job, not an agent, checks policy + verdict label + green pipeline and requests auto-merge. Scripts measure, agents decide and explain. Auditor flow (govern): on every main pipeline, reads the evidence pack (proof-of-delivery.md) and writes the delivery summary on the originating issue — and refuses to call it "delivered" when the evidence doesn't support it. Pilot flow (monitor → incident): on a failed production gate, does root-cause analysis, opens an incident and a fix MR (wired in CI via when: on_failure; needs the Cloud Run stages to be live). Hands-off run shown in the video (real timestamps, WIB, 27 Oct 2026):

09:26 a human opens issue #3 → a flow trigger (work item created) starts the Dispatcher → 2) 09:28 plan note, 09:29 MR !3 with code + feature tests → 3) 09:31 Duo Code Review requests changes: "weight_kg": "1e999" passes validation, becomes INF, and turns a 422 into a 500 → 4) 09:33 the Inspector pushes a fix with tests → 5) 09:35 Duo re-reviews and approves, the merge gate merges, issue #3 closes → 6) the main pipeline runs and the Auditor posts the delivery note. Nine minutes, zero human clicks. Failure path (seeded on purpose): MR !1 reintroduces the classic utc_clock bug (UTC digits labelled as WIB). PHPUnit goes red, Duo flags the 7-hour shift, the Inspector diagnoses it and pushes fix(quote): restore setTimezone() WIB clock…, the pipeline goes green and the merge gate requests auto-merge.

How we built it Architecture: Laravel 13 / PHP 8.4 ETA-quote API → GitLab CI with 11 stages mapped to the 9 DevSecOps stages → four custom Duo flows created in the AI Catalog from versioned YAML in .gitlab/duo/flows/, enabled on the group and project, and started from CI through POST /api/v4/ai/duo_workflows/workflows (ops/start_flow.py). Flow triggers only fire on human actions, so CI is the "spine" that hands work from one agent to the next. Duo Agent Platform (core): each flow runs as its own service account (ai-lastmile-inspector-dev-pro, …), so every agent action is attributable in the MR and issue history. Flow sandbox image and setup in .gitlab/duo/agent-config.yml. Without the flows there is no fix, no verdict and no close-out — the pipeline would just be red. Guardrails: thresholds and invariants live in lastmile.policy.yml (CODEOWNERS-protected, agents may not edit it). Agents never merge; ops/merge_gate.py does, only with the verdict label and a green pipeline. Business invariants: eta_after_now, eta_after_pickup, pickup_not_in_past, within_sla, eta_in_delivery_window, price_positive; the API fails closed (HTTP 500 + X-LastMile-Invariants: fail). Stack: Laravel 13, PHP 8.4, FrankenPHP container, Python ops scripts, Cloud Run deploy scripts with progressive rollout 10% → 50% → 100% and auto-rollback (ops/rollout.sh, ops/canary_analysis.py, infra/setup-gcp.sh). Quality: 25 PHPUnit tests (1,531 assertions) + 18 ops tests, Pint, composer audit, SAST, secret detection, dependency scanning, CycloneDX SBOM — all in the public pipeline history. Tools used (incl. AI assistants): GitLab Duo Agent Platform (the agents in the product); an AI assistant (Grok Bot) helped the author write code, CI config, docs and this write-up. Evidence: DevSecOps stages Stage What runs Evidence plan plan:policy-and-flows validates policy + flow YAML; Dispatcher planner writes the plan note pipelines: https://gitlab.com/dev-pro5735544/lastmile/-/pipelines · plan notes on https://gitlab.com/dev-pro5735544/lastmile/-/work_items/3 and https://gitlab.com/dev-pro5735544/lastmile/-/work_items/2 create Dispatcher opens MRs with tests; Inspector pushes fix commits https://gitlab.com/dev-pro5735544/lastmile/-/merge_requests/3 · https://gitlab.com/dev-pro5735544/lastmile/-/merge_requests/2 verify phpunit, pint, ops-tests; Duo Code Review MR !1 pipelines: https://gitlab.com/dev-pro5735544/lastmile/-/merge_requests/1/pipelines secure SAST (semgrep), secret detection, dependency scanning (gemnasium), composer audit main pipeline: https://gitlab.com/dev-pro5735544/lastmile/-/pipelines/2992419974 package CycloneDX SBOM (live); container build to Artifact Registry (code in repo, runs when GCP is configured) sbom job; Dockerfile, infra/ release deterministic merge gate + auto-merge; GitLab Release job (needs GCP stage) MR !3 merged by the gate: https://gitlab.com/dev-pro5735544/lastmile/-/merge_requests/3 configure Cloud Run traffic split 10% → 50% (code in repo, not live) ops/rollout.sh monitor canary analysis + business-invariant probes (code + tests in repo, not live) ops/canary_analysis.py, ops/probes.py govern govern:evidence proof-of-delivery artifact, Auditor flow, CODEOWNERS, policy file Auditor notes on https://gitlab.com/dev-pro5735544/lastmile/-/work_items/3 and https://gitlab.com/dev-pro5735544/lastmile/-/work_items/1 · main pipeline https://gitlab.com/dev-pro5735544/lastmile/-/pipelines/2992496243 Agent sessions (Automate → Sessions in the project): Inspector, Auditor, Dispatcher and Duo Code Review runs, e.g. https://gitlab.com/dev-pro5735544/lastmile/-/automate/agent-sessions/10098738

Autonomy, honestly Hands-off, proven twice: issue #3 → MR !3 (with one Duo-requested fix round) and issue #2 → MR !2 were planned, built, reviewed, fixed, merged and audited with no human action after opening the issue. (For #2 the Dispatcher was started through the Flows API; the flow trigger was added right after and fired by itself for #3.) Where a human still can step in: lastmile::needs-human label (Dispatcher/Inspector), CODEOWNERS on the policy, CI config and flow files, and Duo's "request changes" merge block. On the seeded MR !1, Duo's change request stayed in place after the Inspector's fix, so MR !1 is deliberately left open as the "held at the depot" example: green pipeline, but a reviewer block keeps it from shipping until a human decides. Not live in this submission: the Cloud Run package/canary/rollback stages (code, policy and tests are in the repo; no Google Cloud project attached), so no Google Cloud bonus is claimed. Challenges we ran into Flow schema vs docs: the AI Catalog rejected max_cycles on components → removed it (RISKS.md R4). Who may start a flow: a project access token gets 403 forbidden to access duo workflow; flows must be started by a Duo-enabled user identity, with the flow's own service account doing the work (R1). Stage ordering: agents were skipped exactly when needed, because GitLab skips later stages after a red verify stage → the Inspector job now runs when: always on MR pipelines. Foundational Code Review from CI returned 403 This flow is not enabled; the project's automatic Duo reviews cover it, and Duo re-reviews by itself after the Inspector pushes. Flow triggers via API: created with the aiFlowTriggerCreate GraphQL mutation (event types work item + assign) so the Dispatcher starts on a new issue. Accomplishments that we're proud of A full issue → plan → code → review → fix → merge → audit loop in 9 minutes with zero human clicks (issue #3). An agent found and fixed a timezone bug that returned 200 OK but broke every delivery promise, with a test-backed commit, about three minutes after the red pipeline. Four custom flows, versioned as YAML in the repo and created through the API, each with its own service account. 9/9 stages designed and wired in CI; plan, create, verify, secure, release and govern evidenced live. What we learned "Touching a stage" is easy; making an agent responsible for it needs a deterministic gate next to it. Agent identities (service accounts) make the audit trail almost free. Flow triggers fire on human actions only, so CI is the natural orchestrator between agents. What's next for LastMile Attach a Google Cloud project and turn on the canary/rollback stages already in the repo. Let the Inspector reply in Duo's review threads, so every finding has a visible answer. Package the flows + policy as a template for Laravel teams in logistics and e-commerce. What was built during the submission period Everything. The project was created on GitLab on 27 Oct 2026 (local work started 9 Oct 2026, after the 5 Oct start); there is no pre-existing code beyond the Laravel framework skeleton and open-source dependencies.

Built With

Share this project:

Updates

Submission history