- All documentation should be as concise as possible and should avoid explaining everything. Focus on the most significant details for a human reader.
- When writing PR descriptions, do not describe every technical detail of the PR and don't include much, if any, code. Just explain any important decisions, technical gotchas that may not be obvious, and the overall intent of the PR. Link issues if possible.
- When writing issues, follow the same guidelines: do not write lots of code examples and thoroughly lay out the entire proposed implementation plan. Prefer tables over lists of options, but don't put too much in each table cell.
- When writing inline comments, do not explain exactly what the code does. Be concise, focusing on intent and any non-obvious gotchas.
- Don't add comments to code that doesn't need them. Code should ideally be self-documenting.
- When replying to review feedback, give the conclusion and the change only — "Confirmed, fixed in abc1234" is a complete reply. Do not repeat evidence the reviewer can read for themselves, do not explain how the mistake happened, and do not volunteer follow-up work nobody asked for. If you disagree, give the reason in a sentence or two and stop.
- Write all the above in Simplified Technical English (ASD-STE100) where possible.
IMPORTANT: Use the /sandbox/ folder for all temporary working files, test outputs, notes, and drafts.
- The
sandbox/folder is in.gitignoreand will not be committed - Store test plans, results, TODO lists, and exploration notes here
- Do NOT create working files in other directories (they may accidentally be committed)
- Clean up the sandbox when work is complete if appropriate
This is the FINOS Architecture as Code monorepo containing the Common Architecture Language Model (CALM) specification and associated tools.
CALM is a declarative, JSON-based modeling language for describing complex software architectures, particularly in regulated environments like financial services.
architecture-as-code/
├── calm/ # CALM specification (JSON schemas)
├── cli/ # TypeScript CLI (@finos/calm-cli)
├── calm-hub/ # Java/Quarkus REST API backend
├── calm-hub-ui/ # React frontend for CALM Hub
├── calm-server/ # TypeScript server (@finos/calm-server)
├── calm-plugins/vscode/ # VSCode extension
├── calm-models/ # TypeScript data models
├── calm-widgets/ # React visualization components
├── calm-ai/ # AI agent tools & prompts
├── calm-studio/ # SvelteKit visual CALM editor — nested npm-workspace monorepo
├── calm-guard/ # Next.js continuous-compliance platform (CALMGuard)
├── shared/ # Shared TypeScript utilities
├── docs/ # Docusaurus documentation site
├── examples/ # Example CALM documents — source of truth for the CALM Hub seed scripts
├── experimental/ # Experimental features
├── template-bundles/ # Reusable Handlebars template bundles
├── conferences/ # Conference/workshop material
├── brand/ # Logo and brand assets
└── scripts/ # Repo maintenance scripts (e.g. lockfile validation)
calm-studio/ and calm-guard/ are products with their own internal structure, but their packages
are wired directly into the root npm workspaces. Run all npm commands from the repo root, never
from inside these folders.
calm-studio/— a SvelteKit (Svelte 5) visual CALM editor, itself an npm-workspace monorepo. Its packages and app join the root workspaces viacalm-studio/packages/*andcalm-studio/apps/*. See calm-studio/AGENTS.md for the package list.calm-guard/— a Next.js (App Router) continuous-compliance platform (calmguard), plus its Docusaurus docs (calmguard-docs). Both are root workspaces.
- TypeScript/Node.js — every package except the Java modules below. Built with tsup (esbuild), tested with vitest, managed as npm workspaces off a single root lockfile (see Lockfile Regeneration).
- Java/Maven — the root
pom.xmlis a reactor over six modules. Two carry Java code:calm-hub(Quarkus 3.34+, MongoDB/NitriteDB, TestContainers) andcalm-models(a plain jar).cli,calm,docsandsharedare POM-only placeholders. Note thatcalm-modelsis built by both toolchains — it is an npm workspace and a Maven module. - Documentation — Docusaurus, both for the main site and CALMGuard's
calmguard-docs.
Canonical Node version: 26. .nvmrc pins 26.3.1, CI reads it via
node-version-file: '.nvmrc', and engine-strict=true in .npmrc blocks installs on anything
older. Node 26 is the only version builds and tests are validated against.
node --version # MUST show v26.x.x
nvm use # if not — reads .nvmrc → 26.3.1Running on another major version breaks in ways that are slow to diagnose: native bindings
(@swc/core, @tailwindcss/oxide) resolve for the wrong ABI, and Node 26's global Web Storage API
shadows jsdom's localStorage in tests. @types/node is pinned to ^26 by a root package.json
override and by a Renovate allowedVersions rule, because transitive deps with loose constraints
will otherwise hoist an older major to the root and mask API differences.
Packages that touch localStorage or sessionStorage document their own stubbing pattern — see
calm-hub-ui/AGENTS.md and calm-studio/AGENTS.md.
CRITICAL: npm has a known bug (npm/cli#4828) where
running npm install with an existing node_modules directory prunes optional platform-specific
dependencies (e.g. @tailwindcss/oxide, @swc/core, @esbuild) for platforms other than the
current machine. This causes CI failures on Linux runners when the lockfile was regenerated on macOS.
Correct method — always delete both node_modules and the lockfile:
rm -rf node_modules package-lock.json && npm installNever regenerate the lockfile without deleting node_modules first. The validate-lockfile
CI workflow checks that all expected platform variants are present in package-lock.json.
Read the guide for a package before working on its code, tests, or build.
- calm/AGENTS.md - CALM JSON Meta Schema, schema change workflow, draft/release rules
- cli/AGENTS.md - CLI commands, build pipeline, Commander.js patterns
- calm-hub/AGENTS.md - Java/Quarkus backend, storage modes, security
- calm-hub-ui/AGENTS.md - React frontend, service patterns, component conventions
- calm-server/AGENTS.md - TypeScript CALM server
- calm-plugins/vscode/AGENTS.md - VSCode extension, MVVM architecture
- calm-widgets/AGENTS.md - Widget system, Handlebars templates, common pitfalls
- shared/AGENTS.md - Shared TypeScript utilities consumed across packages
- calm-studio/AGENTS.md - CalmStudio visual editor, CALM 1.2 rules, nested workspaces
- calm-guard/AGENTS.md - CALMGuard compliance platform, agents/skills
IMPORTANT: Always run npm commands from the repository root using workspaces, not from within
individual package directories. Any script below can be narrowed to one package with
--workspace <name>, e.g. npm test --workspace cli.
# npm workspaces (from the repository root)
npm run build # Build all TypeScript workspaces
npm test # Test all TypeScript workspaces
npm run lint # Lint all workspaces
npm run lint-fix # Fix auto-fixable lint issues
npm run build:cli # Build CLI and its dependencies
npm run build:shared # Build shared packages
npm run link:cli # Link the CLI globally for manual testing
npm run watch --workspace <name> # Watch mode
# Maven reactor (from the repository root)
./mvnw clean install # Build all Maven modules (mainly calm-hub)
./mvnw test # Test all Maven modulesPackage-specific development loops — CLI, VSCode extension, CALM Hub — live in that package's AGENTS.md.
TypeScript packages (npm workspaces) build in order:
calm-models → calm-widgets → shared → cli → calm-plugins/vscode
Always build dependencies before dependent packages. The Maven reactor works this out for itself:
./mvnw clean install.
IMPORTANT: All workspaces use vitest run for the test script, which runs tests once and exits.
Do NOT use vitest without run as it enters watch mode and will hang indefinitely.
IMPORTANT FOR SHARED PACKAGE:
If you modify the shared package, you MUST run tests for ALL workspaces (npm run test) because shared is a dependency for CLI, VSCode extension, and other packages. Changes in shared can break downstream consumers.
npm test -- --coverage # TypeScript packages, with coverage
cd calm-hub && ../mvnw verify # Java tests with coverage (JaCoCo on by default)
# One file — you must be at or below that package's directory so vitest.config.ts resolves
npx vitest run ${TEST_FILE}
# Java integration tests (requires Docker)
cd calm-hub && ../mvnw -P integration verifyAll new code needs tests covering both success and error cases. Aim for >80% coverage on new code, 100% on critical paths.
Conventional Commits, enforced by commitlint via husky — invalid messages are rejected at commit
time. Format is <type>(<scope>): <subject>, subject with no trailing period.
- type (required, lowercase):
feat,fix,docs,style,refactor,test,chore,perf,ci,build,revert - scope (optional but preferred):
cli,shared,calm-widgets,calm-hub,calm-hub-ui,docs,vscode,deps,ci,release
Run npx cz for an interactive prompt.
Type and scope drive the automated release, so neither is cosmetic: cli/.releaserc.json releases
on the cli, shared, calm-models, calm-ai and calm-widgets scopes, and its fallback rule
also releases any unscoped feat, fix, perf or revert. Check that file before assuming a
commit is release-neutral.
Before considering any code change ready:
- All tests pass with coverage:
npm test -- --coverageANDcd calm-hub && ../mvnw verify - All new code has tests (unit and/or integration tests)
- Linting passes:
npm run lint(0 errors) - Code builds successfully:
npm run buildAND./mvnw clean install - Documentation updated if behavior changed
- Test coverage meets requirements (>80% for new code)
- Commit message follows Conventional Commits (enforced by husky)
CRITICAL: Always create a feature branch for your changes and submit a pull request. Never commit directly to the main branch—direct commits will be rejected.
CRITICAL: Always use the repository PR template in .github/pull_request_template.md when creating or updating a pull request. Do not submit ad-hoc PR descriptions when a template exists; populate each section with accurate status.
Branch names are descriptive and conventional-commit-flavoured (feat/add-caching,
fix/mongodb-timeout). Work through the pre-commit checklist above before pushing, follow the
package-specific guide for whatever you touched, and make sure CI is green on the PR.
- User docs: https://calm.finos.org (calm-hub also serves generated Swagger)
- Issues: https://github.com/finos/architecture-as-code/issues
- Discussions: https://github.com/finos/architecture-as-code/discussions