← Back to Publications

What we learned running agentic SDLC patterns

A field account from the AI Technical Solutions team: how a vulnerability report becomes a reviewed change, how a living application was rebuilt from its own behaviour, and which parts of Alberta’s AI Garage and AI Factory are ready for another team to copy.

9 October 2026

Why this account exists

The runs already happened. The pull requests, gate ledgers, and slide decks sat in repositories this team could see and other teams could not use. This page is the public record. It does not wait on another ministry, a vendor, or a central platform team. Where a number is below, it was counted from a public repository or taken from a named source. Where a number does not exist, the page says so.

Remediation

Project Sightline names vulnerable repositories. Three public forks then carried those findings through an agentic pipeline: BC Parks attendance and revenue admin, CSCP restitution, and LEAR.

Greenfield rebuild

digital-marketplace-next rebuilds the Digital Marketplace from recovered behaviour. It is an experiment. It has never been deployed and must not be used with real data.

Alberta patterns

The AI Garage fixes a system in place. The AI Factory builds a new one the government owns. We used both as the map for the runs above, and we kept their numbers labelled as theirs.

Held back

The Ministry of Transportation CIS Java remediation belongs to Rogene Lacanienta’s team. It is not in this paper. See that section.

The map

Two patterns, and what a scan is for

Alberta’s published framing, in The Four Approaches to AI Modernization, is the one we used. The Garage repairs a system where it stands. The Factory builds a new application against one specification, with specialist agents checking each other and a person accepting or rejecting the result. A scan is the input to that choice. It is not the delivery.

Pattern When it fits What we actually ran
AI Garage The application should keep living, and the defect is local enough to patch under tests. Sightline-style rapid assessments turned into issues, then spec, plan, and implementation pull requests on three forks.
AI Factory The application is tangled, vendor-locked, or cheaper to replace than to patch safely. Digital Marketplace rebuilt in 21 slices from acceptance criteria recovered from the original system.
Project Sightline You need a list of repositories with vulnerability and technical-debt findings. Used as a selector and a backlog source. It does not name an owner, a business case, data sensitivity, or whether to fix, rebuild, or retire.

That last row is the practical limit. A report can start a conversation with the team that owns the system. It cannot sign a checkpoint. The worst findings in this kind of scan sit on applications nobody has claimed. If nobody will accept a merge, the pipeline has nothing to attach to.

Garage, on our code

Project Sightline remediation runs

Each run started from a rapid assessment, filed the recommended findings as GitHub issues, and sent every finding through a specification, a plan, and an implementation pull request. Agents do not merge. A person, or in the parks pilot a simulated reviewer following the same checklist, accepts the change. After the backlog closed, a separate pass re-read the original finding against the code, because a closed issue is not the same thing as a fixed defect.

BC Parks attendance and revenue admin

Repository: bcgov/bcparks-ar-admin-agentic-b. An earlier fork, bcgov/bcparks-ar-admin-agentic, was the first enrolment and was left as a partial pilot. The numbers below are from the second fork.

Measure Result
Recommended findings shipped 45 of 45. Seven optional and three duplicate rows were left untouched on purpose.
Wall clock First pull request 31 Aug 2026 21:36 UTC, last merge 1 Sep 2026 18:18 UTC. About 20.7 hours for the whole backlog, about 28 minutes of calendar time per finding.
Pull requests 149 merged, 7 closed without merge. Open-to-merge time is typically under a minute, because the change was already built before the pull request was opened. That clock is not reviewer effort.
Checkpoint gate 93.8% after 5 slices, 97% after 10. The later full-backlog artifact stopped reporting the rate; sampled pull requests stayed in the same range.
Spec trace Implementation pull requests missing a spec reference: 0% across the pass. 79 criterion ids ended in the registry.
Independent re-check 35 fixed, 8 partial, 2 not fixed, against the original assessment wording rather than the closed issue.

The two misses and most of the partials have a cause, and it is useful. One implementation pull request merged an evidence file and no code: the narrative said the logging levels had changed, and keycloak.service.ts had not. Several other findings were signed at a narrower scope than the assessment asked for, then verified against that narrower contract. The pipeline was faithful to the contract and incomplete against the original defect. Reviewer effort on this fork was a simulated checkpoint, so the 97% figure is a gate result, not a count of hours a person spent reading diffs.

CSCP restitution

Repository: bcgov/pssg-cscp-restitution-agentic, on branch development. Copilot’s coding agent implemented most slices. An operator had to nudge Actions, and finished the tail of the backlog by hand when credits ran out.

Measure Result
Recommended findings shipped 36 of 36. Three informational findings were never filed.
Wall clock First pull request 3 Sep 2026 19:12 UTC, last merge 4 Sep 2026 20:23 UTC. About 25.2 hours, about 42 minutes of calendar time per finding.
Pull requests 108 merged, 0 closed without merge. That is one specification, one plan, and one implementation pull request per finding.
Independent re-check 35 fixed, 1 partial, 0 not fixed. The partial is VULN-004: the signed slice added maximum lengths and left email and phone format checks for a later slice. The implementation matched the signed scope.
Who did the work Copilot for the early and middle slices. From finding 30 onward, Copilot credits were exhausted and the operator shipped the remaining slices locally, still through the same spec, plan, and review comments.

Reviewer effort here was real and narrow. The operator’s repeated job was an empty commit so GitHub Actions would leave the action_required state and actually run the checkpoint gate. A CodeQL default-setup error failed the aggregate gate on slice after slice even when Trivy and the tests were green. The team recorded that residual and kept moving, which kept the backlog moving and also trained everyone to ignore a red check. Both facts belong in the lesson.

LEAR

Repository: bcgov/lear-agentic. This run shows the pipeline stopping, which is part of the result. Forty-one pull requests were closed without merge, including a merge-train, and main was reset to upstream plus a fresh enrolment. One pull request has been merged, and it is the enrolment itself. The first real slice (CONFIG-003) reached a green build and waited for a person. Agents do not merge their own work. The rest of the assessment backlog is still open. Treat LEAR as the control: a harness that can generate a backlog still needs a named person who will accept the first change before a second one is worth starting.

Factory, on our code

Digital Marketplace, rebuilt

The original service is bcgov/digital_marketplace. The experiment is bcgov/digital-marketplace-next, produced through agentic-sdlc. The repository keeps the brief, the recovered specification, the tests, the plan, the application, and every gate ruling. The rebuilt application runs on a developer machine. There is no deployment stage. The top navigation in the rebuild does not yet link the opportunity and organization lists; those routes exist at /opportunities and /organizations.

The method is the part worth copying. Agents read the original and wrote acceptance criteria. Tests were derived from those criteria without seeing an implementation, then run against the original application so the tests had to describe what the system really does. The plan cut the criteria into 21 slices. A builder implemented each slice. Verify ran that slice’s tests and the earlier slices’ tests before a reviewer could approve. Routine rulings, such as a re-derived test, could be approved by automated checks. A person could take any seat.

Measure Result, counted from the published ledger on 4 Oct 2026
Criteria recovered 295 rows in the coverage table: 286 accepted, 9 obsolete, 3 still open questions.
Slices All 21 slices have an approval in the gate ledger. First slice approval 25 Sep 2026, last slice approval 4 Oct 2026. About 9.8 days of calendar time.
Time per slice Median gap between consecutive slice approvals is about 3.2 hours. The gap from slice 1 to slice 2 is about 142 hours. The early slices are where the specification and the test adapter were still being fought.
Gate rulings 655 rulings: 464 approvals, 185 returns, 6 withdrawals. Of the 110 rulings on a build slice, 87 were returns. Work came back about four times per slice before it stayed approved.
Reviewer effort 25 of the 655 rulings were a person, all in the tech-lead seat: 15 approvals and 10 returns. The other rulings were a persona agent or the runner. The ledger’s cost column on agent rulings sums to about $538, median about $0.61. That is the cost of the ruling step, not the cost of writing the slice.
Tests against the original Full run on 4 Oct 2026: 199 pass, 44 fail, 7 unbound, 15 not testable, 265 rows. Of the tests that could run and bind, 81.9% passed. The 44 failures are information: the recovered criteria and the original system disagree, and someone has to decide which side is right.
Tests against the rebuild A slice was approved when verify reported that every criterion the slice claimed was passing, including earlier slices. The run log uses that sentence for 15 of the 21 slices; the ledger shows an approval for all 21. There is no separate full-suite row for the new application in the results table. Do not read the 81.9% figure as the rebuild’s pass rate. That figure is the original system.

The returns are the result, not a blemish. Slice 21 was sent back because criteria could not be exercised, then because they failed, then because an earlier slice’s criterion regressed, and only then verified clean. Slice 14 was refused when the builder was asked to change a design file the build stage is not allowed to write. The gate’s job is to send that condition to the stage that can carry it out.

What we brought home

AI Garage and AI Factory, as Alberta described them

These figures are Alberta’s, from the Velocity papers and from the August 2026 AI Academy Level 3 sessions this team attended. They are included so a BC team can see the shape of the pattern at estate scale. They are not measurements of the runs in the previous sections. Classroom figures from the Academy were spoken in the room; treat them as the presenter’s account until a paper or a dataset restates them.

AI Garage

The Garage points a harness at the existing estate. In the Academy walkthrough the sequence was: a Git Insights brief is a lead, not a verdict; a second scan (dependency and application checks, plus a red-team and blue-team pass) re-verifies before anyone edits; repositories that already have tests and a clean dependency bump are patched; repositories that are vendor-locked or tangled are routed to a rebuild instead. The presenter described one orchestrator driving 30 virtual machines and about 300 coding-agent instances, fixing on the order of 55,000 of about 79,000 known dependency findings in about 40 hours, at a stated compute cost of $125,000 (about $34 a repository) after a scan he put at about $10 a repository. He also said about 2,600 pull requests were staged and not merged, because the next missing piece was a smoke test good enough to hand to the team that owns the repository. About 73% of the repositories had no continuous integration, so the harness was adding tests in the same pass that claimed a fix.

The lesson we kept is the one our own re-checks confirmed at a much smaller scale. A scan starts the work. A second check, against the original wording of the finding, is what you are allowed to call a fix. And a pull request that the owning team has not accepted is still a proposal.

AI Factory

The Factory builds new. Alberta’s published case study, From Five Months to Four Days, gives two numbers from their own staff. The Remote Area Heating Allowance application, hand-written in Java over five months in the early 2000s, was rebuilt in four days with a public portal the original did not have. The Alberta Classroom Information Portal was delivered in eleven weeks for about $108,000, against a traditional estimate of $1.3 million to $1.9 million and up to eighteen months. The paper summarises the pair as a 25-fold speed change and a 95% drop in delivery cost. Those are Alberta’s delivery accounts, with their own baselines.

The Academy also showed a smaller version of the same idea: several agents building the same specification in parallel, so a mistake that appears in every build is blamed on the template rather than on one model. That exercise produced a working application in a teaching session. It was not a production launch. Our factory-shaped run is the Digital Marketplace rebuild above: one specification, tests locked to the original behaviour, slices, and a gate that returns work. We have not reproduced a four-day or an eleven-week production cutover, and this page does not claim one.

If you are choosing Start here
The defect is local, tests exist or can be added, and someone owns the merge. Garage. File the finding, sign a slice no wider than you will verify, and re-read the original ticket after merge.
The repository is the product, and patching it would preserve the tangle. Factory. Recover acceptance criteria, prove the tests on the old system, then build the new one in slices the gate can refuse.
You only have a vulnerability report. Stop and find the owner. Sightline, and Alberta’s Git Insights the same way, will hand you a repository with nobody’s name on it.

Worth keeping

What worked

A finding becomes three pull requests

Specification, plan, implementation. On restitution that produced exactly 108 merged pull requests for 36 findings, and the independent re-check found no empty or wrong diff hiding behind a closed issue.

The gate returns work

On the Marketplace rebuild, 87 of 110 build-slice rulings were returns. Slices that could not be exercised, or that broke an earlier slice, did not get an approval until verify was clean.

A person rules the exception

Twenty-five human rulings out of 655, ten of them returns, were enough to steer the rebuild. The pattern holds when the person sees the refusals and the scope changes, and stays off the routine test re-derivation.

Re-check against the original words

Parks was 35 fixed, 8 partial, 2 not fixed. Restitution was 35 fixed, 1 partial, 0 not fixed. Those counts are the ones to quote. “45 of 45 issues closed” overstates what the code does.

Calendar time can be short

A recommended security backlog of this size moved in about a day of wall clock once the harness, the assessment, and a person who would accept merges were already in place. Setup and the first accepted slice are the long part. LEAR is still in that part.

Tests written before the new code

Marketplace tests were derived from criteria and run on the original system first. Disagreement (44 failing tests on the original) showed up before the rebuild could paper over it.

Worth avoiding

What failed

What happened Where What to do on the next run
An evidence file described a fix the pull request did not contain. Parks, LOG-002. The implementation pull request changed docs/pr-evidence.md only. Refuse an implementation pull request that does not touch a path named in the ticket or the feature file.
The signed slice was narrower than the assessment, and the pipeline then reported the finding shipped. Parks logging and test findings; restitution VULN-004. When the specification drops part of the original expected result, write that down as an accepted gap and leave a follow-up. Keep it out of the “fixed” tally.
GitHub Actions sat on action_required until a person pushed an empty commit. Restitution, repeated from the first slices. Budget operator time for workflow approval, or pre-approve the agent’s identity. This ate more human attention than reading the diffs.
A standing CodeQL failure trained the run to ignore a red gate. Restitution, from the middle of the backlog onward. Split the security checks so a known residual cannot mask a new Trivy or test failure.
Coding-agent credits ran out, and the operator became the builder. Restitution, findings 30 through 36. Put a project budget on the run before the first slice. A backlog that depends on a monthly seat cap will stop in the middle.
A generated backlog was closed without merge. LEAR. 41 pull requests closed, one enrolment merge, the first real slice waiting on a person. Do not open the second slice until a named owner has merged the first. Agents are instructed not to merge themselves, and that rule is the point.
The receipt collector reported missing reviews that were actually there. Parks. Review-receipt miss rate sat at 100%, then 75%, because the collector skipped evidence files when the pull request title lacked a tag. Fix the measure before you manage to it. A red metric that is a parser bug will get ignored, and then a real miss will too.
The rebuild’s results table has a full run for the original system and none for the new one. Marketplace, results ledger, 4 Oct 2026. Publish one end-to-end pass/fail row for the new application beside the original. Slice-level “every claimed criterion passes” is necessary and is not that row.

External case

Ministry of Transportation CIS remediation

This work belongs to Rogene Lacanienta’s team at Transportation and Transit. It is the external case we most wanted in a paper other teams could use: a Java 8 Struts system, lifted with agents, with a person in the centre of the loop. This page does not describe their method, their timeline, or their results. Those details stay with the team that did the work until Rogene agrees they can be published.

For another team

How to try the patterns

Start from a repository you can afford to be wrong about. Fork it, or rebuild it beside the original. Enrol the pipeline, file one finding or one slice, and merge it yourself before you let a backlog run. The public repositories below are the ones that were public on 9 October 2026.

Repository What you will find
alex-struk/agentic-sdlc The pipeline the Marketplace rebuild installed: skills, checks, workflows, and a runner a project takes by reference.
bcgov/digital-marketplace-next The greenfield record. Read the README, then spec/, plan/tasks.md, and site/gates.md. Local run instructions are in the README. Invented seed data only.
bcgov/bcparks-ar-admin-agentic-b The completed parks remediation, including the metrics issues and the evidence-only miss.
bcgov/pssg-cscp-restitution-agentic The restitution remediation on development, including the operator adjustments in the pull request history.
bcgov/lear-agentic The run that stopped at the first human merge. Useful before you scale a backlog.
bcgov/tier1-pattern-test A small public enrolment of the thinner automation: issue triage, docs drift, and a comment on a failed build.
bcgov/tier2-pattern-test A small public enrolment of the checkpointed pattern, for teams that want the gates before they want a full rebuild.

Alberta’s papers, if you want the pattern in their words: the four approaches and the factory case study.

A reasonable first week is one repository, one owner, and one finding that already has a test. If that pull request cannot be reviewed by someone who would be on the hook in production, the rest of the backlog will reproduce LEAR: a queue of proposals and a single merged enrolment.