JavaScript governance

# Architectural governance for AI-assisted JavaScript development

Vanilla JavaScript and Node.js codebases — especially long-lived ones that pre-date the TypeScript migration — have all the same architectural drift problems as TypeScript repos, with fewer guardrails. Mneme provides the same repository, dependency, and workflow governance without assuming a type system.

Tier 1 · Operationally supported

## What governance looks like in JavaScript

Mature JavaScript codebases — Express APIs, legacy React or Vue frontends, long-running Node services — concentrate the drift problem. The TypeScript compiler isn't there to catch the regressions, ESLint covers style rather than architecture, and AI coding agents have plenty of room to re-introduce patterns the team already retired.

Four concrete examples of what the governance layer catches in JavaScript repos under AI-assisted development:

### CommonJS / ESM module-system drift

Architecture

Rule. ADR-012 migrated `services/` to ESM. No `require()` in that subtree.

    // AI-generated in services/billing/invoice.js
    const Stripe = require("stripe");
    const { db } = require("../db");

    module.exports = async function chargeInvoice(invoice) {
      ...
    };

module-system regression ADR-012 violation

### Business logic inside Express route handler

Layer boundary

Rule. Express handlers must delegate to services. No pricing, tax, or inventory logic inline.

    // AI-generated in routes/checkout.js
    app.post("/checkout", async (req, res) => {
      // pricing logic
      const subtotal = req.body.items.reduce((s, i) => s + i.price * i.qty, 0);
      // tax logic
      const tax = subtotal * 0.0875;
      // inventory mutation, payment call, email send...
      res.json({ total: subtotal + tax });
    });

logic in presentation layer missing service abstraction

### Raw SQL string concatenation

Security

Rule. No template-literal SQL. Use parameterized queries via the approved DB client.

    // AI-generated in services/user.js
    async function findUser(userId) {
      const query = `SELECT * FROM users WHERE id = ${userId}`;
      return db.query(query);
    }

unsafe query construction secure coding rule breach

### Cron job written outside the approved scheduler

Platform

Rule. ADR-018 standardized on Cloud Scheduler + Pub/Sub. No `node-cron` for new scheduled work.

    // AI-generated in jobs/cleanup.js
    const cron = require("node-cron");

    cron.schedule("0 3 * * *", async () => {
      await cleanupExpiredSessions();
    });

bypassing approved infra workflow platform standard breach

## Current capabilities

#### What works today

- Repository-level governance (paths, scopes, ownership)
- Architectural boundary enforcement at the file/require/import level
- Forbidden dependency checks (`package.json`)
- Agent workflow governance across Cursor, Claude Code, Copilot, Cline
- CI gating via GitHub Actions
- Workspace / monorepo scope enforcement

#### Not yet

- AST-aware rules (no Babel/Acorn integration)
- Type-level constraints (no language-server hook)
- Framework-specific policy packs (Express, Hapi, NestJS)
- React component-level enforcement
- ESLint plugin integration

## Where it fits in a JavaScript codebase

Identical to the TypeScript flow: decision corpus at `.mneme/project_memory.json`, hooks on file write, `mneme check --mode strict` in CI. The benefit for JS-heavy teams is sharper: most JS codebases lack the compile-time guardrails of TS, so the governance layer is doing relatively more work.

See the Cursor integration, GitHub Actions integration, and CLI reference.

Sibling TypeScript governance → Same model with TypeScript-flavored examples (Next.js, Zustand, monorepos). Full matrix Coverage across all languages → Canonical doc with capabilities, limitations, and roadmap per language. What it catches Governance violations → Twelve worked examples organized by category, not by language.