# Proxy Scripts Constitution ## Core Principles ### I. Monolithic Architecture (NON-NEGOTIABLE) **ALL business logic, data processing, authentication, and request handling MUST exist within the `src/proxyScripts/proxy.js` file.** Pure utility/helper functions MAY be extracted to `src/globalVariables/adapterHelper.js` if they improve code organization. The `server.js` file should ONLY handle: - HTTP server setup - Configuration loading - Global object injection into isolated context - Loading src/proxyScripts/proxy.js via `vm.Script` and `vm.createContext` - Loading src/globalVariables/adapterHelper.js via `vm.Script` (optional) - Per-request context creation with all necessary globals **Implementation via vm.Script**: `src/proxyScripts/proxy.js` MUST be loaded using Node.js `vm.Script` and executed in isolated contexts created per-request with `vm.createContext`. This ensures: - Complete isolation from server.js module system - All dependencies provided explicitly through context objects - Zero ability to import/export modules - Pure functional execution with injected dependencies **Rationale**: Monolithic architecture enables simple packaging as a single IVA Studio proxy script and prevents fragmentation of business logic across multiple files. Using `vm.Script` enforces architectural boundaries at runtime, making it impossible for `src/proxyScripts/proxy.js` to access Node.js module system or file system, ensuring ALL functionality exists in one isolated, dependency-injected file. **Helper Functions Pattern**: Pure utility functions (XML escaping, validation, formatting, routing) MAY be extracted to `src/globalVariables/adapterHelper.js` to improve readability and maintainability. The helpers module: - MUST be loaded via `vm.Script` (same isolation as proxy.js) - MUST evaluate to a single JavaScript object with all helper functions - MUST have ZERO imports/exports - Is injected as `adapterHelper` global object into VM context - Contains ONLY pure utilities, NO business logic or state ### I. Zero External Imports or Exports from `src/proxyScripts/proxy.js` (NON-NEGOTIABLE) `src/proxyScripts/proxy.js` MUST have **ZERO import statements**. All dependencies MUST be provided through `vm.createContext` by server.js. `src/proxyScripts/proxy.js` MUST have **ZERO export statements**. The file MUST be pure JavaScript code executed in an isolated VM context. **File system access** from `src/proxyScripts/proxy.js` is **ABSOLUTELY PROHIBITED** under any circumstances. The `fs` module MUST NOT be accessible. **External libraries** (axios, jwt, googleapis, etc.) MUST NOT be imported. Dependencies are injected through VM context by server.js. **Rationale**: Using `vm.Script` and `vm.createContext` enforces architectural boundaries at the VM level. src/proxyScripts/proxy.js runs in an isolated context with NO access to Node.js module system, file system, or process globals. ALL dependencies must be explicitly injected per-request through the context object, ensuring src/proxyScripts/proxy.js contains ONLY pure business logic with zero capability for I/O operations. **For data files that src/proxyScripts/proxy.js needs** (service account keys, certificates, secrets): 1. Place JSON files in `src/globalVariables/` directory 2. server.js loads them at startup using `loadGlobalObjects()` 3. server.js injects them into VM context per-request via `vm.createContext` 4. src/proxyScripts/proxy.js accesses them as simple variables in context (e.g., `adapter_settings`) **Example**: - File: `src/globalVariables/adapter_settings.json` - Loading: server.js reads and assigns to `globalVariableContext.adapter_settings` - Injection: server.js adds `adapter_settings: globalVariableContext.adapter_settings` to context - Access in src/proxyScripts/proxy.js: Direct variable access `adapter_settings.serviceAccount` **Enforcement**: - src/proxyScripts/proxy.js MUST have NO `import` statements (file should start with comments, then code) - src/proxyScripts/proxy.js MUST have NO `export` statements (no module.exports, no export keyword) - Any `import` or `export` in src/proxyScripts/proxy.js MUST be rejected immediately - server.js MUST load src/proxyScripts/proxy.js using `vm.Script` constructor - server.js MUST execute via `script.runInContext(context)` with fresh context per request - All dependencies injected through `vm.createContext({ ... })` context object - VM isolation prevents access to require(), import(), fs, process, and Node.js globals #### I.0 Forbidden Globals in proxy.js (NON-NEGOTIABLE) `src/proxyScripts/proxy.js` MUST NOT access ANY infrastructure configuration globals. The following are **ABSOLUTELY PROHIBITED**: - ❌ `config` - Infrastructure settings (server port, proxy paths, logging level) - ❌ `global.config` - Global configuration object - ❌ `process.env` - Environment variables (these are server concerns, not business logic) **ONLY the following globals are permitted** in `src/proxyScripts/proxy.js`: - ✅ `console` - Custom logger (injected by server.js) - ✅ `crypto` - Web Crypto API for randomUUID() - ✅ `axios` - HTTP client for API calls - ✅ `jwt` - JSON Web Token library for authentication - ✅ `xmlBuilder` - XML document builder - ✅ `uuidv4` - UUID generator - ✅ `adapterHelper` - Helper functions (loaded from src/globalVariables/) - ✅ `adapter_settings` - Business data only (service account, Drive query, sitemap settings) - ✅ `req` - HTTP request object (includes req.params with routing metadata) - ✅ `res` - HTTP response object **Rationale**: Infrastructure configuration (server ports, proxy routing, deployment settings) is the responsibility of server.js, NOT business logic. proxy.js implements document export logic - it should NOT know about HTTP server configuration, proxy path prefixes, or deployment details. These are injected via `req.params` when needed for routing. **If routing information is needed** (e.g., proxy path prefix for route parsing): 1. server.js MUST parse the incoming request URL 2. server.js MUST extract routing metadata (workspaceId, branch, routeName) 3. server.js MUST add this to `req.params` before invoking proxy.js 4. proxy.js accesses routing info via `req.params`, NOT via `config` **Example of correct routing metadata injection**: ```javascript // server.js - BEFORE invoking proxy.js if (global.config.proxy) { const { pathPrefix, workspaceId, branch, routeName } = global.config.proxy; const fullPrefix = `${pathPrefix.replace(/\/$/, '')}/${workspaceId}/${branch}/${routeName}`; if (req.url.startsWith(fullPrefix)) { req.params = { "0": req.url, // Original path workspaceId, // Extracted from config branch, // Extracted from config route: routeName // Extracted from config (renamed to 'route') }; } } ``` **Enforcement**: - Any reference to `config` in proxy.js MUST be rejected - Any reference to `global.config` in proxy.js MUST be rejected - Any reference to `process.env` in proxy.js MUST be rejected - Routing metadata MUST be passed via `req.params`, never via `config` - Code reviews MUST verify zero infrastructure globals in proxy.js #### I.I What MUST Be in src/proxyScripts/proxy.js The following MUST be implemented in `src/proxyScripts/proxy.js` (or extracted to adapterHelper.js if pure utilities): 1. **Authentication**: Service Account JWT, OAuth flows, token management (MUST be in proxy.js) 2. **Business Logic**: All request handling, routing, and processing (MUST be in proxy.js) 3. **Data Transformation**: Document parsing, XML generation, data mapping (MUST be in proxy.js or adapterHelper.js) 4. **API Integration**: Drive API queries, error mapping, response handling (MUST be in proxy.js) 5. **Request Queue**: FIFO queue for sequential processing (MUST be in proxy.js) 6. **Utility Functions**: Request ID generation, validation, XML escaping, date formatting (MAY be in adapterHelper.js) 7. **Error Handling**: All error mapping and HTTP status code logic (MAY be in adapterHelper.js) **Helper Extraction Guidelines**: - ✅ **CAN extract**: Pure functions, validators, formatters, XML utilities, error mappers, route parsers - ❌ **MUST NOT extract**: Authentication, API calls, request queue, cached state, business decisions **NO EXCEPTIONS for business logic** - Even complex authentication (OAuth 2.0, JWT) must be in proxy.js. #### I.II What Can Be Separate Files ONLY the following infrastructure modules may exist outside `src/proxyScripts/proxy.js`: 1. **src/logger.js**: Structured logging with console replacement (ONLY logging, no business logic) 2. **src/server.js**: HTTP server bootstrap and configuration (ONLY server setup, no business logic) 3. **config/**: JSON configuration files (data files, not code) 4. **src/globalVariables/**: JSON data files AND adapterHelper.js module - `*.json`: Runtime data loaded at startup (credentials, settings) - `adapterHelper.js`: Pure utility functions loaded via vm.Script (OPTIONAL) 5. **src/proxyScripts/**: Directory containing the main proxy script (proxy.js) **Test files are exempt** - Test utilities may exist solely for test compatibility if needed, but MUST NOT be imported by production code. **File Structure**: ``` src/ ├── proxyScripts/ │ └── proxy.js # Main business logic (authentication, API, queue) ├── globalVariables/ │ ├── *.json # Data files for VM context │ └── adapterHelper.js # Pure utility functions (OPTIONAL) ├── logger.js # Structured logging └── server.js # HTTP server bootstrap config/ └── default.json # Infrastructure settings ``` **adapterHelper.js Pattern (Literal Function Body)**: - MUST be loaded using `vm.Script` (same isolation as proxy.js) - MUST contain LITERAL FUNCTION BODY with `return` statement (NOT valid standalone JS) - server.js wraps it: `(function() { })()` - Function body returns a single JavaScript object containing all exports - MUST have ZERO imports/exports (pure vm.Script execution) - Loaded by `loadGlobalVariables()` which scans for both JSON and JS files - Filename determines global key: `adapterHelper.js` → `globalVariableContext.adapterHelper` - Injected as `adapterHelper` global object into VM context - Contains ONLY pure utilities: validators, formatters, XML, error mappers - MUST NOT contain: authentication, API calls, state, business decisions - Executed in context with full access to globalVMContext and globalVariableContext #### I.III Enforcement During code review and planning: - ANY file in `src/proxyScripts/` besides `proxy.js` MUST be challenged - ANY file in `src/globalVariables/` besides `adapterHelper.js` and `*.json` MUST be challenged - ANY file in `src/` besides `proxyScripts/`, `globalVariables/`, `logger.js`, `server.js` MUST be challenged - Authentication, even if complex, MUST be in `src/proxyScripts/proxy.js` (never in adapterHelper.js) - Business logic MUST be in `src/proxyScripts/proxy.js` (never in adapterHelper.js) - Exceptions require explicit constitutional justification with measurable trade-offs - When in doubt about helpers extraction, keep it in `src/proxyScripts/proxy.js` **RED FLAGS to reject immediately:** - Separate files for: auth, database, utilities, helpers, services, controllers, models - Any file containing business logic or domain knowledge - Multiple files "organizing" the codebase #### I.IV Configuration - Configuration for the Node.js web server infrastructure should be stored as JSON in `config/default.json`. - `config/default.json` MUST contain ONLY infrastructure settings: server (host, port), logging level - `config/default.json` MUST NOT contain authentication credentials, secrets, API keys, or behavioral configuration - Authentication credentials, secrets, and ALL behavioral configuration MUST be stored in `src/globalVariables/` directory as JSON files - Global JSON files are automatically loaded by server.js and made available as global objects - server.js should validate both configuration from `config/default.json` AND global objects from `src/globalVariables/` directory #### I.V Global Objects Provided by server.js The `server.js` file MUST inject the following objects into VM context for use by `src/proxyScripts/proxy.js`: **VM Context Injection Pattern:** server.js uses a spread operator pattern for cleaner context creation: ```javascript // Define static VM context (libraries and built-ins) const globalVMContext = { URLSearchParams, URL, console: logger, crypto, axios, uuidv4, jwt, xmlBuilder, }; // Load dynamic data from src/globalVariables/ directory let globalVariableContext = {}; // Populated by loadGlobalVariables() // Load all global variables (JSON data + JS function modules) at startup loadGlobalVariables(); // Pattern: // 1. Single-pass scan of globalVariables/ for *.json and *.js files (excluding *.example.*) // 2. Categorize into jsonFiles and jsFiles arrays // 3. Load JSON files first (data) → globalVariableContext[filename] // 4. Load JS files second (functions) → globalVariableContext[filename] // 5. JS files execute in context with {...globalVMContext, ...globalVariableContext} // Example: adapterHelper.js returns object → globalVariableContext.helpers = object // Example: adapter_settings.json → globalVariableContext.adapter_settings = data // Per-request: Create fresh context with all dependencies const context = vm.createContext({ ...globalVMContext, // Spread static dependencies ...globalVariableContext, // Spread dynamic data (JSON + function modules) req, // Fresh request object res // Fresh response object }); script.runInContext(context); ``` **Note:** src/proxyScripts/proxy.js accesses these as direct variables (e.g., `adapter_settings`, not `globalThis["adapter_settings"]`). The VM context makes all properties available as top-level variables. **Core Infrastructure Context Variables:** 1. **console** - Custom logger from `logger.js` - Purpose: Structured JSON logging - Usage: `console.info()`, `console.debug()`, `console.error()` - Injected from: `globalVMContext.console` (set to `logger`) 2. **crypto** - Web Crypto API (built-in) - Purpose: UUID generation, cryptographic operations - Usage: `crypto.randomUUID()`, etc. - Injected from: `globalVMContext.crypto` - Note: Web Crypto API available by default in Node.js 3. **axios** - HTTP client library - Purpose: Making HTTP requests to external APIs - Usage: `axios.get(url)`, `axios.post(url, data)` - Package: `axios` - Injected from: `globalVMContext.axios` 4. **uuidv4** - UUID v4 generator - Purpose: Generate RFC4122 compliant UUIDs - Usage: `uuidv4()` returns string like "110ec58a-a0f2-4ac4-8393-c866d813b8d1" - Package: `uuid` (v4 function only) - Injected from: `globalVMContext.uuidv4` 5. **jwt** - JSON Web Token library - Purpose: Creating and verifying JWTs for authentication - Usage: `jwt.sign(payload, secret)`, `jwt.verify(token, secret)` - Package: `jsonwebtoken` - Injected from: `globalVMContext.jwt` 6. **xmlBuilder** - XML builder/generator - Purpose: Constructing XML documents programmatically - Usage: `xmlBuilder({ root: { child: 'value' } })` - Package: `xmlbuilder2` (create function) - Injected from: `globalVMContext.xmlBuilder` **Built-in Web APIs:** 7. **URLSearchParams** - URL query string parser (built-in) - Purpose: Parse and manipulate URL query strings - Usage: `new URLSearchParams(queryString)` - Injected from: `globalVMContext.URLSearchParams` 8. **URL** - URL parser (built-in) - Purpose: Parse and manipulate URLs - Usage: `new URL(urlString)` - Injected from: `globalVMContext.URL` - Note: Currently not included in globalVMContext but available in Node.js by default **Dynamic Data Context Variables:** 9. **Dynamic JSON objects from src/globalVariables/ directory** - Purpose: Authentication credentials, secrets, API keys, and behavioral configuration - Pattern: Each `src/globalVariables/filename.json` loaded by server.js → added to `globalVariableContext` → spread into VM context - Examples: - `src/globalVariables/adapter_settings.json` → context variable `adapter_settings` (consolidated service account, scopes, drive query, sitemap config) - `src/globalVariables/api-keys.json` → context variable `api_keys` (API keys and secrets) - `src/globalVariables/custom-config.json` → context variable `custom_config` (behavioral settings) - Usage in src/proxyScripts/proxy.js: Direct variable access `const settings = adapter_settings;` - Loading: By server.js at startup using `loadGlobalObjects()` function - Injection: Via spread operator `...globalVariableContext` in `vm.createContext()` - **Note**: ALL authentication, secrets, and behavioral configuration MUST be in src/globalVariables/, NEVER in config/default.json **Helper Functions Module:** 10. **adapterHelper** - Pure utility functions object (OPTIONAL) - Purpose: Extracted helper functions for code organization - Source: `src/globalVariables/adapterHelper.js` loaded via `vm.Script` - Loading: server.js loads via `loadGlobalVariables()` at startup - **Literal Function Body Pattern**: - File contains LITERAL BODY of a function (NOT valid standalone JavaScript) - Uses bare `return {...}` statement to export object - server.js wraps it: `const wrappedCode = '(function() {\n' + code + '\n})()'` - Creates IIFE that executes function body and captures returned object - Pattern separates content (file) from execution wrapper (server) - Example file structure: ```javascript // File: src/globalVariables/adapterHelper.js // This is a LITERAL FUNCTION BODY (not valid standalone JS) class DocumentCountExceededError extends Error { constructor(message) { super(message); this.name = 'DocumentCountExceededError'; } } function generateRequestId() { return `req_${crypto.randomUUID()}`; } // ... more functions ... return { DocumentCountExceededError, generateRequestId, // ... all exports }; ``` - server.js wrapping logic: ```javascript const wrappedCode = `(function() {\n${code}\n})()`; const script = new vm.Script(wrappedCode, { filename: file }); const context = vm.createContext({...globalVMContext, ...globalVariableContext}); const returnedObject = script.runInContext(context); globalVariableContext[varName] = returnedObject; ``` - Generic Loading Pattern: - All .js files in globalVariables/ are loaded automatically - Filename determines key: `adapterHelper.js` → `globalVariableContext.adapterHelper` - Executed in tempContext with `{...globalVMContext, ...globalVariableContext}` - Can access all VM globals: axios, jwt, crypto, console, etc. - Can access previously loaded JSON data and function modules - Injection: Spread into VM context via `...globalVariableContext` - Usage in src/proxyScripts/proxy.js: `adapterHelper.functionName()` (e.g., `adapterHelper.generateRequestId()`) - Contains: Pure utilities only (validators, formatters, XML, error mappers, route parsers) - MUST NOT contain: Authentication, API calls, state, business logic - Example functions: - `adapterHelper.generateRequestId()` - UUID generation - `adapterHelper.validateDocumentId(id)` - Document ID validation - `adapterHelper.escapeXml(str)` - XML character escaping - `adapterHelper.generateSitemap(docs, baseUrl)` - Sitemap generation - `adapterHelper.mapDriveErrorToHttp(error)` - Error mapping - `adapterHelper.parseRoute(method, url)` - Route parsing - `adapterHelper.DocumentCountExceededError` - Custom error class - Generic Pattern Note: You can add more .js files (e.g., `utils.js`, `validators.js`) and they will be automatically loaded as `globalVariableContext.utils`, etc. **Request/Response Objects:** 11. **req** - HTTP IncomingMessage - Purpose: Access request data (URL, method, headers, body) - Injected fresh: Per-request from `http.createServer((req, res) => ...)` 12. **res** - HTTP ServerResponse - Purpose: Send response to client - Injected fresh: Per-request from `http.createServer((req, res) => ...)` **Rationale**: Using `vm.createContext` with spread operator pattern for dependency injection achieves: - **Runtime-enforced isolation** - src/proxyScripts/proxy.js physically cannot access Node.js module system or file system - **Zero imports possible** - VM context has no `require()` or `import()` capability - **Explicit dependencies** - All available objects must be explicitly listed in globalVMContext or globalVariableContext - **Clean organization** - Static dependencies (globalVMContext) separated from dynamic data (globalVariableContext) - **Per-request isolation** - Fresh context per request prevents cross-request state leakage - **Testing simplicity** - Mock entire context object instead of individual module imports - **Clear contracts** - Context spread pattern documents every dependency src/proxyScripts/proxy.js uses - **Security boundaries** - VM sandbox prevents escape to underlying system - **DRY principle** - Spread operators eliminate repetitive property declarations #### I.VI Logging Modify server.js to replace the global `console` object with the `logger` export from `logger.js`. This will make all console.log, console.info, console.error calls throughout the application use the custom logger. Logging should use `logger.js` module that has the following functions: - log - which defaults to the 'info' function - info - which writes to stdout - debug - which prefixes the output with "[DEBUG]" written in red font and writes to stdout - error - which prefixes the output with "[ERROR]" written in red font and writes to stderr ### II. API-First Design Every feature MUST expose a clear, documented API before implementation begins. APIs MUST follow RESTful principles where applicable, use consistent naming conventions, and include comprehensive error handling with meaningful status codes and messages. **Rationale**: API-first design ensures contracts are stable, enables parallel front-end/back-end work, facilitates integration testing, and produces naturally documented systems. ### III. Test-First Development (NON-NEGOTIABLE) Test-Driven Development is MANDATORY for all production code. The cycle MUST be: 1. Write failing tests 2. Obtain user approval of test scenarios 3. Implement minimum code to pass tests 4. Refactor while maintaining green tests Unit tests MUST achieve minimum 80% code coverage. Integration tests MUST cover all API contracts and critical user flows. **Rationale**: TDD catches defects early, documents expected behavior, enables confident refactoring, and ensures all code paths are exercised. ### IV. Security & Privacy by Default All user data MUST be treated as sensitive. OAuth tokens, credentials, and personal information MUST be encrypted at rest and in transit. The principle of least privilege MUST govern all access controls. Audit logging MUST track all data access and modifications. **Rationale**: Privacy violations damage trust and carry legal liability. Security must be foundational, not retrofitted. ### V. Observability & Debuggability All operations MUST emit structured logs with appropriate severity levels (DEBUG, INFO, WARN, ERROR). Errors MUST include context (request IDs, user IDs, operation names) sufficient for diagnosis. Performance-critical paths MUST expose metrics (latency, throughput, error rates). **Rationale**: Production issues are inevitable. Observable systems reduce mean time to resolution and enable proactive problem detection. ### VI. Semantic Versioning & Change Management All public APIs MUST follow semantic versioning (MAJOR.MINOR.PATCH): - MAJOR: Breaking changes that require consumer updates - MINOR: Backward-compatible feature additions - PATCH: Backward-compatible bug fixes Breaking changes MUST include migration guides and deprecation notices for at least one MINOR version before removal. **Rationale**: Clear versioning communicates impact, enables safe upgrades, and respects downstream consumers' need for stability. ### VII. Simplicity, Minimal Dependencies & YAGNI Implement only features with demonstrated need. Choose the simplest solution that satisfies current requirements. Reject premature optimization and speculative features. Complexity MUST be explicitly justified with measurable benefits. **Dependency Minimization**: Prefer Node.js built-in modules over external npm packages. Each external dependency MUST be justified by: - Significant functionality that would take >2 days to implement correctly - Active maintenance and security track record - Clear, documented benefit that outweighs maintenance risk Prohibited without explicit approval: - Utility libraries for functionality Node.js provides natively (fs, path, crypto, http, etc.) - Heavy framework dependencies when lightweight alternatives exist - Multiple packages solving the same problem **Rationale**: External dependencies introduce supply chain risk, increase bundle size, complicate auditing, and create maintenance burden. Node.js built-ins are stable, well-tested, and maintained by the platform. ## API Design Standards All external APIs MUST: - Accept and return JSON for structured data - Use standard HTTP methods (GET, POST, PUT, DELETE, PATCH) semantically - Return appropriate HTTP status codes (2xx success, 4xx client errors, 5xx server errors) - Include rate limiting headers where applicable - Version endpoints explicitly (e.g., /v1/, /v2/) - Document all parameters, responses, and error codes using OpenAPI/Swagger Response formats MUST be consistent and include: - Timestamp of response generation - Request correlation ID for tracing - Pagination metadata for list operations - Clear error messages with actionable guidance ## Security & Data Protection Authentication & Authorization MUST: - Never log or expose credentials, tokens, or API keys - Validate all input to prevent injection attacks - Apply rate limiting to prevent abuse Data Handling MUST: - Minimize data retention—delete temporary files promptly - Encrypt sensitive data using industry-standard algorithms (AES-256 or equivalent) - Sanitize all user-supplied content before processing - Implement CSRF protection for web interfaces ## Development Workflow Code Reviews MUST: - Verify alignment with all constitutional principles - Check test coverage meets minimum thresholds - Validate API contracts match documentation - Confirm security best practices are followed Quality Gates (ALL must pass before merge): - All tests pass (unit, integration, end-to-end) - Code coverage ≥ 80% - No critical security vulnerabilities (use automated scanning) - Documentation updated for API/behavior changes - Performance regression checks pass Deployment MUST: - Use automated CI/CD pipelines - Include smoke tests post-deployment - Support rollback within 5 minutes - Include release notes documenting all changes ## Technology Stack **Platform**: Node.js (LTS version or later) **Mandatory Baseline**: - Use Node.js built-in modules as first choice (fs, path, crypto, http, https, stream, util, url, querystring, etc.) - **DO NOT use 'events' EventEmitter** - implement simple patterns directly (e.g., Promise-based queues) - Plain JavaScript (ES2022+) without TypeScript - JSDoc comments for type documentation where needed - JavaScript tooling (ESLint, Prettier) does not count against dependency budget - Native test runner (node:test) or minimal test framework **Dependency Approval Process**: Any external npm package (excluding JavaScript tooling like ESLint and Prettier) MUST be justified in the feature specification with: 1. **Functionality gap**: What Node.js built-ins cannot do 2. **Implementation cost**: Estimated effort to build vs. maintain dependency 3. **Risk assessment**: Package security, maintenance history, download stats 4. **Alternatives considered**: Why alternatives were rejected **Examples of acceptable dependencies** (when justified): - xmlbuilder2 - axios - uuid **Examples of prohibited dependencies** (use Node.js built-ins or inline implementations instead): - lodash/underscore (use native Array/Object methods) - moment/date-fns (use native Date, Intl.DateTimeFormat) - rimraf (use fs.rm with recursive: true) - mkdirp (use fs.mkdir with recursive: true) - **EventEmitter from 'events'** (implement simple queue classes directly - no need for event system) - express/fastify (use native http/https for simple servers **Node.js built-in modules to prefer:** - Use 'node:' prefix for clarity: `import crypto from 'node:crypto'` - Acceptable built-ins: fs, path, crypto, http, https, stream, util, url, querystring, etc. - NOT acceptable: 'events' EventEmitter - implement patterns directly without event system IMPORTANT : All dependencies that are not acceptable must be approved when running plan and task agents ## Governance This constitution supersedes all other development practices and guidelines. When conflicts arise between this document and team conventions, the constitution takes precedence. Amendments to this constitution require: 1. Documented justification explaining the need for change 2. Impact analysis of affected systems and workflows 3. Approval from project maintainers 4. Migration plan for any breaking changes 5. Update of version number following semantic versioning rules All pull requests, code reviews, and design discussions MUST verify compliance with constitutional principles. Exceptions MUST be rare, explicitly justified with measurable trade-offs, and documented in the relevant specification or plan. For runtime development guidance, refer to `.github/prompts/` and `.github/agents/` files which operationalize these principles into agent workflows. **Version**: 1.14.0 | **Ratified**: 2026-03-05 | **Last Amended**: 2026-03-07