LexOrbital Module Template Guide
Complete guide for module development
LexOrbital Core Team
29 November 2025
- LexOrbital Module Template Guide
- Sheet #0: Quick Start
- Sheet #1: Template Structure
- Sheet #2: Module Manifest
- Sheet #3: Development Rules
- Sheet #4: Tests and Quality
- Sheet #5: CI/CD Workflow
- Sheet #6: Semantic Versioning (SemVer)
- Sheet #7: Integration with LexOrbital Core
- Sources and References
- π Appendix: Module Manifest Validation
- LexOrbital Template Module Tests
LexOrbital Module Template Guide
Complete guide for the LexOrbital Module template: creation, development, testing, integration and deployment of modules compatible with the orbital station.
Table of Contents
- Quick Start
- Template Structure
- Module Manifest
- Development Rules
- Tests and Quality
- CI/CD Workflow
- Semantic Versioning (SemVer)
- Integration with LexOrbital Core
- Sources
- Appendix : Manifest Validation
Overview
The LexOrbital Module Template is a standardized template for creating modules compatible with the LexOrbital orbital station. It includes:
- βοΈ Complete configuration: TypeScript, ESLint, Prettier, Husky, Commitlint
- π§ͺ Pre-configured tests: Vitest with code coverage
- π CI/CD: GitHub Actions with quality gates
- π¦ Automatic versioning: Semantic-release based on Conventional Commits
- π³ Dockerfile: Ready-to-use multi-stage containerization
- π Documentation: Markdown structure β Pandoc (HTML/PDF/DOCX)
Documentation Organization
Technical Sheets (00β07)
The 8 numbered sheets cover all aspects of module development:
| Sheet | Title | Content |
|---|---|---|
| 00 | Quick Start | Installation, configuration, first module |
| 01 | Template Structure | File tree, files, organization |
| 02 | Module Manifest | lexorbital.module.json format
(MANDATORY) |
| 03 | Development Rules | 7 mandatory rules for integration |
| 04 | Tests and Quality | Test standards, coverage, tools |
| 05 | CI/CD Workflow | GitHub Actions pipeline, quality gates |
| 06 | Semantic Versioning | Automatic Semantic Versioning |
| 07 | Core Integration | Git subtree, docking, discovery |
| 08 | Sources | References and resources |
| 09 | Manifest Validation | JSON Schema validation and testing |
Additional Documentation
- QUICKSTART.md: Quick installation and usage guide
- legal/sources.md: Sources and references used
Configure the Module
- Update
package.json: name, description, author - Configure
lexorbital.module.json: name, type, role, compatibility - Customize
README.md - Develop your module in
src/ - Test with
pnpm test - Commit with Conventional Commits:
git commit -m "feat: add my feature"
Mandatory Rules (MANDATORY)
For a module to be integrated into LexOrbital, it must comply with:
- β Conventional Commits (enforced by Commitlint)
- β Dockerfile present and functional
- β Mandatory tests (min. healthcheck + functional)
- β
Complete manifest
(
lexorbital.module.json) - β Complete README with installation instructions
- β CI compliance (lint, type-check, test, build)
- β TypeScript strict mode enabled
Non-negotiable: These rules are automatically enforced by Husky, Commitlint and CI.
Contributing to Documentation
Add a New Sheet
- Create a file
docs/NN_sheet-title.md(NN = 2-digit number) - Use the header template:
# Sheet #N: Sheet Title {#sheet-N-title}
Summary in 2-3 sentences.
## 1. Sheet Objective
## 2. Key Concepts and Decisions
## 3. Technical Implications
## 4. Implementation Checklist
## 5. Key Takeaways
## 6. Related Links- Add an entry in the
README.mdtable of contents - Regenerate the doc:
./scripts/generate-docs.sh
Update an Existing Sheet
- Edit the relevant
docs/NN_*.mdfile - Respect the structure (numbered sections, explicit IDs)
- Commit with Conventional Commits:
docs(sheet-N): description - Automatically regenerate doc (CI/CD GitHub Actions)
License
This project is licensed under MIT. See the LICENSE file at the project root.
Support
For any questions or contributions, consult:
- CONTRIBUTING.md - Contribution guide
- CODE_OF_CONDUCT.md - Code of conduct
- GitHub Issues - Report a bug or propose a feature
Sheet #0: Quick Start
1. Sheet Objective
Provide a step-by-step guide to install, configure, and use the LexOrbital Module template, enabling developers to quickly create modules that comply with station standards.
2. Prerequisites
2.1. Required Software
| Tool | Minimum Version | Installation |
|---|---|---|
| Node.js | β₯24.11.1 | nodejs.org |
| pnpm | Latest | npm install -g pnpm |
| Git | β₯2.0 | git-scm.com |
| Docker | Latest (optional) | docker.com |
| Docker Compose | Latest (optional) | Included with Docker Desktop |
2.2. Required Knowledge
- TypeScript: Intermediate level
- Node.js: Basics of npm/pnpm and modules
- Git: Commits, branches, git subtree (recommended)
- Docker: Optional, for containerization
3. Installation
3.1. Create a Module from the Template
Option 1: Via GitHub UI (recommended)
- Go to github.com/lexorbital/lexorbital-template-module
- Click βUse this templateβ β βCreate a new repositoryβ
- Name the new repository:
lexorbital-module-<scope>- Example:
lexorbital-module-auth,lexorbital-module-dossiers
- Example:
- Choose visibility (Public/Private)
- Click βCreate repositoryβ
Option 2: Via CLI
# Clone the template
git clone https://github.com/lexorbital/lexorbital-template-module.git lexorbital-module-<scope>
cd lexorbital-module-<scope>
# Remove Git history from template
rm -rf .git
git init
git add .
git commit -m "chore: initial commit from template"
# Link to new remote repository
git remote add origin git@github.com:your-org/lexorbital-module-<scope>.git
git push -u origin main3.2. Install Dependencies
cd lexorbital-module-<scope>
pnpm installThis installs:
- TypeScript (strict mode)
- ESLint + Prettier (quality gates)
- Vitest (testing framework)
- Husky (git hooks)
- Commitlint (conventional commits)
- Semantic-release (automatic versioning)
3.3. Configure the Module
Step 1: Update
package.json
{
"name": "lexorbital-module-<scope>",
"version": "0.1.0",
"description": "Short description of your module",
"repository": {
"type": "git",
"url": "https://github.com/your-org/lexorbital-module-<scope>"
},
"author": "Your Name <email@example.com>",
"keywords": ["lexorbital", "module", "<scope>"]
}Step 2:
Configure lexorbital.module.json
{
"name": "lexorbital-module-<scope>",
"description": "Description of your module",
"type": "back",
"version": "0.1.0",
"entryPoints": {
"main": "dist/index.js",
"types": "dist/index.d.ts"
},
"lexorbital": {
"role": "<scope>-module",
"layer": "back",
"compatibility": {
"metaKernel": ">=1.0.0 <2.0.0"
},
"tags": ["<scope>", "your-tags"]
},
"env": ["ENV_VAR_1", "ENV_VAR_2"],
"maintainer": {
"name": "Your Name",
"contact": "https://github.com/your-org/lexorbital-module-<scope>"
}
}Important fields:
type:"back"(backend),"front"(frontend), or"infra"(infrastructure)lexorbital.role: Unique module identifierlexorbital.layer: Integration layer ("back","front","infra")env: Required environment variables
Step 3: Update
README.md
# LexOrbital Module - <Scope>
> Short description of the module.
## Installation
```bash
pnpm install
```Configuration
Required environment variables:
ENV_VAR_1- DescriptionENV_VAR_2- Description
Usage
import { YourService } from "lexorbital-module-<scope>"
const service = new YourService()Documentation
See docs/README.md
## 4. Development Commands
### 4.1. Main Commands
```bash
# Development mode (watch mode with hot reload)
pnpm run dev
# Tests (Vitest)
pnpm test
# Tests in watch mode
pnpm run test:ui
# Production build
pnpm run build
# Linting
pnpm run lint
# Automatic lint + format fix
pnpm run lint:fix
# Formatting (Prettier)
pnpm run format
# TypeScript type checking
pnpm run type-check
4.2. Docker Commands (optional)
# Build Docker image
pnpm run docker:build
# Start in development mode with Docker
pnpm run docker:dev
# Start with Docker Compose (if infrastructure needed)
docker-compose -f infra/docker-compose.local.yml up5. Setup Validation
Before starting development, validate that everything works:
# 1. Verify Git hooks are active
ls -la .husky/
# Should display: pre-commit, commit-msg
# 2. Run tests
pnpm test
# β
Should display at least 1 passing test
# 3. Check lint
pnpm run lint
# β
No errors
# 4. Build
pnpm run build
# β
Should create dist/ folder
# 5. Test a commit (Conventional Commits)
git add .
git commit -m "test: validate setup"
# β
The commitlint hook should validate the messageIf all these steps pass, your environment is ready! π
6. First Development
6.1. Starting Structure
The template provides a minimal structure:
tests/
βββ example.test.ts # Example test (to adapt)
6.2. Create Your First Service
// src/services/my-service.ts
export class MyService {
constructor(private readonly config: Config) {}
async doSomething(): Promise<string> {
// Your business logic
return "Hello from MyService"
}
}6.3. Write the Test
// tests/my-service.test.ts
import { describe, it, expect } from "vitest"
import { MyService } from "../src/services/my-service"
describe("MyService", () => {
it("should return a greeting", async () => {
const service = new MyService({})
const result = await service.doSomething()
expect(result).toBe("Hello from MyService")
})
})6.4. Commit with Conventional Commits
git add src/services/my-service.ts tests/my-service.test.ts
git commit -m "feat: add MyService with basic functionality"The commitlint hook will automatically
validate the format.
7. Startup Checklist
8. Next Steps
Once setup is validated, consult:
9. Troubleshooting
Error:
pnpm: command not found
npm install -g pnpmError: Git hooks not triggering
npx husky install
chmod +x .husky/pre-commit
chmod +x .husky/commit-msgError:
commitlint rejects my commits
Check the format:
type(scope): description
Valid examples:
feat: add new featurefix: correct bug in servicedocs: update README
Tests fail after installation
# Clean and reinstall
rm -rf node_modules pnpm-lock.yaml
pnpm install
pnpm testSheet #1: Template Structure
1. Sheet Objective
Present the complete file tree of the template, explain the role of each file and folder, and justify organizational choices to maintain consistency across all LexOrbital modules.
2. Complete File Tree
lexorbital-module-<scope>/
βββ .github/
β βββ workflows/
β βββ ci.yml # CI GitHub Actions
βββ .husky/
β βββ pre-commit # Git hook (lint-staged)
β βββ commit-msg # Git hook (commitlint)
βββ docs/
β βββ README.md # Documentation index
β βββ [...] # Other doc files
βββ infra/
β βββ docker-compose.local.yml # Local infrastructure (optional)
βββ src/
β βββ index.ts # Main entry point
β βββ [...] # Module source code
βββ tests/
β βββ example.test.ts # Tests (Vitest)
βββ .editorconfig # Editor configuration
βββ .gitignore # Git exclusions
βββ .prettierignore # Prettier exclusions
βββ .prettierrc # Prettier configuration
βββ CHANGELOG.md # Version history (auto)
βββ CODE_OF_CONDUCT.md # Code of conduct
βββ commitlint.config.ts # Commitlint configuration
βββ CONTRIBUTING.md # Contribution guide
βββ Dockerfile # Module Docker image
βββ eslint.config.cjs # ESLint configuration (flat config)
βββ lexorbital.module.json # β LexOrbital Manifest (MANDATORY)
βββ LICENSE # License (MIT recommended)
βββ package.json # npm/pnpm configuration
βββ pnpm-lock.yaml # pnpm lock file
βββ README.md # Main documentation
βββ SECURITY.md # Security policy
βββ SUPPORT.md # Support and help
βββ tsconfig.json # TypeScript configuration
βββ vitest.config.ts # Vitest configuration (optional)
3. Main Folders
3.1. src/ β Source
Code
Role: Contains all TypeScript source code for the module.
Recommended Structure:
@TODO: Add recommended structure
Conventions:
- One file = one responsibility (single responsibility)
- Exports via
index.ts(barrel exports) - No code outside
src/(except config)
3.2. tests/ β
Tests
Role: Contains all module tests (unit, integration, e2e).
Recommended Structure:
@TODO: Add recommended structure
Conventions:
- Test files:
\*.test.ts - Mirrors
src/structure for unit tests - At least 1 test mandatory (healthcheck or functional)
3.3. docs/ β
Documentation
Role: Detailed module documentation (beyond README).
Structure:
docs/
βββ README.md # Doc index
βββ 00_quick-start.md # Quick start guide
βββ 01_template-structure.md # This sheet
βββ [...] # Other sheets
βββ templates/ # Pandoc templates (optional)
βββ custom.html
Conventions:
- Markdown format (
.md) - Numbered sheets for Pandoc generation
- README as main index
3.4. infra/ β
Infrastructure
Role: Docker Compose configuration and local infrastructure (databases, caches, etc.).
Example:
@TODO: Add example
Usage:
docker-compose -f infra/docker-compose.local.yml upNote: Infrastructure must not be deployed by the module, only for local development.
3.5.
.github/workflows/ β CI/CD
Role: GitHub Actions workflows for continuous integration.
Main File: ci.yml
name: CI
on:
push:
branches: [main, develop]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
- run: corepack enable
- run: pnpm install
- run: pnpm run lint
- run: pnpm run type-check
- run: pnpm test
- run: pnpm run buildMandatory Steps:
- Lint (ESLint)
- Type check (tsc βnoEmit)
- Tests (Vitest)
- Build (tsc)
3.6. .husky/ β Git
Hooks
Role: Automatic Git hooks to ensure code quality.
pre-commit:
Lint before commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged.lintstagedrc.json file
(lint-staged configuration):
{
"*.{ts,tsx}": ["eslint --fix", "prettier --write"],
"*.{json,md,yml}": ["prettier --write"]
}commit-msg:
Conventional Commits Validation
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx commitlint --edit "$1"4. Configuration Files
4.1.
lexorbital.module.json β (MANDATORY)
Role: Declarative manifest of the module for LexOrbital integration.
See [02_module-manifest] for complete specification.
4.2.
package.json
Mandatory Scripts:
{
"scripts": {
"dev": "tsx watch src/index.ts",
"build": "tsc",
"test": "vitest run",
"test:ui": "vitest --ui",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"format": "prettier --write .",
"type-check": "tsc --noEmit",
"prepare": "husky install"
}
}Standard Dependencies:
typescript(β₯5.0)eslint+@typescript-eslint/*prettiervitesthusky+lint-staged+commitlint
4.3.
tsconfig.json
Recommended Strict Configuration:
{
"compilerOptions": {
"target": "ES2022",
"module": "ESNext",
"lib": ["ES2022"],
"moduleResolution": "node",
"outDir": "./dist",
"rootDir": "./src",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"declaration": true,
"declarationMap": true,
"sourceMap": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "tests"]
}4.4.
eslint.config.cjs (flat config)
Modern ESLint Configuration:
const eslint = require("@eslint/js")
const tseslint = require("typescript-eslint")
module.exports = tseslint.config(eslint.configs.recommended, ...tseslint.configs.recommendedTypeChecked, {
languageOptions: {
parserOptions: {
project: true,
tsconfigRootDir: __dirname,
},
},
rules: {
"@typescript-eslint/no-unused-vars": "error",
"@typescript-eslint/no-explicit-any": "warn",
},
})4.5. .prettierrc
Prettier Configuration:
{
"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5",
"printWidth": 100
}4.6.
commitlint.config.ts
Commitlint Configuration:
import type { UserConfig } from "@commitlint/types"
const config: UserConfig = {
extends: ["@commitlint/config-conventional"],
rules: {
"type-enum": [2, "always", ["feat", "fix", "docs", "style", "refactor", "perf", "test", "chore", "ci", "revert"]],
},
}
export default config4.7. Dockerfile
Minimal Multi-Stage Dockerfile:
# Stage 1: Build
FROM node:24-alpine AS builder
WORKDIR /app
# Enable pnpm
RUN corepack enable
# Copy package files
COPY package.json pnpm-lock.yaml ./
# Install dependencies
RUN pnpm install --frozen-lockfile
# Copy source
COPY . .
# Build
RUN pnpm run build
# Stage 2: Production
FROM node:24-alpine
WORKDIR /app
RUN corepack enable
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --prod --frozen-lockfile
COPY --from=builder /app/dist ./dist
CMD ["node", "dist/index.js"]5. Why This Structure?
5.1. Consistency
All LexOrbital modules share exactly the same structure:
- β Facilitates navigation for developers
- β Enables automation (scripts, CI)
- β Guarantees interoperability with Core
5.2. Quality
Integrated tooling ensures:
- β Lint-free code (ESLint + Prettier)
- β Conventional commits (Commitlint)
- β Automatic tests (Vitest + CI)
- β Strict types (TypeScript strict mode)
5.3. Autonomy
Each module is autonomous:
- β Independent Git repository
- β Own CI/CD
- β SemVer versioning
- β Independent lifecycle
6. Compliance Checklist
For a module to be template-compliant:
Sheet #2: Module Manifest
The
lexorbital.module.jsonfile is the mandatory manifest for each LexOrbital module. It declares metadata, entry points, compatibility, and module dependencies.
1. Sheet Objective
Specify the exact format of the
lexorbital.module.json manifest, its role
in the LexOrbital ecosystem, and how the Core uses it to
discover and validate modules.
2. Manifest Role
2.1. Why a Manifest?
The manifest allows the Meta-Kernel of LexOrbital Core to:
- Discover modules automatically
(scan of
modules/*/lexorbital.module.json) - Validate compatibility (Core version, dependencies)
- Load modules into the correct ring (Ring)
- Document architecture automatically (dependency graphs)
- Configure required environment variables
2.2. No Manifest, No Integration
A module without
lexorbital.module.json:
- β Cannot be docked to the station
- β Will not be detected by the Meta-Kernel
- β Cannot declare its dependencies
- β Cannot be automatically documented
3. Complete Manifest Structure
{
"name": "lexorbital-module-<scope>",
"description": "Short module description (1-2 sentences)",
"type": "back",
"version": "0.1.0",
"entryPoints": {
"main": "dist/index.js",
"types": "dist/index.d.ts"
},
"lexorbital": {
"role": "<scope>-module",
"layer": "back",
"orbit": 2,
"compatibility": {
"metaKernel": ">=1.0.0 <2.0.0"
},
"dependencies": {
"required": ["config-module", "logger-module"],
"optional": ["notification-module"]
},
"provides": {
"services": ["MyService", "AnotherService"],
"events": ["module.event.created", "module.event.updated"],
"endpoints": ["/api/<scope>"]
},
"consumes": {
"events": ["user.created", "user.deleted"]
},
"tags": ["<scope>", "backend", "database"]
},
"env": ["DATABASE_URL", "API_KEY"],
"healthcheck": {
"endpoint": "/health",
"interval": 30000
},
"maintainer": {
"name": "Your Name or Organization",
"contact": "https://github.com/your-org/lexorbital-module-<scope>"
},
"repository": {
"type": "git",
"url": "https://github.com/your-org/lexorbital-module-<scope>"
},
"license": "MIT"
}4. Required Fields
4.1. name
(string, required)
Format:
lexorbital-module-<scope>
Examples:
lexorbital-module-authlexorbital-module-dossierslexorbital-module-documents
Rules:
- Must start with
lexorbital-module- - Kebab-case only (lowercase + hyphens)
- Unique in the LexOrbital ecosystem
4.2.
version (semver, required)
Format: Semantic Versioning
(MAJOR.MINOR.PATCH)
Examples:
0.1.0(initial development)1.0.0(first stable version)2.3.5(mature version)
Rules:
- Must match version in
package.json - Managed automatically by
semantic-release
4.3. type
(enum, required)
Possible Values:
"back"β Backend module (NestJS, Express, API)"front"β Frontend module (React, Vue, UI)"infra"β Infrastructure module (scripts, config, orchestration)
Example:
{
"type": "back"
}4.4.
entryPoints (object, required)
Structure:
{
"entryPoints": {
"main": "dist/index.js",
"types": "dist/index.d.ts"
}
}Fields:
main: Compiled JavaScript file (entry point)types: TypeScript declaration files (.d.ts)
4.5.
lexorbital.role (string, required)
Role: Unique module identifier in the station.
Format:
<scope>-module
Examples:
auth-moduledossiers-moduledocuments-module
4.6.
lexorbital.layer (enum, required)
Possible Values:
"back"β Backend (Meta-Kernel, services)"front"β Frontend (React, user interface)"infra"β Infrastructure (Docker, CI, scripts)
4.7.
lexorbital.compatibility (object,
required)
Structure:
{
"compatibility": {
"metaKernel": ">=1.0.0 <2.0.0"
}
}Format: pnpm range (semver)
Examples:
">=1.0.0 <2.0.0"β Compatible with Meta-Kernel 1.x"^1.2.0"β Compatible with 1.2.0 and above (minor)"~1.2.3"β Compatible with 1.2.x (patches only)
5. Optional Fields
5.1.
description (string, optional)
Role: Short module description (1-2 sentences).
Example:
{
"description": "JWT authentication module with OAuth2 and RBAC support"
}5.2.
lexorbital.orbit (number, optional)
Role: Module orbital ring (0-3).
Values:
0β Meta-Kernel (Core)1β Core Services (auth, audit, logs)2β Business Logic (dossiers, documents)3β Integrations (API Gateway, webhooks)
Example:
{
"orbit": 1
}5.3.
lexorbital.dependencies (object,
optional)
Structure:
{
"dependencies": {
"required": ["config-module", "logger-module"],
"optional": ["notification-module"]
}
}Role: Declares inter-module dependencies.
Validation: The Meta-Kernel verifies
that all required modules are loaded before
initializing this module.
5.4.
lexorbital.provides (object, optional)
Structure:
{
"provides": {
"services": ["AuthService", "TokenService"],
"events": ["user.login", "user.logout"],
"endpoints": ["/auth/login", "/auth/logout"]
}
}Role: Declares what the module exposes (services, events, HTTP endpoints).
Usage: Automatic documentation generation and dependency graphs.
5.5.
lexorbital.consumes (object, optional)
Structure:
{
"consumes": {
"events": ["user.created", "user.deleted"]
}
}Role: Declares events the module listens to (pub/sub).
Usage: Maps inter-module communication flows.
5.6.
lexorbital.tags (array, optional)
Role: Tags for search and categorization.
Example:
{
"tags": ["auth", "security", "jwt", "oauth2"]
}5.7. env
(array, optional)
Role: List of required environment variables.
Example:
{
"env": ["DATABASE_URL", "JWT_SECRET", "REDIS_URL"]
}Usage: The Meta-Kernel can validate that all variables are defined at startup.
5.8.
healthcheck (object, optional)
Structure:
{
"healthcheck": {
"endpoint": "/health",
"interval": 30000
}
}Role: Configures module health check.
Fields:
endpoint: HTTP endpoint to poll (e.g.,/health)interval: Interval in ms (default: 30000 = 30s)
5.9.
maintainer (object, optional)
Structure:
{
"maintainer": {
"name": "LexOrbital Core Team",
"contact": "https://github.com/lexorbital/lexorbital-module-auth"
}
}5.10.
repository (object, optional)
Structure:
{
"repository": {
"type": "git",
"url": "https://github.com/lexorbital/lexorbital-module-auth"
}
}5.11.
license (string, optional)
Role: Module license.
Examples:
"MIT"(recommended)"Apache-2.0""GPL-3.0"
6. Manifest Validation
6.1. Validation on Load
The Meta-Kernel validates the manifest on each load:
// Pseudo-code validation
function validateManifest(manifest: Manifest): void {
// Required fields
if (!manifest.name) throw new Error("Missing required field: name")
if (!manifest.type) throw new Error("Missing required field: type")
if (!manifest.version) throw new Error("Missing required field: version")
// Name format
if (!manifest.name.startsWith("lexorbital-module-")) {
throw new Error('Module name must start with "lexorbital-module-"')
}
// SemVer version
if (!semver.valid(manifest.version)) {
throw new Error("Invalid version format (must be SemVer)")
}
// Compatibility
if (!semver.satisfies(CORE_VERSION, manifest.lexorbital.compatibility.metaKernel)) {
throw new Error(`Module incompatible with Meta-Kernel version ${CORE_VERSION}`)
}
// Dependencies
for (const dep of manifest.lexorbital.dependencies?.required || []) {
if (!loadedModules.has(dep)) {
throw new Error(`Missing required dependency: ${dep}`)
}
}
}6.2. Validation with JSON Schema
A JSON Schema is available for automatic validation:
URL:
https://lexorbital.dev/schemas/module-manifest.v1.json
Usage in Manifest:
{
"$schema": "https://lexorbital.dev/schemas/module-manifest.v1.json",
"name": "lexorbital-module-auth",
...
}CLI Validation:
# Install @exodus/schemasafe
pnpm install --save-dev @exodus/schemasafe
# Validate manifest
npx schemasafe validate lexorbital.module.json7. Complete Examples
7.1. Backend Module (Auth)
{
"$schema": "https://lexorbital.dev/schemas/module-manifest.v1.json",
"name": "lexorbital-module-auth",
"description": "JWT authentication module with OAuth2 and RBAC support",
"type": "back",
"version": "1.2.0",
"entryPoints": {
"main": "dist/index.js",
"types": "dist/index.d.ts"
},
"lexorbital": {
"role": "auth-module",
"layer": "back",
"orbit": 1,
"compatibility": {
"metaKernel": ">=1.0.0 <2.0.0"
},
"dependencies": {
"required": ["config-module", "logger-module"],
"optional": ["notification-module"]
},
"provides": {
"services": ["AuthService", "RBACService", "TokenService"],
"events": ["user.login", "user.logout", "token.refreshed"],
"endpoints": ["/auth/login", "/auth/logout", "/auth/refresh"]
},
"consumes": {
"events": ["user.created", "user.deleted"]
},
"tags": ["auth", "jwt", "oauth2", "rbac", "security"]
},
"env": ["JWT_SECRET", "JWT_EXPIRY", "DATABASE_URL"],
"healthcheck": {
"endpoint": "/auth/health",
"interval": 30000
},
"maintainer": {
"name": "LexOrbital Core Team",
"contact": "https://github.com/lexorbital/lexorbital-module-auth"
},
"repository": {
"type": "git",
"url": "https://github.com/lexorbital/lexorbital-module-auth"
},
"license": "MIT"
}7.2. Frontend Module (Console)
{
"name": "lexorbital-module-console",
"description": "3D control console with Three.js",
"type": "front",
"version": "0.5.0",
"entryPoints": {
"main": "dist/index.js",
"types": "dist/index.d.ts"
},
"lexorbital": {
"role": "console-module",
"layer": "front",
"orbit": 3,
"compatibility": {
"metaKernel": ">=1.0.0 <2.0.0"
},
"dependencies": {
"required": ["api-gateway-module"]
},
"tags": ["frontend", "react", "threejs", "console", "ui"]
},
"license": "MIT"
}7.3. Infrastructure Module
{
"name": "lexorbital-module-ci-scripts",
"description": "CI/CD scripts and automation",
"type": "infra",
"version": "1.0.0",
"entryPoints": {
"main": "dist/index.js"
},
"lexorbital": {
"role": "ci-scripts",
"layer": "infra",
"compatibility": {
"metaKernel": "*"
},
"tags": ["ci", "cd", "automation", "scripts"]
},
"license": "MIT"
}8. Compliance Checklist
Sheet #3: Development Rules
1. Sheet Objective
Define strict development rules to ensure quality, consistency, and interoperability of all LexOrbital modules. No exceptions are tolerated: these rules are mandatory for docking.
2. The 7 Golden Rules
Rule 1: Conventional Commits
Status: β MANDATORY
Description: All commits must follow the Conventional Commits specification.
Required Format
<type>(<scope>): <subject>
[optional body]
[optional footer]
Allowed Types
| Type | Description | Example |
|---|---|---|
feat |
New feature | feat: add OAuth2 support |
fix |
Bug fix | fix: correct token expiration |
refactor |
Refactoring (no feat/fix) | refactor: extract service logic |
docs |
Documentation only | docs: update README |
test |
Test additions/changes | test: add unit tests for AuthService |
chore |
Maintenance, config, deps | chore: update dependencies |
perf |
Performance improvement | perf: optimize database queries |
ci |
CI/CD modification | ci: add coverage report |
revert |
Revert a commit | revert: revert "feat: add feature X" |
Breaking Changes
For breaking changes:
feat!: remove deprecated API endpoint
BREAKING CHANGE: The /api/v1/old endpoint has been removed.
Migrate to /api/v2/new instead.
Enforcement
Conventional Commits are enforced by:
- Husky (hook
commit-msg) - Commitlint (format validation)
- CI (GitHub Actions)
If the commit does not respect the format, it will be rejected.
Rule 2: Mandatory Dockerfile
Status: β MANDATORY
Description: Each module
must include a Dockerfile
for containerization.
Requirements
- β Multi-stage Dockerfile (build + production)
- β
Official base image (
node:24-alpinerecommended) - β No secrets in image (use environment variables)
- β Lightest possible image
- β Non-root user (security)
Dockerfile Template
# Stage 1: Build
FROM node:24-alpine AS builder
WORKDIR /app
RUN corepack enable
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --frozen-lockfile
COPY . .
RUN pnpm run build
# Stage 2: Production
FROM node:24-alpine
# Non-root user
RUN addgroup -g 1001 -S appuser && \
adduser -S -u 1001 -G appuser appuser
WORKDIR /app
RUN corepack enable
COPY package.json pnpm-lock.yaml ./
RUN pnpm install --prod --frozen-lockfile
COPY --from=builder /app/dist ./dist
# Switch to non-root user
USER appuser
CMD ["node", "dist/index.js"]Validation
# Build must succeed
docker build -t lexorbital-module-<scope> .
# Image must start without error
docker run --rm lexorbital-module-<scope>Rule 3: Mandatory Tests
Status: β MANDATORY
Description: Each module must include at minimum:
- A healthcheck test (validates the module can start)
- A functional test (tests the main functionality)
Healthcheck Test (example)
// tests/healthcheck.test.ts
import { describe, it, expect } from "vitest"
describe("Healthcheck", () => {
it("should return 200 OK", async () => {
const response = await fetch("http://localhost:3000/health")
expect(response.status).toBe(200)
})
})Functional Test (example)
// tests/functional.test.ts
import { describe, it, expect } from "vitest"
import { MyService } from "../src/services/my-service"
describe("MyService", () => {
it("should perform core functionality", async () => {
const service = new MyService()
const result = await service.doSomething()
expect(result).toBeDefined()
})
})Test Coverage (recommended)
- Goal: β₯80% coverage
- Tool: Vitest with
c8or@vitest/coverage-v8
pnpm run coverageEnforcement
- β
Tests executed in CI
(
pnpm test) - β Build fails if tests fail
- β No merge without passing tests
Rule 4: Complete Manifest
Status: β MANDATORY
Description: A complete and
valid lexorbital.module.json file
is mandatory.
See: [02_module-manifest] for complete specification.
Required Fields
- β
name(formatlexorbital-module-<scope>) - β
version(SemVer) - β
type(back,front,infra) - β
entryPoints.mainandentryPoints.types - β
lexorbital.role - β
lexorbital.layer - β
lexorbital.compatibility.metaKernel
Validation
# Validate with JSON Schema
npx schemasafe validate lexorbital.module.jsonRule 6: CI Compliance
Status: β MANDATORY
Description: The module must pass all CI tests without error.
Mandatory CI Pipeline
The .github/workflows/ci.yml workflow
must execute:
- Install:
pnpm install - Lint:
pnpm run lint - Type check:
pnpm run type-check(ortsc --noEmit) - Tests:
pnpm test - Build:
pnpm run build
Enforcement
- β No PR can be merged if CI fails
- β No module can be docked if CI is not green
Rule 7: TypeScript Strict Mode
Status: β MANDATORY
Description: All modules must use TypeScript in strict mode.
Enforcement
- β
pnpm run type-checkmust pass without error - β
No
@ts-ignoreor@ts-expect-errorwithout justification - β
No
anyexcept exceptional cases (then annotate with// eslint-disable-line)
3. Best Practices (recommended but not mandatory)
3.1. Keep Modules Focused
One module = one responsibility (Single Responsibility Principle).
Examples:
- β
lexorbital-module-auth: Authentication only - β
lexorbital-module-auth-and-files: Mixed responsibility
3.2. Minimize Dependencies
Fewer dependencies = fewer conflict risks.
Tips:
- Use Node.js native features when possible
- Avoid large frameworks if a utility is sufficient
- Check licenses of third-party dependencies
3.3. Document All Public APIs
Each exported function/class must have JSDoc.
/**
* Authenticates a user by email/password.
* @param email - User email
* @param password - Plain password
* @returns JWT token if authentication succeeds
* @throws UnauthorizedException if invalid credentials
*/
async login(email: string, password: string): Promise<string> {
// ...
}5. Compliance Checklist
For a module to be compliant:
6. Consequences of Non-Compliance
β Automatic Rejection
A module that does not comply with these rules will be automatically rejected by:
- Git hooks (if Conventional Commits not respected)
- CI (if tests/lint/build fail)
- The Meta-Kernel (if manifest invalid)
β οΈ Docking Impossibility
A non-compliant module cannot be docked to the LexOrbital station.
π PR Blocking
PRs with failing CI are automatically blocked (branch protection rules).
Sheet #4: Tests and Quality
1. Sheet Objective
Define mandatory and recommended test standards for LexOrbital modules, with tools, patterns, and metrics to comply with.
2. Mandatory Tests
2.1. Healthcheck Test (MANDATORY)
Objective: Validate that the module can start and respond.
For Backend Modules (HTTP)
// tests/healthcheck.test.ts
import { describe, it, expect, beforeAll, afterAll } from "vitest"
import request from "supertest"
import { app } from "../src/app"
describe("Healthcheck", () => {
let server: any
beforeAll(async () => {
server = app.listen(3000)
})
afterAll(async () => {
server.close()
})
it("should return 200 OK on /health", async () => {
const response = await request(app).get("/health")
expect(response.status).toBe(200)
expect(response.body).toEqual({
status: "ok",
timestamp: expect.any(Number),
})
})
})For Frontend Modules (Component)
// tests/healthcheck.test.tsx
import { describe, it, expect } from 'vitest';
import { render, screen } from '@testing-library/react';
import { App } from '../src/App';
describe('App Component', () => {
it('should render without crashing', () => {
render(<App />);
expect(screen.getByTestId('app-container')).toBeInTheDocument();
});
});For Infrastructure Modules
// tests/healthcheck.test.ts
import { describe, it, expect } from "vitest"
import { initModule } from "../src/index"
describe("Module Initialization", () => {
it("should initialize without errors", async () => {
await expect(initModule()).resolves.not.toThrow()
})
})2.2. Functional Test (MANDATORY)
Objective: Test at least one main functionality of the module.
Example: Authentication Module
// tests/functional/auth.test.ts
import { describe, it, expect, beforeEach } from "vitest"
import { AuthService } from "../src/services/auth.service"
describe("AuthService", () => {
let authService: AuthService
beforeEach(() => {
authService = new AuthService({
jwtSecret: "test-secret",
jwtExpiry: "1h",
})
})
it("should authenticate valid user", async () => {
const token = await authService.login("user@example.com", "password123")
expect(token).toBeDefined()
expect(typeof token).toBe("string")
})
it("should reject invalid credentials", async () => {
await expect(authService.login("user@example.com", "wrong-password")).rejects.toThrow("Invalid credentials")
})
it("should verify valid token", async () => {
const token = await authService.login("user@example.com", "password123")
const payload = await authService.verifyToken(token)
expect(payload.email).toBe("user@example.com")
})
})Example: Dossier Management Module
// tests/functional/dossiers.test.ts
import { describe, it, expect } from "vitest"
import { DossiersService } from "../src/services/dossiers.service"
describe("DossiersService", () => {
let service: DossiersService
beforeEach(() => {
service = new DossiersService()
})
it("should create a new dossier", async () => {
const dossier = await service.create({
title: "Test Dossier",
clientId: "123",
})
expect(dossier.id).toBeDefined()
expect(dossier.title).toBe("Test Dossier")
})
it("should retrieve dossier by ID", async () => {
const created = await service.create({ title: "Test", clientId: "123" })
const retrieved = await service.findById(created.id)
expect(retrieved).toEqual(created)
})
})3. Recommended Test Types
3.1. Unit Tests
Objective: Test isolated functions/classes.
Tool: Vitest
Structure:
tests/
βββ unit/
βββ services/
β βββ my-service.test.ts
βββ utils/
β βββ helpers.test.ts
βββ models/
βββ user.test.ts
Example:
// tests/unit/utils/helpers.test.ts
import { describe, it, expect } from "vitest"
import { formatDate, calculateAge } from "../../src/utils/helpers"
describe("Helpers", () => {
describe("formatDate", () => {
it("should format date to ISO string", () => {
const date = new Date("2025-11-22")
expect(formatDate(date)).toBe("2025-11-22")
})
})
describe("calculateAge", () => {
it("should calculate age from birthdate", () => {
const birthdate = new Date("2000-01-01")
const age = calculateAge(birthdate)
expect(age).toBeGreaterThanOrEqual(24)
})
})
})3.2. Integration Tests
Objective: Test interaction between multiple components.
Structure:
tests/
βββ integration/
βββ api.test.ts
βββ database.test.ts
Example:
// tests/integration/api.test.ts
import { describe, it, expect, beforeAll, afterAll } from "vitest"
import request from "supertest"
import { app } from "../../src/app"
import { db } from "../../src/database"
describe("API Integration", () => {
beforeAll(async () => {
await db.connect()
})
afterAll(async () => {
await db.disconnect()
})
it("should create and retrieve a user", async () => {
// Create
const createResponse = await request(app).post("/api/users").send({ name: "John Doe", email: "john@example.com" })
expect(createResponse.status).toBe(201)
// Retrieve
const userId = createResponse.body.id
const getResponse = await request(app).get(`/api/users/${userId}`)
expect(getResponse.status).toBe(200)
expect(getResponse.body.name).toBe("John Doe")
})
})3.3. E2E Tests (End-to-End)
Objective: Test complete user workflows.
Tool: Playwright (frontend) or Supertest + seed data (backend)
Structure:
tests/
βββ e2e/
βββ auth-flow.test.ts
βββ dossier-workflow.test.ts
Example:
// tests/e2e/auth-flow.test.ts
import { describe, it, expect } from "vitest"
import request from "supertest"
import { app } from "../../src/app"
describe("Authentication Flow (E2E)", () => {
it("should complete full auth flow", async () => {
// 1. Register
const registerResponse = await request(app).post("/auth/register").send({ email: "user@example.com", password: "password123" })
expect(registerResponse.status).toBe(201)
// 2. Login
const loginResponse = await request(app).post("/auth/login").send({ email: "user@example.com", password: "password123" })
expect(loginResponse.status).toBe(200)
const { token } = loginResponse.body
// 3. Access protected route
const protectedResponse = await request(app).get("/api/profile").set("Authorization", `Bearer ${token}`)
expect(protectedResponse.status).toBe(200)
expect(protectedResponse.body.email).toBe("user@example.com")
// 4. Logout
const logoutResponse = await request(app).post("/auth/logout").set("Authorization", `Bearer ${token}`)
expect(logoutResponse.status).toBe(200)
})
})4. Test Tools
4.1. Vitest (mandatory)
Installation:
pnpm add -D vitestConfiguration:
vitest.config.ts
import { defineConfig } from "vitest/config"
export default defineConfig({
test: {
globals: true,
environment: "node",
coverage: {
provider: "v8",
reporter: ["text", "json", "html", "lcov"],
exclude: ["**/node_modules/**", "**/dist/**", "**/tests/**", "**/*.config.*"],
thresholds: {
lines: 80,
functions: 80,
branches: 75,
statements: 80,
},
},
},
})package.json
Scripts:
{
"scripts": {
"test": "vitest run",
"test:watch": "vitest",
"test:ui": "vitest --ui",
"coverage": "vitest run --coverage"
}
}4.2. Supertest (backend HTTP modules)
Installation:
pnpm add -D supertest @types/supertestUsage:
import request from "supertest"
import { app } from "../src/app"
await request(app).get("/api/users").expect(200)4.3. React Testing Library (frontend modules)
Installation:
pnpm add -D @testing-library/react @testing-library/jest-dom @testing-library/user-eventUsage:
import { render, screen, fireEvent } from '@testing-library/react';
import { LoginForm } from '../src/components/LoginForm';
test('should submit form', () => {
render(<LoginForm />);
const input = screen.getByLabelText('Email');
fireEvent.change(input, { target: { value: 'user@example.com' } });
// ...
});5. Test Coverage
5.1. Coverage Goals
| Metric | Goal | Minimum Acceptable |
|---|---|---|
| Lines | β₯80% | β₯70% |
| Functions | β₯80% | β₯70% |
| Branches | β₯75% | β₯65% |
| Statements | β₯80% | β₯70% |
5.2. Generate Coverage Report
pnpm run coverageOutput:
---------------------------|---------|----------|---------|---------|
File | % Stmts | % Branch | % Funcs | % Lines |
---------------------------|---------|----------|---------|---------|
All files | 85.2 | 78.5 | 82.1 | 85.2 |
src/services | 92.3 | 85.7 | 90.0 | 92.3 |
auth.service.ts | 95.0 | 88.0 | 92.0 | 95.0 |
src/utils | 78.5 | 70.0 | 75.0 | 78.5 |
helpers.ts | 78.5 | 70.0 | 75.0 | 78.5 |
---------------------------|---------|----------|---------|---------|
5.3. Display HTML Report
open coverage/index.html # macOS
xdg-open coverage/index.html # Linux6. Test Patterns
6.1. AAA Pattern (Arrange, Act, Assert)
it("should calculate total price", () => {
// Arrange
const cart = new ShoppingCart()
cart.addItem({ name: "Book", price: 10 })
cart.addItem({ name: "Pen", price: 2 })
// Act
const total = cart.getTotal()
// Assert
expect(total).toBe(12)
})6.2. Mocking with Vitest
import { describe, it, expect, vi } from "vitest"
import { EmailService } from "../src/services/email.service"
import { UserService } from "../src/services/user.service"
describe("UserService", () => {
it("should send welcome email on user creation", async () => {
// Mock email service
const emailService = {
send: vi.fn(),
} as any
const userService = new UserService(emailService)
await userService.create({ email: "user@example.com", name: "John" })
expect(emailService.send).toHaveBeenCalledWith({
to: "user@example.com",
subject: "Welcome!",
})
})
})6.3. Test Fixtures
// tests/fixtures/users.ts
export const mockUsers = [
{ id: "1", name: "Alice", email: "alice@example.com" },
{ id: "2", name: "Bob", email: "bob@example.com" },
]
// In tests
import { mockUsers } from "../fixtures/users"
it("should list all users", () => {
const users = service.getAll()
expect(users).toEqual(mockUsers)
})7. Quality Gates
7.1. Pre-commit
Before each commit, Husky + lint-staged check:
- β Lint-free code (ESLint)
- β Formatted code (Prettier)
7.2. CI Pipeline
CI executes:
- Lint:
pnpm run lint - Type check:
pnpm run type-check - Tests:
pnpm test - Coverage:
pnpm run coverage(with thresholds) - Build:
pnpm run build
7.3. Branch Protection
GitHub branch protection rules:
- β CI must pass before merge
- β At least 1 review required
- β No force push
- β Linear history
8. Test Checklist
For a module to be compliant:
Sheet #5: CI/CD Workflow
1. Sheet Objective
Present the GitHub Actions workflow included in the template, explain each step, and show how to extend it for specific needs.
2. Minimal CI Workflow
2.1. Pipeline Steps
File: .github/workflows/ci.yml
Step 1: Checkout Code
- uses: actions/checkout@v4Role: Clone the Git repository into the GitHub Actions runner.
Step 2: Setup Node.js
- uses: actions/setup-node@v4
with:
node-version: 24Role: Install Node.js version 24 (LTS).
Matrix strategy: Allows testing on multiple Node versions (if needed).
Step 3: Enable Corepack
- run: corepack enableRole: Enable Corepack to use pnpm without global installation.
Step 4: Install Dependencies
- run: pnpm install --frozen-lockfileRole: Install exact dependencies
from pnpm-lock.yaml.
--frozen-lockfile:
Fails if lock file is not up to date (ensures
reproducibility).
Step 5: Lint
- run: pnpm run lintRole: Check code quality with ESLint.
Fails if: ESLint errors detected.
Step 6: Type Check
- run: pnpm run type-checkRole: Check TypeScript types without generating files.
Command:
tsc --noEmit
Fails if: Type errors detected.
Step 7: Run Tests
- run: pnpm testRole: Execute all tests with Vitest.
Fails if: One or more tests fail.
Step 8: Build
- run: pnpm run buildRole: Compile TypeScript code to JavaScript.
Fails if: Compilation errors detected.
Step 9: Upload Coverage (optional)
- uses: codecov/codecov-action@v3
with:
files: ./coverage/coverage-final.json
fail_ci_if_error: falseRole: Send coverage report to Codecov.
Optional: Can be removed if Codecov is not used.
3. Workflow Triggers
3.1. Push on Main Branches
on:
push:
branches:
- main
- developWhen: On each push to
main or develop.
Objective: Ensure main branches always remain green.
3.2. Pull Requests
on:
pull_request:
branches:
- main
- developWhen: On each PR to
main or develop.
Objective: Validate code before merge.
4. Branch Protection Rules
4.1. GitHub Configuration
To enforce CI, configure branch protection rules:
Settings β Branches β Branch protection rules β Add rule
Recommended Rules for
main:
- β
Require status checks to pass before
merging
- β
quality-checks(CI job name)
- β
- β Require branches to be up to date before merging
- β Require approvals (at least 1 review)
- β Dismiss stale pull request approvals when new commits are pushed
- β Require linear history (no merge commits)
- β Do not allow bypassing the above settings (even for admins)
4.2. Result
With these rules:
- β Impossible to merge a PR if CI fails
- β Impossible to push directly to
mainwithout PR - β Guarantee that only tested and validated code reaches production
5. Possible Extensions
5.1. Security Tests (Snyk)
Test that Docker image builds correctly:
- name: Build Docker image
run: docker build -t lexorbital-module-test .
- name: Test Docker image
run: docker run --rm lexorbital-module-test node --version5.4. pnpm Publication (CD)
Separate workflow for publication:
name: Publish
on:
push:
tags:
- "v*"
jobs:
publish:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 24
registry-url: "https://registry.npmjs.org"
- run: corepack enable
- run: pnpm install --frozen-lockfile
- run: pnpm run build
- name: Publish to pnpm
run: pnpm publish --no-git-checks
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}5.5. Semantic Release
Automate versioning and changelogs:
- name: Semantic Release
run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}6. Deployment (CD)
6.1. Important Rule
β οΈ Deployment (CD) MUST NOT be added to individual modules.
Reason: Modules are deployed
via the LexOrbital station
(lexorbital-stack), not individually.
6.2. Deployment Workflow
Deployment happens at the
lexorbital-core level:
- Module pushed β Module repo (CI passes)
- Subtree update β
lexorbital-corepulls updated module - Deploy station β
lexorbital-stackdeploys entire station
Consequence: Modules only need CI, not CD.
7. CI Monitoring
7.1. Status Badges
Add a GitHub Actions badge to README:
[](https://github.com/your-org/lexorbital-module-<scope>/actions/workflows/ci.yml)7.2. Notifications
Configure Slack/Discord notifications:
- name: Notify on failure
if: failure()
uses: 8398a7/action-slack@v3
with:
status: ${{ job.status }}
text: "CI failed for ${{ github.repository }}"
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}8. Optimizations
8.1. pnpm Cache
Speed up dependency installation:
- name: Setup pnpm
uses: pnpm/action-setup@v2
with:
version: 8
- name: Get pnpm store directory
id: pnpm-cache
run: echo "pnpm_cache_dir=$(pnpm store path)" >> $GITHUB_OUTPUT
- name: Cache pnpm modules
uses: actions/cache@v3
with:
path: ${{ steps.pnpm-cache.outputs.pnpm_cache_dir }}
key: ${{ runner.os }}-pnpm-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-8.2. Parallel Jobs
Run lint and tests in parallel:
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: corepack enable
- run: pnpm install --frozen-lockfile
- run: pnpm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: corepack enable
- run: pnpm install --frozen-lockfile
- run: pnpm test9. CI Checklist
For a module to be compliant:
10. Troubleshooting
Error:
pnpm: command not found
Solution: Add
corepack enable before
pnpm install.
Error: Lock File Out of Date
Solution: Update lock file locally and commit:
pnpm install
git add pnpm-lock.yaml
git commit -m "chore: update lock file"Tests Fail in CI but Pass Locally
Possible Causes:
- Missing environment variables
- Timezone difference (UTC in CI vs local)
- Non-reproducible dependencies
Solution: Use
--frozen-lockfile and define variables in
GitHub Secrets.
Sheet #6: Semantic Versioning (SemVer)
Automatic versioning policy based on Semantic Versioning and Conventional Commits, ensuring consistent versions and automatically generated changelogs.
1. Sheet Objective
Explain the automatic versioning system for LexOrbital modules, based on SemVer and powered by Conventional Commits, with automatic changelog generation.
2. Semantic Versioning (SemVer)
2.1. Format
Format:
MAJOR.MINOR.PATCH
Examples:
0.1.0β Initial development1.0.0β First stable version1.2.5β Mature version2.0.0β Breaking change
2.2. Bump Rules
| Version | When to Bump | Example |
|---|---|---|
| PATCH | Bug fixes, optimizations | 1.0.0 β 1.0.1 |
| MINOR | New features (backward compatible) | 1.0.1 β 1.1.0 |
| MAJOR | Breaking changes (non backward compatible) | 1.1.0 β 2.0.0 |
2.3. Pre-releases
For development versions:
0.1.0-alpha.1β Alpha (unstable)0.1.0-beta.1β Beta (complete features, testing in progress)0.1.0-rc.1β Release Candidate (ready for release)
3. Conventional Commits β SemVer
3.1. Automatic Mapping
| Commit Type | SemVer Impact | Example |
|---|---|---|
fix: |
PATCH | 1.0.0 β 1.0.1 |
feat: |
MINOR | 1.0.0 β 1.1.0 |
feat!: or
BREAKING CHANGE: |
MAJOR | 1.0.0 β 2.0.0 |
chore:, docs:,
refactor:, test: |
None | No release |
3.2. Concrete Examples
PATCH (fix)
git commit -m "fix: correct token expiration bug"Result: 1.0.0 β
1.0.1
CHANGELOG:
## [1.0.1] - 2025-11-22
### Bug Fixes
- correct token expiration bug ([abc123](https://github.com/...))MINOR (feat)
git commit -m "feat: add OAuth2 Google provider"Result: 1.0.1 β
1.1.0
CHANGELOG:
## [1.1.0] - 2025-11-22
### Features
- add OAuth2 Google provider ([def456](https://github.com/...))MAJOR (breaking change)
git commit -m "feat!: change AuthService.login() signature
BREAKING CHANGE: login() now requires { email, password } object instead of separate parameters.
Migration: Replace authService.login(email, password) with authService.login({ email, password })"Result: 1.1.0 β
2.0.0
CHANGELOG:
## [2.0.0] - 2025-11-22
### β BREAKING CHANGES
- change AuthService.login() signature
login() now requires { email, password } object instead of separate parameters.
**Migration:** Replace `authService.login(email, password)` with `authService.login({ email, password })`
### Features
- change AuthService.login() signature ([ghi789](https://github.com/...))4. Semantic-release
4.1. Installation
The template already includes
semantic-release:
{
"devDependencies": {
"semantic-release": "^22.0.0",
"@semantic-release/changelog": "^6.0.3",
"@semantic-release/git": "^10.0.1"
}
}4.2.
Configuration: .releaserc.json
{
"branches": ["main"],
"plugins": [
"@semantic-release/commit-analyzer",
"@semantic-release/release-notes-generator",
"@semantic-release/changelog",
[
"@semantic-release/npm",
{
"npmPublish": false
}
],
[
"@semantic-release/git",
{
"assets": ["CHANGELOG.md", "package.json"],
"message": "chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}"
}
],
"@semantic-release/github"
]
}4.3. Plugins
| Plugin | Role |
|---|---|
commit-analyzer |
Analyzes commits to determine release type |
release-notes-generator |
Generates release notes from commits |
changelog |
Updates CHANGELOG.md |
npm |
Publishes to npm (disabled by default with
npmPublish: false) |
git |
Commits changes (CHANGELOG, package.json) and creates a tag |
github |
Creates a GitHub Release |
5. Automatic Workflow
5.1. Release on Push (main)
GitHub Actions Workflow:
.github/workflows/release.yml
name: Release
on:
push:
branches:
- main
jobs:
release:
name: Semantic Release
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 0
persist-credentials: false
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 24
- name: Enable Corepack
run: corepack enable
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Build
run: pnpm run build
- name: Semantic Release
run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}5.2. Automatic Process
- Push to
mainβreleaseworkflow triggers - Semantic-release analyzes commits since last release
- Version determination:
fix:commits β PATCHfeat:commits β MINOR- Commits with
BREAKING CHANGEβ MAJOR
- CHANGELOG generation (adds new commits)
- Version bump in
package.json - Commit changes:
chore(release): X.Y.Z [skip ci] - Tag creation Git:
vX.Y.Z - Push commit + tag
- GitHub Release creation with release notes
5.3. Result
After a push with
feat: add new feature:
- β
package.json:"version": "1.1.0" - β
CHANGELOG.mdupdated with new version - β
Git tag:
v1.1.0 - β GitHub Release created automatically
6. Automatic CHANGELOG
6.1. Structure
The CHANGELOG.md is automatically
generated:
# Changelog
All notable changes to this project will be documented in this file.
## [1.1.0] - 2025-11-22
### Features
- add OAuth2 Google provider ([abc123](https://github.com/.../commit/abc123))
- add 2FA support ([def456](https://github.com/.../commit/def456))
### Bug Fixes
- correct token refresh logic ([ghi789](https://github.com/.../commit/ghi789))
## [1.0.1] - 2025-11-20
### Bug Fixes
- fix password hashing issue ([jkl012](https://github.com/.../commit/jkl012))
## [1.0.0] - 2025-11-15
### Features
- initial release with JWT authentication6.2. Commit Groups
Commits are automatically grouped by type:
- β BREAKING CHANGES β Breaking changes
- Features β New features
(
feat:) - Bug Fixes β Fixes
(
fix:) - Performance Improvements β
Optimizations (
perf:) - Reverts β Commit reverts
(
revert:)
7. Manual Release
7.1. Dry Run (simulation)
Simulate a release without publishing:
npx semantic-release --dry-runOutput:
[semantic-release] βΊ βΉ Start step "analyzeCommits" of plugin "@semantic-release/commit-analyzer"
[semantic-release] βΊ βΉ Analyzing commit: feat: add new feature
[semantic-release] βΊ β Completed step "analyzeCommits" of plugin "@semantic-release/commit-analyzer"
[semantic-release] βΊ βΉ The next release version is 1.1.0
7.2. Local Release
Create a release manually (if not in GitHub Actions):
npx semantic-release --no-ciβ οΈ Warning: Requires
GITHUB_TOKEN and NPM_TOKEN
environment tokens.
8. Branch Management
8.1. Release Branches
By default, semantic-release only releases from
main:
{
"branches": ["main"]
}8.2. Multi-branches (optional)
To support multiple release channels:
{
"branches": [
"main",
{
"name": "next",
"prerelease": true
},
{
"name": "beta",
"prerelease": true
}
]
}Result:
- Push to
mainβ1.0.0 - Push to
nextβ1.1.0-next.1 - Push to
betaβ1.1.0-beta.1
9. npm Publication (optional)
9.1. Enable Publication
In .releaserc.json, remove
"npmPublish": false:
{
"plugins": ["@semantic-release/npm"]
}9.2. npm Token
Add the NPM_TOKEN secret in GitHub:
Settings β Secrets β Actions β New repository secret
Name: NPM_TOKEN
Value: Your npm token (generated on npmjs.com)
9.3. npm Scope
To publish a scoped package (e.g.,
@lexorbital/module-auth):
package.json:
{
"name": "@lexorbital/module-auth",
"publishConfig": {
"access": "public"
}
}10. Best Practices
10.1. Squash Commits
Squash PR commits into a single commit:
git rebase -i HEAD~5
# Squash all commits except the first
# Edit final message to respect Conventional Commits10.2. Clear Commit Messages
Bad:
fix stuff
update code
wip
Good:
fix: correct token expiration calculation
feat: add support for refresh tokens
refactor: extract auth logic into service
10.3. Manual Changelog (if necessary)
If manual notes are needed in CHANGELOG:
## [1.0.0] - 2025-11-22
### Migration Guide
This is a major release with breaking changes. Please follow this guide:
1. Update all imports from `auth` to `@lexorbital/auth`
2. Replace `login(email, password)` with `login({ email, password })`
3. Update environment variables (see README)
## 11. Versioning Checklist
- [ ] All commits follow Conventional Commits
- [ ] `semantic-release` configured in `.releaserc.json`
- [ ] GitHub Actions `release.yml` workflow present
- [ ] `GITHUB_TOKEN` secret available (automatic)
- [ ] `NPM_TOKEN` secret configured (if npm publication)
- [ ] CHANGELOG.md automatically generated
- [ ] Git tags automatically created
- [ ] GitHub Releases automatically createdSheet #7: Integration with LexOrbital Core
How modules are discovered, validated, and docked to the LexOrbital Core station via git subtree, while maintaining their autonomy and independent repository.
1. Sheet Objective
Explain the module integration process into
lexorbital-core, the use of git subtree,
autonomy rules, and the update workflow.
2. Integration Principle
2.1. Autonomous Modules, Unified Station
Concept: Each module is an
independent Git repository, but all are
integrated into
lexorbital-core to form the complete
station.
lexorbital-module-auth β Independent repository
lexorbital-module-dossiers β Independent repository
lexorbital-module-documents β Independent repository
β
lexorbital-core
βββ modules/
β βββ auth/ β git subtree of lexorbital-module-auth
β βββ dossiers/ β git subtree of lexorbital-module-dossiers
β βββ documents/ β git subtree of lexorbital-module-documents
2.2. Why git subtree?
Advantages:
- β
Transparency: Module code is
physically present in
lexorbital-core - β
Simple clone:
git clone lexorbital-coreis sufficient, no submodules - β Preserved history: Module history is merged into Core
- β Autonomy: Module can evolve independently
- β Contribution: Easy to push changes upstream
Vs git submodule:
| Criterion | git subtree | git submodule |
|---|---|---|
| Clone | Simple (git clone) |
Complex (--recurse-submodules) |
| Code Present | β Yes | β No (reference only) |
| Detached State | β No | β Yes (detached HEAD) |
| Contribution | β
Easy (subtree push) |
β Complex |
3. Module Docking (Initial Docking)
3.1. git subtree add Command
From the lexorbital-core repository:
git subtree add \
--prefix=modules/auth \
git@github.com:lexorbital/lexorbital-module-auth.git \
main \
--squashParameters:
--prefix=modules/auth: Where to place the module in the monorepogit@github.com:...: Module repository URLmain: Branch to integrate--squash: Merge history into a single commit (recommended)
3.2. Docking Script
The Core provides a script to simplify:
lexorbital-core/scripts/add-module.sh
#!/bin/bash
set -e
MODULE_NAME=$1
MODULE_REPO=$2
MODULE_BRANCH=${3:-main}
if [ -z "$MODULE_NAME" ] || [ -z "$MODULE_REPO" ]; then
echo "Usage: ./scripts/add-module.sh <module-name> <repo-url> [branch]"
echo "Example: ./scripts/add-module.sh auth git@github.com:lexorbital/lexorbital-module-auth.git"
exit 1
fi
echo "π°οΈ Docking module ${MODULE_NAME}..."
git remote add -f "${MODULE_NAME}-remote" "$MODULE_REPO"
git subtree add --prefix="modules/${MODULE_NAME}" "${MODULE_NAME}-remote" "$MODULE_BRANCH" --squash
git remote remove "${MODULE_NAME}-remote"
echo "β
Module ${MODULE_NAME} docked successfully in modules/${MODULE_NAME}"Usage:
cd lexorbital-core
./scripts/add-module.sh auth git@github.com:lexorbital/lexorbital-module-auth.git3.3. Post-Docking Verification
After docking, verify:
# 1. Module is present
ls -la modules/auth/
# 2. Manifest is valid
cat modules/auth/lexorbital.module.json
# 3. Meta-Kernel detects the module
pnpm run start:dev
# Logs: "β
Module auth-module loaded successfully"4. Module Update (Pull Upstream)
4.1. git subtree pull Command
From lexorbital-core, to update a
module:
git subtree pull \
--prefix=modules/auth \
git@github.com:lexorbital/lexorbital-module-auth.git \
main \
--squash4.2. Update Script
lexorbital-core/scripts/update-module.sh
#!/bin/bash
set -e
MODULE_NAME=$1
MODULE_REPO=$2
MODULE_BRANCH=${3:-main}
if [ -z "$MODULE_NAME" ] || [ -z "$MODULE_REPO" ]; then
echo "Usage: ./scripts/update-module.sh <module-name> <repo-url> [branch]"
exit 1
fi
echo "π Updating module ${MODULE_NAME}..."
git remote add -f "${MODULE_NAME}-remote" "$MODULE_REPO" 2>/dev/null || true
git subtree pull --prefix="modules/${MODULE_NAME}" "${MODULE_NAME}-remote" "$MODULE_BRANCH" --squash
git remote remove "${MODULE_NAME}-remote" 2>/dev/null || true
echo "β
Module ${MODULE_NAME} updated successfully"Usage:
./scripts/update-module.sh auth git@github.com:lexorbital/lexorbital-module-auth.git4.3. Conflict Resolution
If conflicts occur during pull:
# 1. Manually resolve conflicts
git status
# Conflicted files listed
# 2. Edit files to resolve conflicts
code modules/auth/src/service.ts
# 3. Mark as resolved
git add modules/auth/src/service.ts
# 4. Continue merge
git commit5. Contributing to a Module (Push Upstream)
5.1. Golden Rule: Do NOT Modify in lexorbital-core
β οΈ IMPORTANT: Modifications
must be made in the module repository,
not in
lexorbital-core/modules/.
Reason:
- Maintain module autonomy
- Preserve module Git history
- Avoid desynchronization
5.2. Recommended Workflow
Step 1: Clone Module Separately
git clone git@github.com:lexorbital/lexorbital-module-auth.git
cd lexorbital-module-authStep 2: Develop in Module
# Create feature branch
git checkout -b feat/add-oauth2
# Develop
# ... modifications ...
# Commit (Conventional Commits)
git add .
git commit -m "feat: add OAuth2 Google provider"
# Tests
pnpm test
# Push
git push origin feat/add-oauth2Step 3: Pull Request
Create a PR on the module repository
(lexorbital-module-auth).
Step 4: Merge
Once PR is merged into module main.
Step 5: Update Core
cd lexorbital-core
./scripts/update-module.sh auth git@github.com:lexorbital/lexorbital-module-auth.git5.3. Exceptional Case: git subtree push
If a modification absolutely must be
made in lexorbital-core (critical hotfix),
we can push to the module:
git subtree push \
--prefix=modules/auth \
git@github.com:lexorbital/lexorbital-module-auth.git \
hotfix-branchβ οΈ Warning: This command can be very slow (it filters entire history).
Alternative Workflow (faster):
# 1. Extract subdirectory
git subtree split --prefix=modules/auth -b temp-auth-branch
# 2. Push to module
git push git@github.com:lexorbital/lexorbital-module-auth.git temp-auth-branch:hotfix
# 3. Cleanup
git branch -D temp-auth-branch6. Module Discovery by Meta-Kernel
6.1. Automatic Scan
On startup, the Meta-Kernel scans all subdirectories
of modules/:
// meta-kernel/src/core/module-loader.service.ts
async discoverModules(): Promise<ModuleManifest[]> {
const modulesDir = path.join(__dirname, '../../../modules');
const modules: ModuleManifest[] = [];
const dirs = await fs.readdir(modulesDir, { withFileTypes: true });
for (const dir of dirs) {
if (!dir.isDirectory()) continue;
const manifestPath = path.join(modulesDir, dir.name, 'lexorbital.module.json');
if (await fs.pathExists(manifestPath)) {
const manifest = await fs.readJSON(manifestPath);
modules.push(manifest);
}
}
return modules;
}6.2. Manifest Validation
For each discovered module, the Meta-Kernel validates:
validateManifest(manifest: ModuleManifest): void {
// 1. Required fields
if (!manifest.name) throw new Error('Missing field: name');
if (!manifest.version) throw new Error('Missing field: version');
if (!manifest.type) throw new Error('Missing field: type');
// 2. Name format
if (!manifest.name.startsWith('lexorbital-module-')) {
throw new Error('Module name must start with "lexorbital-module-"');
}
// 3. Compatibility
if (!semver.satisfies(CORE_VERSION, manifest.lexorbital.compatibility.metaKernel)) {
throw new Error(`Module incompatible with Core version ${CORE_VERSION}`);
}
// 4. Dependencies
for (const dep of manifest.lexorbital.dependencies?.required || []) {
if (!this.loadedModules.has(dep)) {
throw new Error(`Missing required dependency: ${dep}`);
}
}
}6.3. Dynamic Loading
Once validated, the module is loaded:
async loadModule(manifestPath: string): Promise<void> {
const manifest = await fs.readJSON(manifestPath);
this.validateManifest(manifest);
// Dynamic loading (ESM)
const modulePath = path.dirname(manifestPath);
const entryPoint = path.join(modulePath, manifest.entryPoints.main);
const moduleExports = await import(entryPoint);
// Registration
this.loadedModules.set(manifest.lexorbital.role, {
manifest,
exports: moduleExports,
});
console.log(`β
Module ${manifest.lexorbital.role} loaded successfully`);
}7. Module Undocking
7.1. Command
git rm -r modules/auth
git commit -m "chore: remove auth module"7.2. Undocking Script
lexorbital-core/scripts/remove-module.sh
#!/bin/bash
set -e
MODULE_NAME=$1
if [ -z "$MODULE_NAME" ]; then
echo "Usage: ./scripts/remove-module.sh <module-name>"
exit 1
fi
echo "ποΈ Undocking module ${MODULE_NAME}..."
git rm -r "modules/${MODULE_NAME}"
git commit -m "chore(modules): remove ${MODULE_NAME}"
echo "β
Module ${MODULE_NAME} undocked successfully"7.3. Pre-Undocking Checks
8. Module Replacement
8.1. Use Case
Replace a module with a new implementation (same interface, different implementation).
Example: Replace
auth-module-jwt with
auth-module-oauth.
8.2. Workflow
# 1. Undock old module
./scripts/remove-module.sh auth-jwt
# 2. Dock new module
./scripts/add-module.sh auth-oauth git@github.com:lexorbital/lexorbital-module-auth-oauth.git
# 3. Update config (if necessary)
# Edit lexorbital-core/.env or config files
# 4. Test
pnpm run start:dev9. Integration Checklist
For a module to be docked:
Sources and References
This document lists the sources consulted and references used for the creation and development of the LexOrbital Core repository as a whole.
Architecture and Design
Architectural Patterns
- Modular Architecture Patterns : Inspiration for the modular system design
- Microservices Architecture : Principles applied to module orchestration
- Plugin Architecture : Design pattern used for module integration
Orbital Metaphor
- @TODO: Add orbital metaphor
Technologies and Frameworks
- @TODO: Add technologies and frameworks
Infrastructure
- Docker : Containerization
- Official documentation : https://docs.docker.com/
- Docker Compose : Container
orchestration
- Official documentation : https://docs.docker.com/compose/
Development Tools
Package Management
- pnpm : Package manager
- Official documentation : https://pnpm.io/
Linting and Formatting
- ESLint : JavaScript/TypeScript
linter
- Official documentation : https://eslint.org/
- Commitlint : Commit message
validation
- Official documentation : https://commitlint.js.org/
Git
- Git Subtree : Module integration
- Documentation : https://git-scm.com/book/en/v2/Git-Tools-Subtree-Merging
Standards and Conventions
Conventional Commits
- Specification : https://www.conventionalcommits.org/
- Used for commit message standardization
Documentation
- @TODO: Add documentation standards
Licenses and Compliance
Open Source Licenses
- MIT License : Recommended license
for modules
- Full text : https://opensource.org/licenses/MIT
Security
- Security best practices for open source projects
- Responsible vulnerability disclosure guidelines
Privacy and Data Protection
- @TODO: Add privacy and data protection best practices
Inspiration and Philosophy
Design Principles
- Minimalism : Minimal and essential architecture
- Modularity : System composed of autonomous and replaceable modules
- Security : Priority on security and compliance
- Elegance : Clean and maintainable code
Key Concepts
- Vessels : Modules designed as autonomous vessels
- Orbital System : Architecture based on an orbital system
- Law-Driven Core : Core guided by contracts and rules
Notes
This list is non-exhaustive and will be updated as the project develops. The sources mentioned have served as references for the design, implementation, and documentation of the LexOrbital Template Module system.
π Appendix: Module Manifest Validation
Overview
The manifest validation system ensures that your LexOrbital module is properly configured and compliant with ecosystem standards.
Validation Components
1.
JSON Schema
(schemas/module-manifest.schema.json)
A complete JSON Schema that defines:
- Required and optional fields
- Formats and patterns (semver, URLs, etc.)
- Enumerations for types and layers
- Custom validation rules
- Constraints on default values
2.
Automated Tests
(tests/module-manifest.test.ts)
Test suite that verifies:
- β Compliance with JSON schema
- β Template customization (no default values)
- β Presence of all required fields
- β Format validity (semver, URLs)
- β Type and layer consistency
- β Tag uniqueness
3. Documentation
(schemas/README.md)
Complete guide on:
- Schema usage
- Validation rules
- Available types and enumerations
- Examples and use cases
π Usage
Quick Validation
# Validate your manifest
pnpm test:manifest
# Detailed validation with error messages
pnpm validate:manifest
# All tests (including manifest)
pnpm test:allIDE Integration
The schema is automatically recognized by modern IDEs
thanks to the $schema property in
lexorbital.module.json:
{
"$schema": "./schemas/module-manifest.schema.json",
...
}IDE Features:
- π― Autocompletion of fields
- π‘ IntelliSense with documentation
- β οΈ Real-time validation
- π Tooltips with descriptions
CI/CD Validation
Validation tests are automatically executed in the CI/CD pipeline to ensure that:
- The manifest is valid
- All required fields are present
- The template has been customized
- Formats are correct
π Customization Checklist
Before committing your module, make sure you have customized:
Basic Information
LexOrbital Configuration
Metadata
Entry Points
π― Types and Layers
Module Types
| Type | Description | Example |
|---|---|---|
utility |
Utilities and helpers | Formatting functions, date helpers |
service |
Business services | Authentication service, API client |
ui-component |
UI components | Buttons, forms, modals |
data-provider |
Data providers | Database connectors, API wrappers |
middleware |
Middlewares | Logging, validation, transformation |
plugin |
Extensible plugins | Extensions, system hooks |
theme |
Visual themes | Styles, visual configurations |
integration |
Third-party integrations | Stripe, SendGrid, AWS |
library |
Generic libraries | Collections, algorithms |
Architectural Layers
| Layer | Description | Examples |
|---|---|---|
infrastructure |
Technical infrastructure | Database, caching, logging |
domain |
Business logic | Entities, business rules |
application |
Application coordination | Use cases, services |
presentation |
User interface | Components, views, controllers |
integration |
External integrations | APIs, webhooks, adapters |
LexOrbital Template Module Tests
This directory contains tests for the LexOrbital module template.
Test Structure
1.
template-module.test.ts
Basic tests to verify that the template structure is functional.
Execution:
pnpm test2.
module-manifest.test.ts
Validation tests for the
lexorbital.module.json manifest.
Execution:
pnpm test:manifest
# or
pnpm validate:manifest # with detailed outputβ οΈ Important: Manifest Validation Tests
The tests in module-manifest.test.ts
will fail by default until you have
customized your module. This is intentional!
Why do these tests fail?
These tests verify that you have customized the template with your own moduleβs information. They fail as long as you use the templateβs default values:
- β
name: "lexorbital-template-module" - β
lexorbital.role: "template-module" - β
maintainer.name: "LexOrbital Core" - β
repository.url: "https://github.com/YohanGH/lexorbital-template-module"
How to make these tests pass?
- Open
lexorbital.module.json - Modify the following fields:
{
"$schema": "./schemas/module-manifest.schema.json",
"name": "lexorbital-my-awesome-module", // β
Change this
"description": "My awesome module for...", // β
Change this
"type": "service", // β
Choose the right type
"version": "0.1.0",
"entryPoints": {
"main": "dist/index.js",
"types": "dist/index.d.ts"
},
"lexorbital": {
"role": "authentication-service", // β
Change this
"layer": "application", // β
Choose the right layer
"compatibility": {
"metaKernel": ">=1.0.0 <2.0.0"
},
"tags": ["auth", "security"] // β
Add your tags
},
"maintainer": {
"name": "Your Name", // β
Change this
"contact": "your.email@example.com" // β
Change this
},
"repository": {
"type": "git",
"url": "https://github.com/your-username/your-repo" // β
Change this
},
"license": "MIT"
}- Rerun the tests:
pnpm test:manifestExample Output with Errors
If you havenβt customized the manifest, youβll see:
π΄ Module Manifest Customization Issues:
β Please change the 'name' field from 'lexorbital-template-module' to your module name
β Please change 'lexorbital.role' from 'template-module' to your module's actual role
β Please update 'maintainer.name' with your name or organization
β Please update 'repository.url' with your repository URL
β οΈ Consider updating 'description' to remove references to 'template'
π See docs/02_module-manifest.md for more information
Example Successful Output
Once the manifest is customized:
β tests/module-manifest.test.ts > Module Manifest Validation (17 tests) 45ms
β should load the manifest file
β should load the schema file
β should validate the manifest against the JSON schema
β should have a customized module name
β should have a meaningful description
β should have a customized role
β should have customized maintainer information
β should have a customized repository URL
...
Test Files 1 passed (1)
Tests 17 passed (17)
JSON Schema Validation
The JSON schema
(schemas/module-manifest.schema.json)
automatically validates:
Required Fields
- β
name:lexorbital-*format (not default) - β
description: 10-500 characters - β
type: One of the valid types - β
version: Valid semver - β
entryPoints: Entry points todist/ - β
lexorbital: Complete configuration - β
maintainer: Name and contact - β
repository: Type and URL - β
license: License identifier
Valid Module Types
utility,service,ui-component,data-providermiddleware,plugin,theme,integration,library
Valid Architectural Layers
infrastructure,domain,application,presentation,integration
CI/CD Integration
These tests are automatically executed in the CI/CD pipeline to ensure that:
- The manifest is valid according to the JSON schema
- All required fields are present
- The template has been customized (no default values)
- Versions follow the semver format
- URLs and formats are correct
Local Development
Run Manifest Tests Only
pnpm test:manifestNeed Help?
If the tests fail and you donβt understand why:
- Read the detailed error messages
- Consult
docs/02_module-manifest.md - Verify that you have modified ALL default values
- Consult
schemas/README.mdfor validation rules
The tests are there to guide you! π―