How to Configure Custom Quality Gates in AIOX Beyond the Default npm run lint, typecheck, and test

You configure custom quality gates in AIOX by adding new command or script entries to .aiox-core/core/quality-gates/quality-gate-config.yaml and implementing Node.js modules that export a Promise-returning function adhering to the { passed: boolean, summary: string } contract.

The SynkraAI/aiox-core repository provides a three-layer Quality Gate system that executes automatically before commits and pull requests. While the default pipeline runs npm run lint, npm run typecheck, and npm test, the architecture is deliberately plug-in-friendly, enabling you to configure custom quality gates that enforce security scans, custom linters, or manual review checklists.

Understanding the AIOX Quality Gate Architecture

AIOX orchestrates quality gates through the QualityGateManager (.aiox-core/core/quality-gates/quality-gate-manager.js). This manager reads declarative configurations from .aiox-core/core/quality-gates/quality-gate-config.yaml and dynamically loads implementations using Node.js require.

The system operates across three distinct layers:

  1. Layer 1 – Pre-Commit: Fast static checks (lint, type-check) implemented in layer1-precommit.js. Extend by adding command entries.
  2. Layer 2 – PR Automation: CI-level validations (unit tests, integration tests) implemented in layer2-pr-automation.js. Extend by registering script modules.
  3. Layer 3 – Human Review: Manual or semi-automated review steps orchestrated via human-review-orchestrator.js. Extend by declaring review-tasks with optional interactive: true flags.

Each layer respects the same execution contract: the manager invokes your module and expects a Promise resolving to an object with passed (boolean) and summary (string) properties. Because the manager simply requires the paths listed in the config, you can drop any executable Node.js module into the quality-gates directory and AIOX will treat it as a new gate.

Step-by-Step Configuration of Custom Quality Gates

Editing the YAML Configuration File

The central configuration lives in .aiox-core/core/quality-gates/quality-gate-config.yaml. To add a gate, append an entry to the appropriate layer array:

  • Use command for shell commands (Layer 1).
  • Use script for Node.js module paths (Layers 2 and 3).
  • Use interactive: true for Layer 3 gates requiring human input.

Implementing the Gate Logic Contract

Create a JavaScript file that exports a single function. This function must return a Promise that resolves to an object with:

  • passed: Boolean indicating success or failure.
  • summary: String describing the outcome for CLI and UI display.

The manager automatically invokes this function during *push and *pre-push workflows defined in bin/aiox.js.

Practical Examples for Each Quality Gate Layer

Layer 1 Example – Adding a Custom ESLint Rule Set (Pre-Commit)

Add a custom linting step that runs alongside the default npm run lint.

Update quality-gate-config.yaml:

layer1:
  - name: lint
    command: "npm run lint"
  - name: custom-eslint
    command: "node .aiox-core/core/quality-gates/custom-eslint.js"
    description: "Run project-specific ESLint rules"

Implement .aiox-core/core/quality-gates/custom-eslint.js:

const { exec } = require('child_process');

/**
 * Executes a custom ESLint command.
 * Must return {Promise<{passed: boolean, summary: string}>}
 */
module.exports = () => new Promise((resolve) => {
  exec('npx eslint src --config .eslintrc.custom.js', (err, stdout, stderr) => {
    if (err) {
      resolve({
        passed: false,
        summary: `Custom ESLint failures:\n${stderr || stdout}`,
      });
    } else {
      resolve({ passed: true, summary: 'Custom ESLint passed.' });
    }
  });
});

Now every pre-push executes both the default linter and your custom rules.

Layer 2 Example – Integrating a Security Scanner (PR Automation)

Block pull requests containing vulnerable dependencies by adding a Layer 2 gate.

Update quality-gate-config.yaml:

layer2:
  - name: test
    command: "npm test"
  - name: scan-dependencies
    script: "./.aiox-core/core/quality-gates/dependency-scan.js"
    description: "OWASP Dependency-Check on node_modules"

Implement .aiox-core/core/quality-gates/dependency-scan.js:

const { exec } = require('child_process');

module.exports = async () => {
  return new Promise((resolve) => {
    exec('npx retire --outputformat json', (err, stdout) => {
      if (err) {
        resolve({
          passed: false,
          summary: `Dependency scan found issues:\n${stdout}`,
        });
      } else {
        const results = JSON.parse(stdout);
        if (results.length) {
          resolve({
            passed: false,
            summary: `Vulnerable packages detected:\n${JSON.stringify(results, null, 2)}`,
          });
        } else {
          resolve({ passed: true, summary: 'No vulnerable dependencies.' });
        }
      }
    });
  });
};

This gate executes automatically after unit tests, preventing merges when security issues exist.

Layer 3 Example – Creating an Interactive Human Review Checklist

Enforce manual verification steps before merging.

Update quality-gate-config.yaml:

layer3:
  - name: checklist
    script: "./.aiox-core/core/quality-gates/manual-checklist.js"
    description: "Require reviewer to confirm checklist items"
    interactive: true

Implement .aiox-core/core/quality-gates/manual-checklist.js:

module.exports = async ({ ui }) => {
  const answer = await ui.confirm(
    'Did you verify that the new API follows the security guidelines?'
  );
  return {
    passed: answer,
    summary: answer
      ? 'Reviewer confirmed checklist.'
      : 'Checklist not approved – block merge.',
  };
};

When triggered, the human-review-orchestrator.js renders the UI prompt inside the AIOX interface. The merge remains blocked until the reviewer confirms the checklist.

Key Source Files and Extension Points

Understanding these files enables advanced customization:

Summary

  • AIOX uses a three-layer architecture (Pre-Commit, PR Automation, Human Review) controlled by quality-gate-config.yaml and executed by QualityGateManager.
  • Configuration requires two steps: adding an entry to the YAML config and implementing a Node.js module returning { passed, summary }.
  • Layer 1 uses command for shell scripts; Layer 2 uses script for modules; Layer 3 supports interactive: true for UI prompts.
  • All custom gates automatically integrate with *push and *pre-push workflows without modifying core framework code.

Frequently Asked Questions

What is the exact function signature my custom quality gate must implement?

Your module must export a function that returns a Promise resolving to an object with exactly two properties: passed (boolean) and summary (string). For Layer 3 interactive gates, the function receives a { ui } object parameter containing UI interaction methods like confirm().

Can I use shell commands instead of JavaScript modules for custom gates?

Yes. For Layer 1 pre-commit gates, use the command key in quality-gate-config.yaml to specify any shell command. However, Layers 2 and 3 require the script key pointing to a JavaScript file to properly handle async execution and UI integration.

How do I test a custom quality gate locally before committing?

Invoke the gate manually through the AIOX CLI entry point at bin/aiox.js, or require your module directly in a Node.js REPL to verify it returns the expected Promise structure. The QualityGateManager loads gates dynamically via require, so standard Node.js debugging applies.

Will custom gates slow down the pre-push workflow?

Execution time depends on your implementation. Layer 1 gates run sequentially before every push, so heavy operations should reside in Layer 2 (PR automation) or Layer 3 (human review) to maintain fast feedback cycles during local development.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →