Active development YottaDB · IRIS Built with Go + M

VistA Forge

The hardened, industry-standard VistA/M toolchain.

Work on VistA like it's 2026, not 1985. VistA Forge gives M the developer experience every other language takes for granted: format and lint in your editor, navigate over a real language server, run unit tests with coverage against a live engine on every push, call a 40-module standard library instead of hand-rolling utilities, and ship VistA patches that provably install — and provably back out. Your code lives in git; the M engine is just the runtime. One docker pull gets you a running VistA; one static binary gets you the whole toolchain — identical on YottaDB and InterSystems IRIS.

docker pull ghcr.io/vista-forge/vista-iris:latest

A fully installed VistA-on-IRIS, public and pullable today. The toolchain repos are opening as they stabilize — see what's available now.

Hardened. Industry-standard.

The tagline makes two claims, and both are load-bearing.

VistA — the VA's public-domain hospital information system — has run real hospitals for over four decades and is one of the largest working bodies of M (MUMPS) code in existence. Yet developing on it today still means working the way its authors did in the 1980s: code lives in the database rather than in git; there is no formatter, no linter, no language server, no unit-test runner, no coverage, no CI; and a patch installs into a live system with no reliable way to back it out. VistA Forge closes that gap — not by rewriting VistA, but by building the modern loop around it.

Hardened — the VistA layer

VistA, treated the way regulated industries treat production software

Nothing here is enforced by convention or a review note. Every boundary is a generated registry held by a red gate.

  • Contract/registry-based seams. Every cross-layer boundary — the m/v waterline, the client-server dispatch seam, the engine seam — is a generated registry held by a red gate.
  • TDD for every module. Each VSL* module is built test-first against live VistA, with per-module coverage gates; each Go client the same way.
  • Full-corpus, live-system testing. Suites and executable examples run in CI against two complete live VistA systems, each carrying VistA's full ~40k-routine base.
  • Provable reversibility. A release tag can only exist after a build → install → verify → test → uninstall cycle diffs byte-clean against baseline on both engines.
  • Declared data ownership. Modules declare their file footprints, exactly one module may write a given file, and every mutating verb carries fail-closed, host-attributed audit.

Industry-standard — the M layer

The tooling every mainstream language takes for granted, built on the M standard itself

And because the m-* half is engine-neutral, none of it is VistA-bound — the same toolchain works on any M system.

  • The M standard, machine-readable. m-standard reconciles the Annotated M Standard, YottaDB, IRIS, and the VA's SAC/XINDEX rules into one citable reference that parsers, linters, and AI agents consume directly.
  • One grammar, generated from that standard. tree-sitter-m parses the full ~39k-routine VistA corpus at over 99% clean and stamps every token with its portability tier — driving the first real formatter, linter, and LSP server M has ever had.
  • Validated beyond VistA. m-modern-corpus snapshots ~4,000 routines of modern open-source M as a second validation corpus — proving the rules hold on today's idioms, not just VA legacy style.
  • The M Standard Library. 40 STD* modules — JSON, HTTP(S), JWT, crypto, UUIDs, regex, S3, testing — conformance-tested against vendored RFC/NIST corpuses, identical on both engines.
  • Mainstream delivery. Git-canonical .m source, static Go binaries, Docker engines, and CI on every push.

By the numbers

A red anywhere is a hard stop.

Measured from the repos, July 2026. The gating is rigid top to bottom — it blocks the commit, the merge, or the release tag. Nothing in the stack ships around a failing gate.

3,200+
M assertions across 64 suites and 1,400+ test cases — every suite run on both engines
1,300+
Go test functions (665 m-layer, 667 v-apps), table-driven
21
repos gated on every push; 15 layer-bearing repos run the waterline gates
≥85%
per-module coverage floor, alongside zero lint findings at --error-on=error
Hardening surfaces and their measures
Hardening surfaceMeasure
M unit tests (MSL + VSL) 64 suites · 1,400+ test cases · 3,200+ assertions, every suite run on both engines
Go unit tests (m-apps + v-apps) 1,300+ test functions (665 m-layer, 667 v-apps), table-driven
Executable doc examples 51 generated example programs from 500+ @example tags, run against the live VistA engines
CI coverage 21 repos gated on every push; 15 layer-bearing repos each run the waterline gates
m/v waterline checks G1–G4 (m arch check: dependency direction, no VistA symbols below the line, transport monopoly, seam pin) in every layer-bearing repo's CI, plus a scheduled org-wide meta-gate backstop
m-engine waterline checks an executable conformance gate per driver — a driver binary that can't pass it can't ship
VSL drift gates 24 red gates in one make gates run — ICR, namespace, engine-access, manifest/dispatcher/envelope drift, data ownership, additive-only compat
Hard stops lint --error-on=error zero findings · ≥85% per-module coverage · release only on a byte-clean lifecycle, both engines

The stack at a glance

Two layers, split by an enforced waterline.

The VistA layer (v-*) is built from one repeating shape — a v-app, where app is a VistA functional domain. Each domain ships as a client and a server joined by a client-server API, consolidating an entire category of VistA-specific functionality into one interface the end user actually drives. The M layer (m-*) is the engine toolchain, seam, and runtime every domain is built on. Each seam row is itself an enforced contract, held by a generated registry and a red gate rather than convention.

VistA layer · v-* — requires Kernel / FileMan / KIDS
v-app
End-user client application (Go) for a v-stdlib domain — database, tasks, monitoring — using mainstream interface and naming conventions, with comprehensive quality, safety, and unit tests. VistA-specific terminology modernized to plain terms.
v-api
client-server API — carries every client-to-server verb call, audited
v-stdlib
VistA Standard Library (VSL). Wrappers of VistA infrastructure applications (FileMan, Kernel, …) in modern, mainstream formats, naming conventions, and APIs.
the m/v waterline — does this code work on a bare M engine with no VistA installed? Dependency is one-way: v → m, never back.
M layer · m-* — runs on any M engine, VistA or not
m-toolchain
The m dev tools — fmt · lint · lsp · test · coverage — all on one shared parser.
m-stdlib
M Standard Library (MSL). A portable, industry-standard M library of 40 STD* runtime modules — JSON, HTTP, crypto, testing, and more.
m-driver-sdk
M engine seam — the only path to a live engine
m engines
YottaDB / IRIS — run VistA; vendor specifics contained in the drivers (m-ydb, m-iris).
The two standard libraries this stack is built on. The VistA Standard Library (VSL) is a thin wrapper around VistA's bespoke technology — Kernel, FileMan, KIDS — reframed in modern mainstream terms, so working against VistA feels like working against an ordinary, well-typed API. The M Standard Library (MSL) is a suite of industry-standard libraries that make M a peer of other mainstream languages instead of a special case.

What's here, by developer task

The everyday loop M never had.

Write M like any modern language

m fmt (AST-preserving formatter), m lint (query-driven rule engine, with XINDEX/Kernel compatibility profiles), and m lsp (an LSP 3.x language server) all sit on one parserm-parse, which embeds the tree-sitter-m grammar as WASM and runs it through wazero. Static Go binaries, no CGO, no C toolchain at runtime.

Test against a real engine, with coverage

m test runs *TST.m suites on a live YottaDB or IRIS engine via ^STDASSERT, with machine-readable results; m coverage produces LCOV with per-module coverage gates. Every library in the org is built test-first and gated on both engines.

Stop hand-rolling utilities

m-stdlib is a pure-M library of 40 STD* modules: data formats (STDJSON, STDXML, STDCSV, STDREGEX), encoding, testing (STDASSERT, STDMOCK), crypto and auth (STDCRYPTO, STDJWT), networking (STDHTTP, STDS3), plus dates, logging, collections, strings, math, and filesystem.

Reach an engine exactly one way

m-driver-sdk defines the vendor-neutral driver contract — typed verbs, a structured engine-error model, honest capability documents, and an executable conformance gate any driver binary must pass. Everything above the seam reaches an engine only through this contract.

Treat VistA patches as code

v-pkg gives KIDS — VistA's native package/patch format — a real lifecycle: parse, classify, lint, decompose, assemble, roundtrip, diff, build, install, verify, snapshot, restore, uninstall, attest. Decompose a distribution into a git-diffable component tree and reassemble it byte-identically; install, verify, and cleanly back out against a live engine.

Administer VistA with plain-noun commands

The sysadmin platform pairs each engine-side VSL* module with a host-side v <domain> command, generated — not hand-wired — from the VSL manifest. Plain nouns a developer can guess: v pkg, v rpc-debug, v rpc-tap. VA product names never appear in a command; a lint gate enforces the plain language.

Run VistA on your own machine

vista-iris publishes a multi-arch container of WorldVistA on IRIS for Health Community — the full site build is baked into the image, so it boots already operational: Management Portal and REST, RPC Broker for CPRS, HL7 MLLP, IRIS superserver. Fictitious test data only.

Drive it all with an AI agent

Every binary shares one command grammar (clikit): --output text|json|auto, a versioned JSON envelope, a deterministic exit-code ladder, and a reflected schema command — so an agent invokes the same gated surface a human uses and gets machine-parseable results.

Architecture

Why registries — VistA's failure mode, inverted.

Classic VistA integrates by reaching into other packages' globals: every application owns its own data and freely reads and writes everyone else's, with the agreements recorded in prose nobody executes, naming policed by human review, and patches installed with no reliable back-out. The result is the coupling archaeology every VistA developer knows. Here the same concerns are declared, generated, and red-gated — one discipline, source-tag → generate → registry → red-gate, at every layer.

Surface Registry (generated) Red gate
Repo layering ecosystem.json — layer per repo arch-waterline in every repo's CI (G1–G4), plus a scheduled bidirectional meta-gate
Engine access driver capability document + seam contract executable conformance gate per driver; an engine-access scan red-gates any hand-rolled transport
Admin verbs vsl-manifest.json → generated dispatch table + host bindings dispatch/bindings drift gates; the published surface is additive-only against the last release tag
Data ownership per-module @file <n> <mode> footprints in the manifest source scan vs declared footprint, single-writer-per-file, sprawl counters
Releases deterministic KIDS build spec → dist/VSL.kids lifecycle-healthcheck: install → verify → suites → uninstall → byte-clean baseline diff, both engines. Every mutation lands in a hash-chained attestation ledger.
Command surface v-registry.json — the v umbrella mounts registry golden test + plain-language lint (no VA product names in commands)
m-driver-sdk
typed verbs — Health · Load · Exec · ReadGlobal · SetGlobal — plus an executable conformance gate
m-ydb
local · Docker · SSH transports, plus mupip/dse/gde passthrough
YottaDB
m-iris
Atelier REST · Docker · local transports, plus routine sync/deploy
InterSystems IRIS
So no application "owns its own data" in the VistA sense. A VSL module declares which files it touches and how, exactly one module may write a given file, every mutating verb is audited with host attribution, and a patch that cannot prove byte-clean reversibility cannot become a release. Raw docker exec and direct-mode engine access are denied by tooling, not discouraged by docs.

The repos

Everything in the org.

The toolchain is in active development and most of it is still private while the seams and licensing settle. Linked names are public today; the rest are listed for shape and open as they land.

Available right now. The vista-iris container (docker pull ghcr.io/vista-forge/vista-iris:latest) — a fully installed VistA-on-IRIS with fictitious test data. The tree-sitter-m grammar — a real parser for M. And the twin editor extensions, vista-atlas and vista-compass.

M toolchain — engine-neutral

RepoDeliversLatest
m-cliCross-engine M toolchain — the m busybox (fmt/lint/lsp/test/coverage/watch/vista/arch)v0.1.0
m-stdlibPure-M runtime standard library — STD* modulesv0.13.0
m-driver-sdkM engine-driver SDK — the seam contract + reference engine Client (mdriver.Client)v0.11.0
m-ydbYottaDB engine driver — the m-ydb binary producing the driver envelope
m-irisInterSystems IRIS engine driver — the m-iris binary producing the driver envelopev0.1.0
m-parseEngine-neutral M parse substrate — tree-sitter-m over wazero; the foundation fmt/lint/lsp sit on (spec §4)v0.1.0
clikitShared CLI convention layer — Kong grammar, JSON envelope, exit-code ladder — for the m-* / v-* Go toolchain (engine-neutral; no engine transport)v0.9.0

VistA toolchain — requires Kernel / FileMan / KIDS

RepoDeliversLatest
v-pkgVistA KIDS packaging — the v pkg domain (build/install/verify/uninstall over the m engine seam)v0.7.0
v-cliThe v CLI umbrella — VistA developer tooling (v pkg/db/config/…) aggregated under one binary
v-stdlibVistA Standard Library — VSL* routines (VistA-specific; consumes the engine-neutral STD* base upward)v1.0.25
v-baseHost base library for v-<domain> CLIs — VSLAPI dispatch client (envelope codec, engine profiles, pagination, attribution/--yes) + the vslgen binding generator (vista-sysadmin-base §5)v0.4.0
v-dbVistA FileMan data-dictionary / PIKS profiler — the v db domain (read-only inspect/profile over the m engine seam via v-base)
v-webVistA Web Services — VWEB* routines: the inbound socket adapter (listener + device/TLS adapter) that drives the m-stdlib STDHTTPD server framework over a real socket
v-rpc-debugVistA RPC developer tools — the v rpc-debug domainv0.4.0
v-rpc-tapVistA scalable RPC tap — the v rpc-tap domain

The M standard & corpora

RepoDelivers
tree-sitter-mThe M grammar — generated from m-standard's data; parses the full VistA corpus at over 99% clean
m-standardThe M standard, machine-readable — the Annotated M Standard, YottaDB, IRIS, and VA SAC/XINDEX rules reconciled into one citable reference
m-modern-corpus~4,000 routines of modern open-source M (EWD, the YottaDB web server, mgsql, YDBOcto) as a second validation corpus

Editor extensions

RepoDelivers
vista-atlasVS Code extension over the vdocs gold-corpus release — what the VA documentation says. Twin of vista-compass.
vista-compassVS Code extension over the vista-meta data release — what the VistA system measurably is. Twin of vista-atlas.

Shared foundations & infrastructure

RepoDelivers
go-cli-templateScaffold for new Go CLIs in the house style (carries the canonical, drift-gated .golangci.yml)
docsADRs, design corpus, and cross-repo coordination
workspaceClone-all manifest + idempotent bootstrap.sh for machine setup
vista-irisPre-built VistA-on-IRIS container, fictitious test data only — the image is public; the build repo is not yet
.githubReusable CI, the docs standard, the org repo registry, and the scheduled meta-gate

Design principles

What the whole stack agrees on.

  • Git-canonical source. M code lives in .m files under version control; the database is the runtime, not the repository.
  • Dual-engine parity. YottaDB and IRIS are both first-class; the same suites gate both, and engine specifics live only inside the drivers.
  • One seam. Every tool reaches a live engine through the m-driver-sdk contract — no hand-rolled transports, verified by an executable conformance gate.
  • Gated, not aspirational. Layer boundaries, seam contracts, registries, build specs, and doc links are generated, drift-gated artifacts checked in CI — not conventions enforced by review.
  • Declared data ownership. A module states which VistA files it touches and how; a source scan red-gates undeclared access, and exactly one module may write a given file.
  • Reversible by proof. Engine mutations are audited into a hash-chained attestation ledger, installs capture pre-images, and a release tag can only be cut when a full install → uninstall cycle diffs byte-clean.
  • Static, dependency-free binaries. CGO_ENABLED=0 everywhere; even the M parser runs as WASM.
  • One contract, many surfaces. A single command grammar and reflected schema mean CLI flags, JSON envelopes, and agent tools never drift.
  • Test-first. Every module is built TDD with per-module coverage gates; conformance suites run against vendored RFC/NIST corpuses.
  • Plain nouns. A command wraps an insider VistA subsystem in a name a developer can guess — and a lint gate keeps it that way.