# Legacy Rules: ASP Classic, VB6, and VBScript 1. **Explicit Cleanup:** Always clean up COM objects and Recordsets explicitly: ```vbscript If Not (rs Is Nothing) Then If rs.State = 1 Then rs.Close Set rs = Nothing End If If Not (conn Is Nothing) Then If conn.State = 1 Then conn.Close Set conn = Nothing End If ``` 2. **Option Explicit:** Ensure `Option Explicit` is present at the top of all VBScript and VB6 modules. 3. **Safe Parameterization:** Never concatenate input strings into ADO SQL statements. Use `ADODB.Command` with `CreateParameter`. 4. **Error Handling:** Avoid blanket `On Error Resume Next` without an immediate check. In a RouteKit-based app (see rule 6), route the error through `ErrorHandler().HandleError(context, Err)` / `CheckAndHandle(context)` (`core/lib.ErrorHandler.asp`) rather than writing bespoke log code — it already logs to the flat file at `ErrorLogPath` when `EnableErrorLogging` is `true` (both set in `public/web.config`, recorded in `.devfoundry/references/environments.md`). Outside that framework, log every handled error to the flat log file documented in `.devfoundry/references/environments.md` ("Legacy Error Log" section) — one line per error with timestamp, source module/function, `Err.Number`, and `Err.Description`: ```vbscript On Error Resume Next ' Risky call If Err.Number <> 0 Then ' Append a line to the flat error log path from environments.md, then: Err.Clear End If On Error GoTo 0 ``` 5. **Driver Awareness:** Confirm 32-bit vs 64-bit ODBC/OLEDB driver compatibility before deploying changes touching Access databases. 6. **Architecture / Framework:** All new ASP Classic web applications (and substantial rework of existing ones) use the **RouteKit Classic ASP MVC framework** — see `.devfoundry/references/asp-classic-framework.md` for its directory layout, controller/migration/repository generator workflow, DAL usage, and error-handling/testing conventions. Follow that reference's "Adding a Feature" order (migration → repo/model → controller → wiring) rather than hand-rolling routing, data access, or error handling. Never modify files under `core/` — extend only inside `app/`. For a one-off script or non-web utility with no controller/view involved, plain `.asp`/`.vbs`/`.bas` modules with the concern-separation described previously are still fine. 7. **Design by Contract:** Functions/subs (in `.vbs`, `.bas`, `.cls`) validate their input parameters at entry and set `Err.Raise` or return an explicit error/status rather than proceeding on unchecked assumptions; document expected pre/postconditions in a comment above the function signature. 8. **TDD:** In a RouteKit-based app, the `tests/` `aspunit` harness (see `.devfoundry/references/asp-classic-framework.md`) is a real test harness — write the failing `aspunit` test first, add it to `tests/test-manifest.asp`, confirm it fails for the right reason, then implement only enough to pass it. For any other project with a test harness (e.g., a VB6 unit-test framework or a script-based test runner), do the same with that harness. If no harness exists at all, write the exact manual verification steps (inputs, expected output, expected error behavior) in the spec before writing the code — this is the required TDD-equivalent artifact and must exist before implementation begins.