20260601 - From No Tests to Safe Refactors Debug Logging + AI Agents for Legacy AL
Areopa webinar (a rerun of a Days of Knowledge talk) on using AI agents to refactor legacy AL code safely. It covers compiler and linter feedback with warnings treated as errors, and debug logging by intercepting feature telemetry through a test-app telemetry logger that writes JSONL files in the container. It also covers temporary approval (characterization) tests, agent-run mutation testing, and a TDD loop using wrapper procedures. These are presented as a development workflow, not as product features.
- Webinar introduction and housekeeping
- Speaker introduction and background
- Problem statement - legacy code and brownfields projects
- AI capabilities and challenges in code generation
- Making AI deterministic - compilation and static analysis
- Linters, complexity rules, and test-driven development
- Automated testing and CI/CD integration
- Understanding legacy code behavior
- Mapping procedure behavior and test coverage
- Enabling agents to see code execution paths
- Debug logging implementation with telemetry
- Automating test verification and path detection
- Approval tests and safe refactoring foundations
- Mutation testing introduction and purpose
- Mutation testing execution with agent automation
- Test-driven development loop and refactoring workflow
- Wrapper procedures and test compatibility during refactoring
- Agent economics and cascading benefits of clean code
- Ensuring agent compliance with instructions and hooks
- Test setup and agent learning for refactoring
- Code quality rules and refactoring practices
- Debug logging and feature telemetry safety nets
- Mutation testing with AI agents
- Temporary vs permanent test coverage
- Real unit tests and bug discovery in refactoring
- Closing remarks and webinar information
Overview
The webinar covers brownfield AL projects where a lot of legacy code exists and AI agents are used to refactor it. It starts by making agent output more deterministic: compile after every change, use linters including complexity rules, treat warnings as errors with a ruleset file, and run automated tests in CI/CD.
The main part is a workflow for code with no tests. Debug log markers in if statements and cases are written as JSONL files inside the container through the feature telemetry logger interface, so an agent can see which code paths a test ran, without the 2-5 minute delay of Application Insights. Approval tests capture existing behavior, bugs included. Mutation testing, run by an agent, checks that scenarios are really covered. A TDD loop and wrapper procedures then let the same tests validate old and new implementations. The speaker also covers keeping characterization tests temporary and replacing them with real unit tests.
Key points
- Compile after every agent change and use complexity linters, so overly long procedures cause compiler errors. Pair this with the command-line option to treat warnings as errors and a ruleset file.
- Debug logging implements the telemetry logger interface in a test app with the same publisher. This intercepts feature telemetry and writes JSONL files inside the container. The files are available immediately, unlike Application Insights with its 2 to 5 minute delay. The call is asynchronous and does not block code.
- Debug log markers in if statements and cases show which code paths a test hit. They replace manual breakpoint debugging, and a CI/CD check fails on feature telemetry messages starting with debug, so markers are not shipped.
- Approval (characterization) tests record existing behavior and let bugs pass, so refactoring stays one-to-one. They are temporary because they need heavy setup and database access and run slowly.
- Mutation testing changes one production code element at a time to confirm a test fails. The agent writes a mutation plan for critical paths, the developer reviews it, and the agent runs the compile, publish, test, revert cycle using git from a clean repository. This can take an hour or two.
- Wrapper procedures with the same signature route calls to the old or new implementation, so the same approval tests validate both.
- After refactoring, write real unit and integration tests. Bugs found in the legacy code are listed and fixed only after the refactor is complete.
Features
| Feature | Status | At |
|---|---|---|
| AI code generation for legacy AL refactoring | status not stated | 7:17 |
| Compilation as first-pass validation for AI agents | status not stated | 10:08 |
| Static analysis linters for code quality | status not stated | 10:46 |
| Complexity linters for procedure length control | status not stated | 11:42 |
| Warning-as-errors compiler option with ruleset files | status not stated | 12:16 |
| Test-driven development with AI agents | status not stated, demoed | 13:08 |
| Build automation and CI/CD for agent loops | status not stated | 14:27 |
| Debug logging via telemetry interception | status not stated, demoed | 21:04 |
| Observational test patterns for code discovery | status not stated, demoed | 25:49 |
| Automated path coverage verification | status not stated, demoed | 25:49 |
| Approval testing for refactoring preparation | status not stated, demoed | 27:36 |
| Mutation testing for scenario coverage verification | status not stated, demoed | 28:58 |
| Test-driven development loop in refactoring | status not stated, demoed | 33:04 |
| Wrapper procedures for safe refactoring | status not stated, demoed | 34:31 |
| Agent-assisted economics of safe refactoring | status not stated | 35:45 |
| Large language model selection for AL code | status not stated | 37:42 |
| Git hooks for agent instruction enforcement | status not stated | 38:40 |
| Tests as project documentation for agents | status not stated | 40:04 |
| AI Agent for test execution and verification | status not stated | 39:09 |
| Leave codebase better rule | status not stated | 40:49 |
| Touch code only when necessary | status not stated | 41:31 |
| AI-assisted test development playbook | status not stated | 41:52 |
| Debug logging with feature telemetry safety nets | status not stated | 44:24 |
| AI-generated mutation testing plans | status not stated | 46:28 |
| Characterization testing for legacy code | status not stated | 49:22 |
| Real unit and integration tests after refactoring | status not stated | 50:31 |
| Bug discovery during decoupling and refactoring | status not stated | 51:25 |
AL objects mentioned
As heard in the captions. A name that matches one object page by exact type and name links to it; the others stay as named.
- other “MCP server” at 12:16
- interface “telemetry logger interface” at 22:49
- codeunit “test telemetry logger” at 22:49
- other “CI/CD check” at 44:58
- other “feature telemetry” at 45:11
- other “mutation plan” at 47:05
- other “AL test framework” at 42:27
Not found in BC28-30: interface “telemetry logger interface”, codeunit “test telemetry logger”.
Quotes
- 5:52 “This is projects that where already exist a lot of code and you are supposed to make another feature, fix a bug, do some”
- 6:09 “If you are in in the same circles as I am, then there is a lot of legacy AL code.”
- 7:17 “We have got an AI and AI is really good at writing very very fast code and not code that uh that executes fast”
- 8:07 “Every one of the things that AI actually is really good at is understanding uh the principles behind uh testdriven development writing test and”
- 10:08 “Every time she makes a change ask it to compile uh the app and and that can be done nowhere you have test or”
Disclaimers in the video
- 37:54 subject-to-change: pump instructions are big a and a models are nondeterministic
- 49:09 other: Stefan Mavan has built something for containerless test for unit test working with his AL test
Presenters (as heard): Fleming Buckson, Luke, Thorban Lat, Stefan Mavan.
