| name | dak-dfm-check |
| description | Inspect and validate Delphi DFM forms via `dfm-inspect`, `dfm-check`, or `build --dfmcheck`. Use whenever Codex touches Delphi forms, frames, datamodules, visual controls, event bindings, or any `.dfm`-backed UI change, even if the user only asks for a UI edit. |
Delphi DFM Check
Use this skill whenever we touch Delphi forms, frames, datamodules, or any .dfm-backed UI changes.
Mandatory Policy
- After every form-related change, run DFM validation before we finalize work.
- Prefer
build --dfmcheck when we are already building the project.
- Use
dfm-check standalone when we only need DFM validation.
- Treat any
FAIL line as a critical error and fix it immediately.
- Do not skip, suppress, or defer DFM failures.
- Do not call
msbuild directly; use DelphiAIKit.exe orchestration commands only.
- Treat source
.dpr, .dproj, .pas, and .dfm files as read-only inputs. DAK may rewrite only its generated clone under .dak/<ProjectName>/dfm-check/runs/<RunId>/generated/.
- Never redirect or copy DFM-check generated clones into
.agents/; they are DAK-owned disposable state, not agent memory.
Environment Contract (same as dak-build)
Use the same environment variables as dak-build:
DAK_EXE (required): absolute path to DelphiAIKit.exe
DAK_BUILD_SH (optional, WSL convenience)
Preflight:
test -x "$DAK_EXE" || { echo "DAK_EXE not executable"; exit 1; }
if grep -qi microsoft /proc/version 2>/dev/null; then
if [ -n "${DAK_BUILD_SH:-}" ]; then
test -x "$DAK_BUILD_SH" || { echo "DAK_BUILD_SH is set but not executable"; exit 1; }
fi
fi
Canonical Commands
Lightweight text-DFM inspection:
"$DAK_EXE" dfm-inspect --dfm "<path-to-form.dfm>" --format tree
"$DAK_EXE" dfm-inspect --dfm "<path-to-form.dfm>" --format summary
Use dfm-inspect when we need to understand the component tree, key event bindings, or basic form shape before editing.
It is not a substitute for dfm-check; inspection is optional, validation is mandatory.
Standalone DFM validation:
"$DAK_EXE" dfm-check --dproj "<path-to-project.dproj>" --config Release --platform Win32
Optional:
--delphi 23.0 (or provide [Build] DelphiVersion in cascading dak.ini)
--rsvars "<path-to-rsvars.bat>"
--dfm "MainForm.dfm,Frames\DetailSubEditDocs.dfm" (selected forms only)
--all (validate all forms; default when --dfm is omitted)
--source-context auto|off|on (default auto; emit nearby source lines on failure when DAK can resolve them)
--source-context-lines N (default 2; number of lines before/after the hit)
--verbose true (show stage logs and per-form progress in --all mode)
Build with integrated DFM validation:
"$DAK_EXE" build --project "<path-to-project.dproj>" --delphi 23.0 --platform Win32 --config Release --dfmcheck
--dfmcheck is a presence flag. If present, DFM validation runs after successful build.
For broader build workflow and options, use dak-build skill.
Defaults:
config=Release
platform=Win32
- for DelphiAiKit itself, pass
--platform Win64
Success/Failure Contract
- Non-verbose output is concise:
FAIL lines + summary + final result.
- Verbose output includes stage markers and full validator output.
- In
--all --verbose, validator prints progress lines as CHECK <current>/<total> <resource>.
- When source context is enabled, handler/declaration failures append a bounded nearby snippet after the existing clue lines.
- Exit code
0: all streamable DFM resources are valid.
- Exit code
>0: one or more DFM streams failed; this blocks completion.
- In
--all, unchanged forms may be skipped via <Project>.dfmcheck.cache in the .dproj directory.
- Generated validators exclude the
madExcept define only in the isolated DPROJ clone; the source DPROJ and DPR remain byte-for-byte unchanged.
- DAK writes generated blocker units for the standard madExcept startup units. If project units still link madExcept code unconditionally, DAK exits with an actionable instruction to wrap all related
uses entries and calls in {$IFNDEF DFMCheck} ... {$ENDIF}.
- Generated build and validator processes use a 30-minute default timeout. Set
DAK_DFMCHECK_TIMEOUT_MS to a positive millisecond value to override it.
Remediation Rules (required)
When validation reports FAIL, we must fix DFM-related issues and re-run validation until exit code is 0.
Typical fixes:
- Remove or correct stale properties in
.dfm that no longer exist in the class.
- Restore missing published properties/components expected by the
.dfm.
- Align renamed controls/components between
.pas and .dfm.
- Re-run
dfm-check (or build --dfmcheck) after each fix batch.
- For
DAK_DFMCHECK_MADEXCEPT, guard every madExcept-related uses entry and call in application units:
uses
System.SysUtils,
{$IFNDEF DFMCheck}
madExcept,
madLinkDisAsm,
madListHardware,
madListProcesses,
madListModules,
{$ENDIF}
Vcl.Forms;
Apply the same guard to related initialization/finalization calls. Do not remove madExcept from the real application project merely to satisfy validation.
Task completion gate:
- Do not finish form-related tasks while DFM validation is failing.
- After the final gate, remove only verified stale/successful generated run directories according to DAK's retention behavior. Keep the current failure artifacts while they are still needed for diagnosis.