Files
google-drive-content-adapter/.specify/memory/constitution.md
Peter.Morton c094d4d472 Remove IIFE wrapper from googleDriveAdapterHelper.js
Changed from IIFE pattern to direct object literal evaluation

Rationale:
- Global variable functions should evaluate to an object directly
- IIFE wrapper was unnecessary complexity
- Simpler pattern: code evaluates to object, not function that returns object
- Matches intended architecture for vm.Script module loading

Changes:
1. Removed IIFE wrapper:
   - Before: (function createHelpers() { ... return {...} })()
   - After: ({ ... })

2. Removed function indentation (2 spaces throughout file)

3. Updated constitution.md:
   - Pattern description: 'IIFE returning object' → 'evaluates to a single object'
   - Clarified: 'not wrapped in IIFE'
   - Updated all pattern references

Structure:
- File defines classes and functions at top level
- Final expression is object literal referencing all functions
- When executed via vm.Script, evaluates to the object
- Object is assigned to globalVariableContext.googleDriveAdapterHelper

Benefits:
 Simpler pattern (no function wrapper)
 Clearer intent (direct object evaluation)
 Matches architecture description
 Easier to understand and maintain
 Same functionality, cleaner implementation

Before (IIFE):

After (Object Literal):

Testing:
✓ Syntax validated
✓ Server starts successfully
✓ Module loads: 'Loaded global functions: googleDriveAdapterHelper'
✓ All function calls work correctly
✓ Request handling works as expected

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-07 12:06:13 -06:00

36 KiB

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/googleDriveAdapterHelper.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/googleDriveAdapterHelper.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/googleDriveAdapterHelper.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 googleDriveAdapterHelper 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., google_drive_settings)

Example:

  • File: src/globalVariables/google_drive_settings.json
  • Loading: server.js reads and assigns to globalVariableContext.google_drive_settings
  • Injection: server.js adds google_drive_settings: globalVariableContext.google_drive_settings to context
  • Access in src/proxyScripts/proxy.js: Direct variable access google_drive_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.I What MUST Be in src/proxyScripts/proxy.js

The following MUST be implemented in src/proxyScripts/proxy.js (or extracted to googleDriveAdapterHelper.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 googleDriveAdapterHelper.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 googleDriveAdapterHelper.js)
  7. Error Handling: All error mapping and HTTP status code logic (MAY be in googleDriveAdapterHelper.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 googleDriveAdapterHelper.js module
    • *.json: Runtime data loaded at startup (credentials, settings)
    • googleDriveAdapterHelper.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
│   └── googleDriveAdapterHelper.js        # Pure utility functions (OPTIONAL)
├── logger.js             # Structured logging
└── server.js             # HTTP server bootstrap
config/
└── default.json          # Infrastructure settings

googleDriveAdapterHelper.js Pattern:

  • MUST be loaded using vm.Script (same isolation as proxy.js)
  • MUST evaluate to a single JavaScript object (not wrapped in IIFE)
  • MUST have ZERO imports/exports (pure vm.Script execution)
  • Loaded by loadGlobalVariables() which scans for both JSON and JS files
  • Filename determines global key: googleDriveAdapterHelper.jsglobalVariableContext.googleDriveAdapterHelper
  • Injected as googleDriveAdapterHelper 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 googleDriveAdapterHelper.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 googleDriveAdapterHelper.js)
  • Business logic MUST be in src/proxyScripts/proxy.js (never in googleDriveAdapterHelper.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:

// 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: googleDriveAdapterHelper.js returns object → globalVariableContext.helpers = object
//   Example: google_drive_settings.json → globalVariableContext.google_drive_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., google_drive_settings, not globalThis["google_drive_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:

  1. URLSearchParams - URL query string parser (built-in)

    • Purpose: Parse and manipulate URL query strings
    • Usage: new URLSearchParams(queryString)
    • Injected from: globalVMContext.URLSearchParams
  2. 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:

  1. 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/google_drive_settings.json → context variable google_drive_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 = google_drive_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:

  1. googleDriveAdapterHelper - Pure utility functions object (OPTIONAL)
    • Purpose: Extracted helper functions for code organization
    • Source: src/globalVariables/googleDriveAdapterHelper.js loaded via vm.Script
    • Loading: server.js loads via loadGlobalVariables() at startup
    • Generic Loading Pattern:
      • All .js files in globalVariables/ are loaded automatically
      • Filename determines key: googleDriveAdapterHelper.jsglobalVariableContext.helpers
      • 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: googleDriveAdapterHelper.functionName() (e.g., googleDriveAdapterHelper.generateRequestId())
    • Contains: Pure utilities only (validators, formatters, XML, error mappers, route parsers)
    • MUST NOT contain: Authentication, API calls, state, business logic
    • Example functions:
      • googleDriveAdapterHelper.generateRequestId() - UUID generation
      • googleDriveAdapterHelper.validateDocumentId(id) - Document ID validation
      • googleDriveAdapterHelper.escapeXml(str) - XML character escaping
      • googleDriveAdapterHelper.generateSitemap(docs, baseUrl) - Sitemap generation
      • googleDriveAdapterHelper.mapDriveErrorToHttp(error) - Error mapping
      • googleDriveAdapterHelper.parseRoute(method, url) - Route parsing
      • googleDriveAdapterHelper.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:

  1. req - HTTP IncomingMessage

    • Purpose: Access request data (URL, method, headers, body)
    • Injected fresh: Per-request from http.createServer((req, res) => ...)
  2. 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