-
-
Work item 10 asks to shorten the Saturday greeting from 2,200 ms to 900 ms. The flow then posts the sealed contract. Session 9567205.
-
Incident 11, closed. Call 9: "wait, no" at 990 ms, then book_appointment at 2,500 ms. The resolution is from the flow.
-
Merge request !5. Three commits by Hold the Line: c3bbdc00, 0efe1046, and 3febe5fd.
-
Pipeline 2952624503 fails the regression test on commit 0efe1046.
-
Pipeline 2952628581 passed, created by Hold the Line, for the timing-fix commit 3febe5fd.
-
Certificate verified-2952633485. Verdicts pass, fail, pass. Holdout pass. Three digests, production at 100%.
-
Live service responds mode repaired, greeting silence 900, digest sha256:9d01b87f7f1a6d353608012807a9912433ed26a999b9b0164b37f9aa3dd2cb00.
Inspiration
A shorter greeting is a normal product change. On a voice agent that can book, cancel, or message, that change can also close the microphone before the caller finishes "wait, no." Unit tests stay green, and a judge that scores polite wording will still accept the booking.
Hold the Line grades the tool calls, not the wording. One GitLab Duo flow ships the greeting change. A separate verifier, with no model in the verdict, replays one frozen set of 30 calls on three image digests.
What it does
Creating work item 10 was the only human action. It asks to shorten the Saturday greeting from 2,200 ms to 900 ms and says the consent rules stay as they are. That started session 9567205.
- Plan. Before the first code commit, the flow posted the frozen contract and seal
5ca32408dc0ca5fada8b9f77d91a287c45689cffe9ada345155225d5b1bdd625. - Create. The flow opened merge request !5 and committed the 900 ms greeting (
c3bbdc00). - Verify. The verifier built 30 calls from that image digest. On call 9 the simulated caller said "wait, no" at 990 ms. The agent still called
book_appointmentat 2,500 ms. Pipeline 2952600808 failed. - Monitor. The same session opened Incident 11 with that trace.
- Repair. The flow committed a regression test (
0efe1046). Pipeline 2952624503 failed on that test. A later commit (3febe5fd) kept listening open through the consent window. - Release. Pipeline 2952628581 replayed the same calls on three digests: pass, fail, pass, plus a distinct holdout pass. The verifier promoted revision
hold-the-line-00025-cr8and the flow closed the Incident. Production traffic is 100% on that revision.
How we built it
The flow is .gitlab/duo/flows/hold_the_line.yaml, started by the work item. The voice agent, consent ledger, and timing generator are Python in src/hold_the_line/. They use timing seed 20261014. SHA-256 mixes that seed with the image digest. The booking ledger is simulated. No model decides pass or fail.
The source pipeline tests, scans, and publishes an image by digest. It cannot promote. Promotion is a second public project, hold-the-line-verifier, pinned at gate-v1. It deploys the digest to Cloud Run with GitLab OIDC, calls the tagged URL, and grades the tool calls it sees. The image's own pass flag is ignored. The certificate is release verified-2952633485.
Challenges we ran into
The flow that edits the agent must not be able to edit the rule it is graded on. The contract is sealed, and CI rejects a mismatched hash.
A bot cannot start a second flow. Detection, the Incident, the regression test, the timing fix, and the resolution stay in the one session the work item started.
The image under test cannot grade itself. The verifier replays the Cloud Run tag and checks that the URL is serving the digest it just deployed. Certificate verified-2952633485 names baseline sha256:f69e2b19e229e34a3e1d14ea2ec6a2c8dae36f23b629721a6b73bd71ae910ed7, regressed sha256:965daae9bf7e72bc5abc2350c973af778ec23b59999bad71f6042ace862f28bd, and repaired sha256:9d01b87f7f1a6d353608012807a9912433ed26a999b9b0164b37f9aa3dd2cb00.
Google's token exchange rejects a subject longer than 127 characters, so the workload-identity subject is the CI job id.
Accomplishments that we're proud of
Session 9567205 finished the loop with no later human edit: one work item, one flow, Incident 11 opened and closed, and three commits on merge request !5.
All nine stages leave a GitLab artifact: the work item, the commits, the failed and passing pipelines, the image digest, the scan and SBOM, the Terraform plan, the contract-hash job, Incident 11, and the verification certificate.
Production serves the repaired revision at 100%. The baseline and this run's regressed revision remain on their own URLs.
What we learned
An agent is useful at reading a failed trace and writing the next two commits. It is the wrong place to decide pass or fail. The verdict belongs to a sealed check that replays the same calls on the bytes that were deployed.
Built With
- docker
- gitlab
- gitlab-ci
- gitlab-duo
- google-cloud
- google-cloud-run
- openid-connect
- python
- sqlite
- terraform
- trivy
Log in or sign up for Devpost to join the conversation.