Modernizing VistA development on the VA's Health Cloud.
vista-cloud-dev is an ecosystem of composable tools that bring present-day software engineering — version control, unit testing, linting, formatting, an IDE language server, and AI-agent surfaces — to VistA, the VA's health information system.
VistA is built using the M application database that runs on Intersystems IRIS, which is the same M-based platform and technology that all Epic healthcare systems use worldwide. Beyond the common core technology as Epic, all VistA systems have been migrated to a single integrated cloud platform provided by Amazon Web Services, enabling the next generation of cloud-based AI-driven healthcare innovation and services. For information on the VistA Health Cloud see https://cloudvista.github.io.
vista-cloud-dev is built for both IRIS and YottadB database engines and is open to the community. The work is under active development — interfaces are stabilizing but not yet at a tagged stable release.
The guiding principle is simple:
Git is the source of truth; the database is just the engine.
You write .m files in git, sync them into a running IRIS (or YottaDB)
instance, test against the live engine, and pull changes back — instead of
treating the database as the place source code "lives."
- New here? Read docs — the
modernization strategy, the
m-clispec, and the toolchain dependency map (the why behind everything below). - Setting up a machine? Clone the org via
workspace —
./bootstrap.shclones every repo and checks out the right branches. - Want the tool? m-cli is
the
mcommand; its README has install + first-run instructions. - Want to help? See Contributing.
- Why this exists
- The four capabilities
- Architecture at a glance
- The components
- The
mcommand surface - Design principles
- Contributing
- Shared CI
VistA is one of the largest and longest-lived production codebases in the
world, but M development has historically lacked the everyday tooling other
ecosystems take for granted. VA's migration of VistA onto IRIS — inside the
FedRAMP-HIGH VA Enterprise Cloud (AWS GovCloud) — is an opportunity to close
that gap. vista-cloud-dev supplies four things M developers don't have today:
| Gap | What we provide |
|---|---|
| Version control | Materialize routines out of IRIS into a git-friendly mirror, edit as .m, push back. |
| Modern testing | Assertion-based unit tests (^STDASSERT) run by m test against the live engine, with coverage. |
| M-aware IDE | m fmt, m lint, and an LSP language server built on a real M parser. |
| A standard library | m-stdlib — JSON, regex, UUIDs, crypto, CSV, dates, collections, and 25+ more, conformance-tested. |
Everything is engine-neutral where it can be (works on YottaDB and IRIS) and engine-specific only where it must be (the IRIS source boundary).
Each gap above, as a flow.
Two things get version-controlled: individual routines and whole KIDS patches.
Routines — m pull / m push round-trips M code between IRIS and .m
files on the filesystem, which version-control through GitHub like any other
code.
flowchart LR
gh["GitHub"]
fs["m routines"]
iris[("IRIS<br/>VistA database")]
gh <-->|git pull / push| fs
fs <-->|m pull / m push| iris
Patches — kids-vc decomposes a monolithic .KID patch into its
components (routines, FileMan data dictionaries, …) so they can be diffed and
stored in GitHub, and assembles them back into an installable .KID that is
pushed into IRIS.
flowchart LR
gh["GitHub"]
comps["patch components"]
kid[".KID patch<br/>(assembled)"]
iris[("IRIS<br/>VistA database")]
gh <-->|git pull / push| comps
kid -->|m kids decompose| comps
comps -->|m kids assemble| kid
kid -->|install| iris
Write a *TST.m suite first, run it with m test against the live engine via
^STDASSERT, and get machine-readable results plus coverage.
flowchart TB
tst["*TST.m suite<br/>(written test-first)"]
tst -->|m test| runner["m test runner"]
runner -->|executes on| engine[("YottaDB / IRIS engine")]
engine -->|"^STDASSERT pass / fail"| report["TAP / JUnit report"]
runner -->|m coverage| cov["LCOV coverage<br/>≥85% gate"]
One parser feeds every editor feature: format, lint, and the language server
all sit on the m-parse syntax tree.
flowchart TB
src[".m source"]
src --> mparse["m-parse<br/>tree-sitter-m → syntax tree"]
mparse --> fmt["m fmt<br/>AST-preserving format"]
mparse --> lint["m lint<br/>rule engine"]
mparse --> lsp["m lsp<br/>highlight · go-to-def · diagnostics"]
Your M code calls conformance-tested STD* modules instead of re-inventing
per-site utilities — the same on YottaDB and IRIS.
flowchart TB
app["Your M routine<br/>do ^STDx(...)"]
app --> lib
subgraph lib["m-stdlib — pure-M · YottaDB & IRIS"]
direction LR
fmt2["data formats<br/>STDJSON · STDREGEX · STDCSV"]
enc["encoding<br/>STDUUID · STDB64 · STDHEX"]
test["testing<br/>STDASSERT · STDMOCK · STDFIX"]
util["utilities<br/>STDLOG · STDDATE · STDCOLL"]
end
A developer or AI agent drives m — the centerpiece — which fans out to
its four jobs (sync, parse, package, test), all of which act on the
vista-iris instance at the bottom.
flowchart TB
user["Developer / AI agent"]
user --> mcli["<b>m-cli</b> — the <code>m</code> busybox"]
mcli -->|m pull / push| irissync["irissync<br/>source sync"]
mcli -->|parse tree| mparse["m-parse<br/>tree-sitter-m"]
mcli -->|m kids| kidsvc["kids-vc<br/>KIDS packaging"]
mcli -->|m test| stdlib["m-stdlib<br/>M runtime + tests"]
irissync --> vistairis["<b>vista-iris</b><br/>VistA loaded into IRIS for Health"]
mparse --> vistairis
kidsvc --> vistairis
stdlib --> vistairis
classDef center fill:#00ADD8,stroke:#024,stroke-width:2px,color:#fff;
classDef engine fill:#1f2937,stroke:#111,color:#fff;
class mcli center;
class vistairis engine;
Driven directly from a terminal, or by an AI agent through the m-dev-tools-mcp server (which exposes every
mcommand as an MCP tool). Underpinning the whole stack: docs (strategy/specs), go-cli-template (the sharedclikitCLI grammar every binary inherits), and workspace (the clone-all manifest + bootstrap).
A second, read-only track helps you understand the VistA codebase while you work in it — M-aware editing in VS Code, and code/data-model/docs lookups through vista-info-hub.
flowchart TB
user["Developer"]
user --> vscode["VS Code + M plugin<br/>syntax highlighting · LSP · go-to-definition"]
user --> hub["vista-info-hub<br/>CLI · TUI · web"]
vscode -->|"language intelligence · m lsp"| awareness["VistA situational awareness<br/>routines · FileMan data dictionary · VA docs"]
hub -->|routine / file / risk queries| awareness
Key invariants
- Single writer —
irissync pushis the only thing that writes routines back into IRIS; everything else (list/pull/status/verify) is read-only by construction. - Single parser —
m-parseis the one M parse engine;fmt,lint, andlspall sit on it. It runs thetree-sitter-mgrammar as WASM throughwazero, so the whole toolchain stays a static binary with no CGO. - One command grammar — every Go binary builds on
go-cli-template'sclikit, so they share an identical output contract (text|json|auto), error model, and exit-code ladder.maggregates them all viam schema, which is exactly whatm-dev-tools-mcpreflects to agents.
| Repo | Role |
|---|---|
| docs | The living design/strategy corpus — the why and how of the whole effort: the modernization strategy, the m-cli spec, ADRs, the dev-bridge design, and the toolchain dependency map. |
| doc-framework | A portable documentation standard + zero-dependency Python validator. Defines eight document types (spec, adr, investigation, research, plan, guide, log, map), enforces frontmatter, cross-references, and supersession in CI. |
| Repo | Role |
|---|---|
| m-cli | The m busybox — one static Go binary that fronts the whole toolchain. Native commands (fmt, lint, lsp, test, coverage, watch) plus dispatched sibling namespaces (m pull/push/… → irissync, m kids … → kids-vc). Cross-engine: YottaDB and IRIS. |
| m-parse | The engine-neutral M parse substrate. Embeds the tree-sitter-m grammar as WASM and runs it through wazero (pure-Go) so the toolchain has zero C dependencies at runtime. Powers fmt/lint/lsp. |
| go-cli-template | The shared Go CLI scaffold (clikit): a consistent command grammar, --output text|json|auto, deterministic exit codes (0 ok · 1 runtime · 2 usage · 3 check · 4 refused), TTY-gated styling, and a reflected schema contract. Every binary in the org inherits it. |
| Repo | Role |
|---|---|
| irissync | Owner of the IRIS source boundary, in both directions. Materializes routines from an IRIS namespace into a git-friendly mirror + verifiable manifest (read side, safe by construction), and writes edited routines back (push, gated by single-writer locks + manifest conflict checks). Talks Atelier REST; enterprise auth (PIV/OIDC, mTLS). |
| kids-vc | Version control for VistA KIDS distributions. Decomposes a monolithic .KID patch into a per-component tree you can diff and merge in git, and reassembles it byte-identically. Includes a PIKS data-class lint gate that refuses to package Patient/Institution-class FileMan data (PHI/PII guard). |
| vista-iris | A reproducible VistA-on-IRIS container. The full site build (routine/global import + FileMan/Kernel install) is baked into the image, so it boots an already-loaded, operational instance — Management Portal, RPC Broker, HL7 MLLP, and Atelier REST for irissync to connect to. Ships fictitious test data only. |
| Repo | Role |
|---|---|
| m-stdlib | A pure-M standard library — the batteries M never shipped. 32 conformance-tested modules: STDJSON, STDREGEX, STDUUID, STDB64/STDHEX, STDCSV, STDDATE, STDLOG, STDARGS, STDCOLL, STDURL, STDFS, plus the TDD primitives (STDASSERT, STDFIX, STDMOCK, STDSEED) that m test runs on, and optional callout-backed modules (STDCRYPTO, STDCOMPRESS, STDHTTP). Runs identically on YottaDB and IRIS. |
| Repo | Role |
|---|---|
| m-dev-tools-mcp | A thin Model Context Protocol server over the m toolchain. Reads m schema, exposes every command as an MCP tool, and forwards calls with --output json — so an AI agent drives fmt/lint/test/sync through one surface. Safety profiles (default / safe excludes push / all). |
| vista-info-hub | A VistA introspection engine — one binary, many faces (CLI, MCP, REST, web UI, TUI) for querying the VistA code and data model plus the VA Document Library. vista routine …, vista context … (AI-ready markdown), vista search … (FTS5), vista risk …. A single operation registry projects to every interface. |
| Repo | Role |
|---|---|
| workspace | The coordination hub: a clone-all manifest (repos.txt), an idempotent bootstrap.sh for new machines, and git-update-repos to fast-forward every repo. Start here on a fresh checkout. |
m is a busybox: native commands live in m-cli; sibling namespaces are
dispatched to standalone binaries discovered at runtime ($M_<NAME>_BIN, then
alongside m, then $PATH). Missing siblings degrade to stubs so the schema
stays valid.
m fmt AST-preserving formatter (shape-checked: parse(fmt(x)) == parse(x))
m lint query-driven rule engine over the parse tree
m lsp M language server (LSP 3.x over stdio)
m test run *TST.m suites via the engine, ^STDASSERT, TAP/JUnit output
m coverage line + branch coverage → LCOV
m watch re-run lint/fmt (and tests) on change
m schema emit the aggregated command tree as JSON (agent discovery)
m list|pull|status|verify|push → irissync (push is the sole DB writer)
m kids decompose|assemble|roundtrip|lint|parse → kids-vc
Install and first-run instructions live in the m-cli README; machine setup and the end-to-end pull → edit → test → push workflow live in workspace.
- Git-canonical source. The database is the engine, not the repository.
- Engine-neutral by default. YottaDB and IRIS are both first-class; only
the IRIS source boundary (
irissync) is engine-specific. - Static, dependency-free binaries.
CGO_ENABLED=0everywhere — even the M parser runs as WASM viawazero, so there is no libc/C toolchain at runtime. - One contract, many surfaces. A single command grammar (
clikit) and a reflectedschemamean CLI flags, MCP tools, and JSON envelopes never drift. - Safe by construction. Read verbs can't mutate the database; the single writer is locked and conflict-checked; KIDS packaging refuses PHI/PII.
- Conformance-tested.
m-stdlibmodules ship with vendored RFC/NIST corpuses and an ≥85% coverage gate per module. - Machine-reviewable docs. Every design doc is validated in CI by
doc-framework.
Contributions are welcome. The org-wide guides live in this .github repo:
The codebase is licensed under Apache-2.0, with two deliberately isolated
exceptions (the MIT VS Code extensions and the AGPL-derived embedded grammar
artifact in m-parse) — see
NOTICE.
Not affiliated with or endorsed by the US Department of Veterans Affairs. "VistA" refers to the public-domain VA health information system. These tools operate on VistA source and ship with fictitious test data only — never load real patient (PHI/PII) data into instances used with them.
Go repos call the reusable workflow in this repo:
uses: vista-cloud-dev/.github/.github/workflows/go-ci.yml@main