finos / finos/architecture-as-code

In-browser interactive learning lab: guided CALM lessons with no tool installation

Open
#2,879 4 comments 1 reaction 1 assignee Claimed by @rocketstack-matt View on GitHub
Roadmap Group: CALM Tools Roadmap: Now
Dominant language
TypeScript
Stars
399
Forks
138
Avg merge
2d 14h
Merged PRs (30d)
37

Description

## Feature Proposal

### Target Project:
`docs` (the Docusaurus site at calm.finos.org), with a follow-on dependency on `shared` (browser entry point).

### Description of Feature:
An interactive learning environment that runs **entirely in the browser session** — no CLI install, no server-side sandboxes. Learners work through step-by-step guided lessons in an IDE-style workspace (lesson rail, editor, terminal, live diagram) hosted on the static docs site.

The guiding principle is **real engine, simulated OS**: because the entire CALM toolchain core is TypeScript (Ajv validation, Spectral linting, Handlebars docify, Mermaid generation all live in `@finos/calm-shared`/`calm-models`/`calm-widgets`), the browser can run the *real* engine — only the shell, filesystem and network around it are simulated. Learners get real validator output, real schema errors, and real generated artefacts; lesson steps are verified against real state (e.g. "a successful `calm validate` ran", "the file contains a valid `orders-api` service node"), so any valid solution passes — nothing is scripted theatre.

**🔍 Working proof of concept:** https://calm-docs-redesign-phase5.vercel.app/learn/lab/ (branch `docs/redesign-5-lab` on rocketstack-matt's fork) — a complete 3-step lesson (inspect → add a node → connect it) with:
- a terminal whose `calm validate` runs all 11 real CALM 1.2 release schemas (imported directly from `calm/release/1.2/meta/`, so they can never drift from the repo) through Ajv, plus a CLI-style semantic check for dangling relationship references;
- a virtual filesystem persisted to localStorage;
- a docked full-viewport IDE layout with draggable splitters, editor/diagram tabs, terminal/problems tabs and a live status bar;
- a live diagram rendered with the **CALM Hub visualizer pipeline** — the Hub UI's transform/layout chain ported verbatim (with provenance headers) onto the same React Flow + dagre engine, so containers, actors, `interacts` and protocol-labelled edges render with the same shape as the hosted Hub (verified against the full TraderX architecture);
- zero new runtime dependencies beyond `ajv`/`ajv-formats`; the lab is a lazily-loaded `BrowserOnly` chunk so the docs bundle pays nothing until it's opened.

### User Stories:
- As a **newcomer**, I want to try CALM hands-on in one click, so I can learn the model before installing anything.
- As an **architect following the beginner tutorials**, I want a "try this step in the browser" companion to each tutorial, so I can practise without setting up Node and the CLI.
- As a **workshop facilitator**, I want attendees productive in minutes on locked-down corporate machines, where installing tooling is often impossible.
- As a **maintainer**, I want lesson success-checks that exercise the real validation engine, so lessons double as integration tests and can never teach behaviour that differs from the shipped CLI.

### Current Limitations:
- The tutorials assume a local install (Node 26, CLI, VS Code) before the first "aha" moment — a high barrier, and a hard blocker on restricted corporate machines.
- There is no way to try CALM at all without leaving the docs site.
- Server-side sandboxes could work but bring cost, cold starts, an abuse surface and an ops burden that a docs feature shouldn't carry.

### Proposed Implementation:
Three-layer architecture (all client-side, static-hostable):

1. **Workspace kernel** — virtual filesystem (in-memory, persisted to IndexedDB/localStorage; per-lesson seed snapshots; reset/export), a small purpose-built shell (`ls`, `cat`, `cd`, history, tab-completion) and one first-class binary: `calm`.
2. **Real-engine adapters** — the CLI's command surface bundled for the browser against the virtual FS. Requires a `browser` entry point in `shared` separating the engine from Node I/O (`fs`, `execa`, `playwright-core`, Winston transports) — a refactor that independently benefits Studio/Guard. Mermaid renders natively in the DOM (better than the CLI's Playwright rasterisation). Schema `$ref`s resolve from bundled release schemas. `calm hub` reads can target the FINOS-hosted read-only Hub (needs CORS on hub.calm.finos.org); writes are simulated by an MSW service worker so "publish" lessons work without a backend.
3. **Learning layer** — lessons as data (steps: instruction, seed files, success check, hints) colocated with the tutorials; checks assert real kernel state; progress in localStorage; per-tutorial "▶ Try it in your browser" chips injected via the existing doc-header chips mechanism; entry from the Learn hub.

Upgrade path from the POC's deliberate economies: xterm.js terminal, CodeMirror editor with CALM-schema autocomplete. The diagram already runs a ported copy of the Hub UI's visualizer pipeline — extracting that chain into a shared package (the org has three diagram implementations: Hub UI's React Flow view, Studio's `@calmstudio/diagram`, the VS Code preview, plus now the lab's port) would eliminate the copy and give all four one renderer.

**Dependencies on other components:** `shared` browser entry point (prerequisite for real docify/template/generate in the lab); CORS headers on hub.calm.finos.org for live Hub reads; optionally `calm-widgets` for docify output rendering.

### Alternatives Considered:
- **WebContainers (StackBlitz)** — genuinely boots Node/npm in-browser (learners even practise `npm i -g @finos/calm-cli`). Rejected as the foundation: cross-origin-isolation headers are awkward on GitHub Pages, there's a commercial-licensing question for a FINOS property, and boot latency is significant. Possible later "advanced mode".
- **Server-side sandbox environments** — rejected: cost, cold starts, abuse surface, ops burden; conflicts with the goal of running in the browser session.
- **Fully scripted/faked terminal** — rejected: only accepts the exact commands it expects and lies the moment a learner improvises; kept only as the unsupported-browser fallback message.

### Testing Strategy:
- The docs build (`onBrokenLinks: 'throw'`) plus SSR prerender guard the integration.
- Lesson success-checks run headlessly in CI against the browser bundle — every lesson becomes an integration test of the real engine (the POC already validated this pattern via Playwright: full lesson drive, negative path with a dangling relationship ref, layout invariants like "the page body never scrolls").
- Unit tests for the kernel (vfs, shell parsing) and engine adapter once the design is approved.

### Documentation Requirements:
- A short authoring guide for lesson files (step/check/hint format) so tutorial authors can add lab lessons alongside markdown tutorials.
- A note in the Learn hub / tutorials pointing at the lab as the no-install path.

### Implementation Checklist:
- [x] Design reviewed and approved (POC linked above)
- [x] Phase A — productionise the POC: lesson framework extracted from the hard-coded lesson, beginner tutorials 01–03 as lessons, per-tutorial chips
- [x] Phase B — `shared` browser entry point (#2880); real docify/template in the lab; beginner track complete
- [ ] Phase C — Hub lessons (reads against hub.calm.finos.org, MSW-simulated writes); intermediate lessons
- [ ] Phase D — editor/terminal upgrades (CodeMirror + schema autocomplete, xterm); shared diagram renderer
- [ ] Tests written and passing (lesson checks in CI)
- [ ] Documentation updated
- [ ] Performance impact assessed (lab is a lazy chunk; size budget enforced)

### Additional Context:
Screenshots of the POC (theme-invariant IDE chassis in light and dark site themes, accordion guide, Problems tab with real validator output):
- https://raw.githubusercontent.com/rocketstack-matt/architecture-as-code/assets/calm-docs-redesign/implementation/lab-chassis-light.png
- https://raw.githubusercontent.com/rocketstack-matt/architecture-as-code/assets/calm-docs-redesign/implementation/lab-chassis-dark.png
- https://raw.githubusercontent.com/rocketstack-matt/architecture-as-code/assets/calm-docs-redesign/implementation/lab-tabs-problems.png
- https://raw.githubusercontent.com/rocketstack-matt/architecture-as-code/assets/calm-docs-redesign/implementation/lab-hub-renderer-traderx.png (the full TraderX architecture rendered by the ported Hub pipeline)
- https://raw.githubusercontent.com/rocketstack-matt/architecture-as-code/assets/calm-docs-redesign/implementation/lab-chassis-mobile.png

Open questions (I would like input from the other maintainers here):
1. **Lesson placement** — lab lessons colocated with the tutorial markdown (one source of truth per tutorial) vs. a separate `lessons/` tree?
2. **Engine scope for v1** — validation-only (as the POC) vs. waiting for the `shared` browser refactor so docify/template ship in the first release?
3. **Diagram consolidation** — should the shared renderer extraction (Hub UI / Studio / VS Code / lab) be its own issue, with this feature as its first consumer?

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.