# AGENTS.md ## Purpose This file defines the development rules, architecture standards, safety requirements, and agent behavior for this project. All AI coding agents working in this repository must read this file before making changes. The primary development environment is: - ASP Classic - VBScript - ADODB - IIS - HTML/CSS/JavaScript - SQL Server, Microsoft Access, SQLite, or another configured database VBScript provides limited compile-time validation, weak typing, limited object-oriented features, and minimal runtime safeguards. AI agents must compensate for these limitations through: - strict conventions - defensive programming - architectural boundaries - validation - testing - code inspection - documentation - controlled self-improvement --- # 1. Core Principle The AI agent must behave as more than a code generator. It must act as: - developer - architect - static analyzer - compiler substitute - security reviewer - code reviewer - documentation maintainer - test author - project historian The agent must actively look for problems that VBScript itself may not catch. --- # 2. Instruction Priority When instructions conflict, follow this priority: 1. Explicit user instructions 2. Security and data protection requirements 3. This AGENTS.md file 4. Project architecture documentation 5. Existing project conventions 6. Existing implementation patterns 7. Agent preferences Never weaken security, validation, or data integrity simply to match poor legacy code. If legacy code conflicts with these standards, preserve compatibility where required while gradually improving the implementation. --- # 3. Mandatory VBScript Rules ## 3.1 Option Explicit Every ASP, VBS, and applicable WSC script must use: ```vbscript Option Explicit ``` No undeclared variables are permitted. Before finishing a task, inspect all changed code for undeclared or misspelled identifiers. --- ## 3.2 Variable Declaration All variables must be explicitly declared using an appropriate declaration: ```vbscript Dim Private Public Const ``` Avoid excessive variable reuse. Prefer descriptive names. Bad: ```vbscript Dim x Dim y ``` Better: ```vbscript Dim customerId Dim orderTotal ``` --- ## 3.3 Variant Safety VBScript uses Variants extensively. Do not assume that a value has the expected type. External values must be normalized near application boundaries. Use explicit conversion where appropriate: ```vbscript CStr() CLng() CInt() CDbl() CBool() CDate() ``` Never convert unvalidated input blindly. Validate first when conversion can fail. --- # 4. Null, Empty, and Nothing These are different states and must not be treated as equivalent. Use: ```vbscript IsNull(value) IsEmpty(value) object Is Nothing ``` Database values may contain `Null`. Uninitialized Variants may contain `Empty`. Object references may contain `Nothing`. Code must explicitly account for the state that is expected. Do not rely on accidental VBScript coercion. --- # 5. Request Data Is Untrusted Treat all external input as untrusted, including: - Request.Form - Request.QueryString - Request.Cookies - Request.ServerVariables - HTTP headers - uploaded files - JSON payloads - XML payloads - API data - database data originating from users - Session values derived from user input External data must pass through: ```text Input ↓ Validation ↓ Normalization ↓ Authorization ↓ Business Logic ``` Never pass raw Request values directly into database or business operations. --- # 6. SQL Rules ## 6.1 Parameterization Is Mandatory User-controlled data must never be concatenated into SQL. Prohibited: ```vbscript sql = "SELECT * FROM Users WHERE Email = '" & email & "'" ``` Required: ```vbscript Set cmd = Server.CreateObject("ADODB.Command") Set cmd.ActiveConnection = conn cmd.CommandText = _ "SELECT UserId, Email " & _ "FROM Users " & _ "WHERE Email = ?" cmd.Parameters.Append _ cmd.CreateParameter("@Email", adVarWChar, adParamInput, 255, email) ``` Use parameters for: - SELECT - INSERT - UPDATE - DELETE - stored procedure calls --- ## 6.2 Dynamic SQL When identifiers such as table names or sort columns must be dynamic, they cannot normally be parameterized. In such cases, use a whitelist. Example: ```vbscript Select Case sortField Case "Name", "CreatedDate", "Status" ' allowed Case Else sortField = "CreatedDate" End Select ``` Never accept arbitrary table names, column names, or SQL fragments from users. --- # 7. Output Encoding HTML output must be encoded by default. Prefer: ```vbscript Server.HTMLEncode(value) ``` or a centralized helper such as: ```vbscript Function H(value) If IsNull(value) Then H = "" Else H = Server.HTMLEncode(CStr(value)) End If End Function ``` Raw HTML output should only be used when the value is explicitly trusted and intentionally contains HTML. Do not assume database data is safe to output without encoding. --- # 8. Error Handling ## 8.1 On Error Resume Next Broad use of: ```vbscript On Error Resume Next ``` is prohibited. It may only be used around the smallest practical operation requiring error interception. Required pattern: ```vbscript On Error Resume Next Set rs = cmd.Execute() If Err.Number <> 0 Then errorNumber = Err.Number errorDescription = Err.Description Err.Clear On Error GoTo 0 LogError errorNumber, errorDescription Err.Raise _ vbObjectError + 1000, _ "CustomerRepository.GetCustomer", _ "Database operation failed." End If On Error GoTo 0 ``` Always restore normal error handling. --- ## 8.2 Never Hide Failures Do not silently ignore: - failed database operations - failed file operations - invalid conversions - failed COM object creation - authorization failures - missing required configuration Failures must either: - be handled intentionally, or - be logged and propagated appropriately --- # 9. Architecture The preferred application flow is: ```text HTTP Request ↓ Router ↓ Controller ↓ Service ↓ Repository ↓ Database ``` Views receive prepared data from controllers or ViewModels. --- # 10. Controller Rules Controllers may: - read Request data - invoke validation - invoke services - prepare ViewModels - redirect - select views - set HTTP status codes - write responses through response abstractions Controllers must not: - contain SQL - implement significant business logic - directly manage recordsets - duplicate validation rules - construct complex HTML - hide application failures Keep controllers thin. --- # 11. Service Rules Services contain application and business logic. Services may: - coordinate repositories - enforce business rules - perform calculations - enforce workflow rules - call domain-specific collaborators Services must not: - access Request directly - access Response directly - generate HTML - contain raw SQL - depend unnecessarily on ASP global state Prefer dependency injection through explicit initialization. --- # 12. Repository Rules Repositories own persistence logic. Repositories may: - execute ADODB commands - map records to models - create parameterized queries - manage database-specific concerns Repositories must not: - access Request - access Response - generate HTML - contain UI rules --- # 13. View Rules Views may: - render HTML - display ViewModel data - use simple formatting helpers Views must not: - execute SQL - create database connections - contain major business logic - make authorization decisions - perform complex data transformations Encode dynamic output by default. --- # 14. Models and ViewModels Models should represent application or domain data. ViewModels should represent data specifically prepared for a view. Do not pass ADODB.Recordset objects directly into views unless the existing architecture explicitly requires it and refactoring is not currently practical. Prefer converting recordsets into application-friendly structures. --- # 15. Dependency Management VBScript does not provide modern dependency injection. Use explicit initialization. Example: ```vbscript Class CustomerService Private m_repository Private m_logger Public Sub Init(repository, logger) Set m_repository = repository Set m_logger = logger End Sub End Class ``` Dependencies should be visible. Avoid hidden global dependencies where practical. --- # 16. Composition Over Inheritance VBScript has limited inheritance capabilities. Prefer composition. Instead of designing deep pseudo-inheritance systems, compose objects from smaller collaborators. Example: ```text CustomerService ├── CustomerRepository ├── CustomerValidator └── Logger ``` --- # 17. Interface Conventions VBScript cannot formally declare interfaces. When interchangeable implementations are needed, define a documented contract. Example: ```text IUserRepository Required members: GetById(userId) GetByEmail(email) Create(user) Update(user) Delete(userId) ``` Agents must verify that implementations satisfy documented contracts. --- # 18. Object Initialization Use `Class_Initialize` only for safe initialization that requires no external dependencies. Use an explicit method such as: ```vbscript Public Sub Init(...) ``` for dependency injection. Classes should not secretly fetch dependencies from globals when explicit injection is practical. --- # 19. Session and Application State Avoid storing custom COM objects, recordsets, service instances, or application classes in: ```vbscript Session Application ``` Prefer primitive values: ```vbscript Session("UserId") = CLng(userId) Session("Username") = CStr(username) ``` Use Application state carefully and protect shared writes appropriately. --- # 20. ADODB Resource Management Explicitly close database resources. Example: ```vbscript If Not rs Is Nothing Then If rs.State <> 0 Then rs.Close End If Set rs = Nothing End If ``` Connections must also be closed when owned by the current operation. Do not leave recordsets or connections open unnecessarily. --- # 21. Connection Ownership The project should clearly define who owns a database connection. A method that opens a connection is normally responsible for closing it. Do not close a connection owned by another component unless the contract explicitly states that responsibility. --- # 22. Small Functions Prefer small cohesive procedures. Target guideline: ```text Function: 10–40 lines where practical Class: 100–300 lines where practical Controller: preferably under 200 lines ``` These are guidelines, not absolute limits. When code becomes difficult to understand, split it by responsibility. --- # 23. Naming Conventions Use consistent naming because VBScript is case-insensitive and offers limited compiler assistance. Preferred examples: ```text customerId customerName orderRepository customerService isValid hasPermission ``` Class names: ```text CustomerService CustomerRepository CustomerValidator OrderController ``` Private fields may use: ```text m_repository m_logger m_customerId ``` Follow established project conventions if they are consistent and clear. --- # 24. Boolean Naming Prefer names that read naturally: ```text isValid isActive hasAccess hasPermission canDelete shouldRetry ``` Avoid ambiguous names such as: ```text flag value1 test status2 ``` --- # 25. Magic Values Avoid unexplained magic values. Bad: ```vbscript If status = 4 Then ``` Better: ```vbscript Const STATUS_COMPLETED = 4 ``` Use constants or centralized configuration where appropriate. --- # 26. Configuration Environment-specific settings must not be scattered throughout application code. Centralize: - connection strings - filesystem paths - URLs - email settings - feature flags - API keys - environment names Secrets must not be committed to source control. --- # 27. Logging Important errors should be logged with useful context. Prefer structured information such as: ```text Timestamp RequestId UserId if appropriate Component Operation Error number Error description Relevant safe context ``` Never log: - passwords - authentication tokens - full credit card data - secret keys - highly sensitive personal data unless explicitly necessary and protected --- # 28. Authentication and Authorization Authentication answers: ```text Who is this user? ``` Authorization answers: ```text Is this user allowed to perform this operation? ``` They are not interchangeable. Authorization must be enforced server-side. Never rely solely on hidden buttons, JavaScript, or UI restrictions. --- # 29. CSRF Protection State-changing requests should use CSRF protection where practical. This includes: - POST - PUT-like actions - DELETE-like actions - administrative operations Do not perform destructive actions solely through unprotected GET requests. --- # 30. HTTP Method Semantics Prefer: ```text GET → retrieve data POST → create/change state ``` Avoid state-changing GET endpoints unless required by legacy compatibility. --- # 31. Redirect Safety Do not redirect to arbitrary user-provided URLs. Validate redirects against: - known internal routes - allowed hosts - approved paths --- # 32. File Handling Uploaded files must be treated as untrusted. Validate: - filename - extension - actual content where practical - size - target path - permissions Prevent path traversal. Never construct filesystem paths directly from arbitrary user input. --- # 33. Include File Discipline Includes are dependencies, not architecture. Avoid large global include chains. Prefer explicit grouped includes such as: ```text /config /framework /app/controllers /app/services /app/repositories /app/models /app/views ``` Before adding a new include, check whether the functionality belongs in an existing component. --- # 34. Shared Utilities Before creating a utility function, search for an existing implementation. Common shared helpers may include: ```text HtmlEncode JsonEncode JsonEscape Nz ToInteger ToLong ToBoolean ToDate ValidateEmail ExecuteScalar ExecuteNonQuery Logger UrlEncode GenerateGuid ``` Do not create duplicate helpers with slightly different behavior. --- # 35. JSON Do not build complex JSON through unsafe string concatenation. Use the project's JSON serializer or centralized JSON utilities. Escape: - quotes - backslashes - control characters - line breaks Ensure output is valid JSON. --- # 36. JavaScript Boundaries Server-side validation is mandatory even when client-side validation exists. JavaScript validation is for user experience. VBScript validation is for correctness and security. Never trust browser-side validation alone. --- # 37. Testing Expectations Every significant change should be evaluated for testability. Where practical, create tests for: - validation - business rules - conversions - repositories - security-sensitive logic - regressions Business logic should be separated from ASP globals so it can be tested independently. --- # 38. Regression Prevention When fixing a bug: 1. understand the root cause 2. identify the violated invariant 3. fix the underlying problem 4. add or update a test where practical 5. search for similar occurrences elsewhere 6. update documentation if the rule was previously unclear Do not patch symptoms repeatedly. --- # 39. Agent Pre-Change Procedure Before modifying code, the agent should: 1. Read this AGENTS.md. 2. Read CLAUDE.md if present. 3. Inspect the relevant project files. 4. Search for existing implementations. 5. Understand the dependency direction. 6. Identify security implications. 7. Determine whether tests exist. 8. Avoid creating duplicate abstractions. For small changes, do this proportionally. --- # 40. Agent Post-Change Review Before declaring work complete, review changed code for: - missing Option Explicit - undeclared variables - misspelled identifiers - missing Set statements - incorrect parameter counts - Null handling - Empty handling - Nothing handling - unsafe implicit conversion - SQL injection - unparameterized SQL - XSS - missing HTML encoding - unsafe redirects - path traversal - authorization bypass - broad On Error Resume Next - swallowed errors - open recordsets - open database connections - excessive global state - duplicate utilities - architectural boundary violations - unreachable code - dead code - missing cleanup - poor naming --- # 41. Missing Set Check VBScript requires `Set` for object assignment. Agents must specifically inspect object assignments. Incorrect: ```vbscript repo = New CustomerRepository ``` Correct: ```vbscript Set repo = New CustomerRepository ``` This should be part of every static review. --- # 42. Return Value Check VBScript functions return values by assigning to the function name. Example: ```vbscript Function AddNumbers(a, b) AddNumbers = a + b End Function ``` Agents must verify all execution paths return the expected value when a return value is required. --- # 43. ByRef Awareness VBScript parameters are `ByRef` by default. This can unintentionally mutate caller values. Prefer explicitly declaring intent. Use: ```vbscript Function ValidateCustomer(ByVal customer) ``` when modification of the caller's variable is not intended. Use `ByRef` intentionally. --- # 44. Parentheses and Call Syntax VBScript procedure-call syntax can be confusing. Agents must generate syntactically valid VBScript calls. Be especially careful with: - `Call` - parentheses - functions used for return values - Subs invoked without `Call` Prefer simple consistent calling patterns. --- # 45. Date Handling Do not assume date string formats. Prefer true Date values internally. Validate and convert input explicitly. Be aware of: - server locale - database date formats - regional settings Use parameterized database values rather than embedding formatted date strings in SQL. --- # 46. Numeric Handling Do not assume values from Request are numeric. Validate before conversion. Example logic: ```text Read input ↓ Trim ↓ Check required/optional ↓ Validate numeric format ↓ Convert ``` Handle overflow and invalid values appropriately. --- # 47. Database Null Mapping When mapping database records to models, define expected behavior for Null fields. Do not allow arbitrary Null propagation unless the domain explicitly permits it. Consider centralized helpers. --- # 48. Performance ASP Classic is synchronous. Avoid unnecessary: - database round trips - repeated queries inside loops - filesystem calls - external HTTP requests - COM object creation - large Session values Watch for N+1 query patterns. Prefer set-based SQL. --- # 49. Caching Caching may be used where appropriate but must have: - clear ownership - expiration behavior - invalidation rules - concurrency awareness Never cache sensitive per-user data globally without proper separation. --- # 50. Application State Concurrency ASP `Application` state can be shared across requests. When modifying shared Application values, consider: ```vbscript Application.Lock Application.Unlock ``` Keep locked regions minimal. --- # 51. Backward Compatibility When modifying legacy code: 1. identify existing behavior 2. determine whether other code depends on it 3. preserve public contracts where practical 4. avoid unrelated rewrites 5. improve internals incrementally Do not modernize code purely for style if it introduces unnecessary risk. --- # 52. Refactoring Rule Refactoring should preserve observable behavior unless changing behavior is an explicit goal. Separate: ```text behavior change ``` from: ```text structural cleanup ``` where practical. --- # 53. Documentation Rule When introducing: - a new architecture convention - a new shared component - a new security requirement - a new dependency - a new recurring coding pattern update relevant documentation. Do not leave important architectural knowledge only in source code. --- # 54. Self-Improvement System This file is allowed to evolve. Agents may propose or make updates to AGENTS.md when project experience reveals that the instructions are: - incomplete - outdated - ambiguous - repeatedly violated - causing bugs - missing an important security rule - missing an architectural convention - inconsistent with the actual project - superseded by a better proven pattern Self-improvement must be controlled. --- # 55. When the Agent Should Update AGENTS.md Consider updating this file when: 1. the same mistake occurs more than once 2. a bug reveals a missing development rule 3. a new framework component establishes a reusable pattern 4. a new security requirement becomes necessary 5. project architecture materially changes 6. a repeated manual review step can become an explicit rule 7. a legacy convention is officially replaced 8. new infrastructure becomes standard 9. a user explicitly establishes a permanent project rule Do not update this file for trivial one-time implementation details. --- # 56. Self-Update Safety An agent must never silently weaken these core protections: - parameterized SQL - output encoding - authorization - input validation - controlled error handling - explicit variable declarations - Option Explicit - resource cleanup - security boundaries Changes affecting these protections require explicit justification. --- # 57. Rule Classification Rules may be considered: ```text CORE PROJECT ADVISORY TEMPORARY ``` CORE rules should rarely change. Examples: ```text CORE: SQL parameterization Option Explicit server-side authorization output encoding PROJECT: folder structure repository naming routing conventions ADVISORY: function length guidelines TEMPORARY: migration-specific compatibility rules ``` When adding an important rule, identify its conceptual category if useful. --- # 58. Learning From Bugs After fixing a significant bug, ask: ```text Could a rule have prevented this? ``` If yes: - update AGENTS.md, or - update a specialized project document, or - add a test, or - improve a framework abstraction Prefer systemic prevention over repeated manual correction. --- # 59. Learning From Code Review If a code review repeatedly identifies the same problem, convert the feedback into: - an explicit agent rule - a reusable helper - a test - an architectural constraint The goal is continuous reduction of repeated mistakes. --- # 60. Update History Meaningful changes to AGENTS.md should be recorded below. Keep entries concise. Format: ```text YYYY-MM-DD - Added rule: - Reason: ``` Example: ```text 2026-09-02 - Added explicit ByVal guidance. - Reason: VBScript defaults to ByRef and accidental mutations were difficult to detect. ``` --- # 61. Do Not Turn This File Into a Dumping Ground AGENTS.md should contain durable development knowledge. Do not store: - task-specific notes - temporary debugging output - one-time TODOs - credentials - secrets - personal information - giant code examples Move specialized guidance into focused files when this file becomes too large. --- # 62. Specialized Skills As the project grows, agents may create focused guidance such as: ```text /docs/architecture.md /docs/security.md /docs/database.md /docs/testing.md /skills/asp-classic.md /skills/adodb.md /skills/security.md /skills/testing.md ``` AGENTS.md remains the central index and policy authority. --- # 63. Creating New Skills Agents may create a new skill or focused guidance document when: - a task is repeated frequently - the knowledge is specialized - the instructions are too detailed for AGENTS.md - the process can be reused - consistent execution would materially improve quality A new skill should state: ```text Purpose When to use it Inputs Procedure Rules Validation Common failure modes Output expectations ``` --- # 64. Updating Existing Skills When project behavior changes, update the existing relevant skill instead of creating a duplicate. Before creating a new document, search for an existing location for that knowledge. --- # 65. Agent Decision Journal For major architectural changes, record concise rationale in the appropriate documentation. Document: ```text Decision Context Alternatives Reason selected Consequences ``` Do not record private chain-of-thought. Record only useful engineering rationale. --- # 66. Definition of Done A task is not complete merely because the code runs. A change is complete when appropriate checks have been performed for: ```text Correctness Security Architecture Compatibility Validation Error handling Resource cleanup Testing Documentation Maintainability ``` --- # 67. Final Agent Checklist Before finishing a coding task, answer internally: ```text [ ] Did I read the relevant instructions? [ ] Did I inspect existing code before creating new code? [ ] Did I preserve architecture boundaries? [ ] Is all external input validated? [ ] Is SQL parameterized? [ ] Is dynamic HTML encoded? [ ] Is authorization enforced server-side? [ ] Are errors handled intentionally? [ ] Are database resources cleaned up? [ ] Are object assignments using Set? [ ] Did I account for Null, Empty, and Nothing? [ ] Did I account for ByRef behavior? [ ] Did I avoid unnecessary global state? [ ] Did I avoid duplicating utilities? [ ] Did I update tests where appropriate? [ ] Did I update documentation if a durable rule changed? [ ] Did this task reveal something the agent rules should learn? ``` --- # 68. Guiding Philosophy Do not fight VBScript. Compensate for its weaknesses. Prefer simple, explicit, understandable code over clever abstractions. The desired result is: ```text Classic ASP simplicity + strict engineering discipline + AI-assisted static review + modern security practices = maintainable ASP Classic applications ``` --- # Update History 2026-09-02 - Initial ASP Classic/VBScript AI development policy created. - Added controlled self-improvement rules. - Added architecture, security, validation, ADODB, error handling, testing, and agent review requirements.