- TypeScript 80.1%
- JavaScript 11.5%
- Svelte 3%
- CSS 2.9%
- Vue 1.6%
- Other 0.9%
| .forgejo/workflows | ||
| apps/elfa-tables | ||
| bin | ||
| docs | ||
| experimental | ||
| fixtures/atomic-issue-tracker | ||
| lib | ||
| patches | ||
| scripts | ||
| shared | ||
| tests | ||
| vendor-packages | ||
| .gitignore | ||
| .gitmodules | ||
| AGENTS.md | ||
| astro.config.ts | ||
| CLAUDE.md | ||
| HANDOFF.md | ||
| LICENSE-APACHE2 | ||
| LICENSE-MIT | ||
| package.json | ||
| playwright.atomic-server.config.ts | ||
| playwright.config.ts | ||
| playwright.conflicts.config.ts | ||
| playwright.lenses.config.ts | ||
| playwright.native.config.ts | ||
| playwright.orm-query.config.ts | ||
| playwright.orm-tables.config.ts | ||
| playwright.port.config.ts | ||
| playwright.runtime.config.ts | ||
| playwright.scaling.config.ts | ||
| playwright.subscriptions.config.ts | ||
| playwright.templates.config.ts | ||
| playwright.windows.config.ts | ||
| pnpm-lock.yaml | ||
| pnpm-workspace.yaml | ||
| README.md | ||
| svelte.config.js | ||
| tsconfig.atomic.json | ||
| tsconfig.base.json | ||
| tsconfig.delivery.json | ||
| tsconfig.issues.json | ||
| tsconfig.joep.json | ||
| tsconfig.json | ||
| tsconfig.lenses.json | ||
| tsconfig.orm-query.json | ||
| tsconfig.port.json | ||
| tsconfig.runtime.json | ||
| tsconfig.shopping-list.json | ||
| vitest.config.ts | ||
ELFA Database Apps
Three NextGraph applications are the delivery direction for WP6:
| Application | Purpose | Folder |
|---|---|---|
| ELFA Tables | Create tables from templates and work with records in grid, card and calendar views. | apps/elfa-tables/ |
| ELFA Forms | Build forms over table schemas and collect responses into the same records. | apps/elfa-forms/ |
| ELFA Project | Plan work with issue lists and Kanban boards over those records. | apps/elfa-project/ |
These folders are introduced in separate draft PRs after this preparatory
change. They describe the implementation direction, not completed WP6 delivery.
The apps use NextGraph's RDF engine and native ORM subscriptions; shared
infrastructure remains under shared/.
Current priority: ELFA Tables first; ELFA Forms is postponed unless needed. See the roadmap and decision record for sequencing, the owner-only Forms demo workaround and the conditions for resuming Forms.
Repository layout and runner
apps/: the three delivery apps, each with its own entry point, implementation, documentation and tests. App-local manifests register them with the runner.experimental/: the existing twelve exploratory apps, retained as working examples and sources of reusable code. Their CLI names are unchanged.shared/: common schemas, table components and NextGraph session code.docs/: implementation notes, validation boundaries and walkthroughs.
db-app-runner starts one selected frontend. On a branch containing the delivery
apps, use pnpm db-app-runner elfa-tables, elfa-forms or elfa-project.
Use pnpm db-app-runner --list to see the apps available on your checkout.
The experimental collection includes five expense trackers (expenses-vue,
expenses-react, expenses-svelte, expenses-svelte4, expenses-solid-js),
shopping-list-react, the native and Atomic table editors, Joep's grid,
template tables, an issue tracker and a lenses manager. Moving these folders
keeps their behavior and launch commands intact.
The Atomic grid port experiment
adds pnpm db-app-runner db-table-editor-port: upstream grid/typed-editor UI
backed by bounded native NextGraph ORM queries and draft-aware writes. This is the
staged TablePage port investigation (#77), with native saved views, history
navigation and schema/draft checks in its own WASM suite. Broker-backed
restart/collaboration and broader table-feature parity remain follow-up work.
The grid/primitive editors come from the upstream @tomic/table workspace
package, installed through a pinned Git submodule
until its first registry release.
Read the October 2026 results and two demos for the Atomic schema and reusable table UI experiments. The setup, native wallet, synchronization and validation instructions below remain applicable.
WP6 tasks, deliverables and schedule
WP6, ELFA Database Apps, runs from project month 1 through month 24 and is
led by Atomic/Ontola (beneficiary 6). The project starts on 1 June 2026.
Task numbers (T6.x) identify work to perform; deliverable numbers (D6.x)
identify outputs to submit. Matching numbers do not establish a one-to-one
relationship between a task and a deliverable.
Working task sequence and unchanged deliverable deadlines
The implementation sequence puts T6.2 before T6.1, with the following planning windows at 1 FTE. These windows allocate six and four person-months respectively; they do not move the contractual deliverable deadlines.
| Item | Planning window or deadline | Meaning |
|---|---|---|
| T6.2 — Templates, table and form improvements | Months 1–6: June–November 2026 | Six person-months at 1 FTE. November is the task-completion planning target. |
| T6.1 — Webhooks & View persistence | Months 7–10: December 2026–March 2027 | Four person-months at 1 FTE. |
| D6.1 — Templates, webhooks | Month 12: May 2027, unchanged | Public deliverable, also including view persistence and forms logic. |
| D6.2 — Database GUIs | Month 24: May 2028, unchanged | Public deliverable covering forms, calendar, card and Kanban GUIs. |
These implementation windows leave the deliverable contents and deadlines unchanged. November 2026 is the T6.2 planning target; D6.2 remains due in month 24.
T6.2 — Templates, table and form improvements
Atomic/Ontola allocates 6 person-months to implement:
- Table templates: provide a predefined list of example tables that users can fork.
- Table multi-filter/sort: more powerful query options, including numeric range filters and sorting by multiple values. The grant explicitly anticipates substantial backend refactoring and changes to indexing logic.
- Form field logic: conditional questions.
- Submission presentation: one question per screen.
- Multiple-choice alternatives: an “other” option with free-text input.
- Edit my submission: allow a respondent to change an already-submitted response.
- Submission notifications: email the form owner when a new response arrives; coordinate with Trey's T9.1.
- Form styling: user-entered CSS themes.
- Anonymous submissions: allow them when the form owner permits them.
T6.1 — Webhooks & View persistence
Atomic/Ontola allocates 4 person-months to implement:
- Incoming webhooks: expose webhook functionality over http to manipulate ELFA databases, following the ActivityPods design.
- Outgoing webhooks: client-side create, read, update and delete (CRUD) operations trigger calls to an external webhook.
- View persistence: persist and share the sorting and filtering options a user selects while viewing data.
Incoming webhooks follow the ActivityPods design. There will be no optional AtomicServer service.
D6.1 — Templates, webhooks
- Lead: beneficiary 6, Atomic/Ontola.
- Due: project month 12, May 2027.
- Type: OTHER; dissemination: PU — Public.
- Grant description: templates and webhooks, plus view persistence and forms logic.
T6.1 and T6.2 contain the work corresponding to these areas. Their scopes are broader than the short deliverable description: retain the complete task lists above when planning implementation, rather than treating the deliverable title as an exhaustive feature list.
D6.2 — Database GUIs
- Lead: beneficiary 6, Atomic/Ontola.
- Due: project month 24, May 2028.
- Type: OTHER; dissemination: PU — Public.
- Grant description: Forms, Cal, Card, Kanban — forms, calendar, card and Kanban GUIs.
The detailed GUI work is described in T6.3–T6.5 below. T6.2 also contributes form and table improvements; these related workflows do not imply that D6.2 is due at the end of T6.2's planning window.
Supporting GUI tasks: T6.3–T6.5
These tasks explain the detailed work behind the database GUIs. The T6.1/T6.2 planning clarification above does not assign new dates to them.
T6.3 — UX/UI design. WP6 refers to the T5.5 design description: Ura assists the implementation team and produces UX/UI designs in coordination with it, following T2.2 Product Design and T3.2 Common UX/UI. Designs must maintain a consistent, unified look and feel for new and refactored applications while accommodating decentralized and local-first behavior. The referenced design description allocates 2 Ura person-months. The grant's WP6 design milestone is milestone 7, “UX/UI Design for Database Apps”, led by Ura and due in month 19; its verification is delivery of the UI design to the WP lead.
T6.4 — Forms GUI foundation. Atomic/Ontola allocates 6 person-months. This task depends on T6.3 and includes:
- A form builder for creating forms and defining input field names, descriptions and ordering.
- Field controls, including radio versus dropdown and toggle versus checkbox.
- Grouping, flow settings, success screens, branding and themes.
- A form-submission wizard, success page, redirects, branding and themes.
T6.5 — Other views, comments. Atomic/Ontola allocates 6 person-months. This task depends on T6.3 and includes:
- Calendar view, coordinated with Trey's T9.6.
- Card view.
- Kanban view, grouping resources into columns by a selected field.
- Comments: show and post comments on resources and Kanban issues.
- UI improvements and alignment with ELFA design.
- Kanban and task views for the ELFA Project mini-app.
- Property migration: migrate existing values when changing a column's datatype, for example from string to date.
Overall WP6 output and implementation boundary
WP6's objective is ELFA Tables, ELFA Forms and ELFA Project, based on NextGraph. They must work standalone or embedded in the ELFA Suite, without requiring AtomicServer. Existing Atomic frontend code may be reused and extracted into reusable components. The scope includes powerful data views, flexible forms, webhook support and real-time collaboration.
The amended implementation scope does not include an optional AtomicServer service. Incoming webhooks expose HTTP endpoints following the ActivityPods design; they do not require an AtomicServer deployment.
For the ELFA implementation, use the direct NextGraph ORM data path: useShape
for records and useDiscrete for schemas/metadata, following the architecture
reviewed during October. The scope lists here describe commitments, not claims
that every feature is implemented or accepted. Track implementation and
validation evidence separately.
Sources: Grant Agreement GAP-101298715, Annex 1 Part A, WP6 and the referenced T5.5 description (printed pp. 10–11), deliverables D6.1/D6.2 (printed pp. 30–31), and milestone 7 (printed p. 37). The implementation windows for T6.2 and T6.1 are Michiel's planning clarification of 28 October 2026, not revised grant deliverable deadlines. Direct NextGraph storage follows the consortium architecture guidance and the October implementation review. The webhook architecture and exclusion of an optional AtomicServer service follow the amendment clarification.
Lenses
pnpm db-app-runner lenses-react
Manage content-addressed Atomic property mappings, preview transformations, and save collection bridges and durable record correspondences in NextGraph. Export Atomic Lens JSON-AD or a complete configuration bundle. The app manages configuration; a collection synchronization daemon is a later step. See Lenses app behavior and validation.
The 20 October review runbook defines the current narrow
demo, Atomic compatibility boundary and fix window. In the Atomic runner,
/atomic-reuse runs the same React table against Atomic Server v0.41.0-beta.8,
with persisted schemas and rows, native signed commits, and server permissions.
It does not load NextGraph. See server setup, walkthrough and tests.
The earlier in-memory example is retained at /atomic-reuse-memory for fixture
tests and the original guided rehearsal.
For a guided walkthrough, run pnpm rehearse:table after installing dependencies,
Chromium and the pinned broker. It opens two disposable replicas, prints presenter
instructions and checks each step as you press Enter. See the runbook for setup
and the unattended --auto --headless option.
Alice and Peer stay in two labelled tabs; wallet setup and automatic transitions
pause for Enter, and you control which tab is visible.
Run an app
Requirements: Node.js >= 22.18 and pnpm 12.5.1
(the version required by package.json and used in CI).
Run these commands from the repository root:
pnpm setup:table # initialize submodule and build @tomic/table
pnpm install
pnpm db-app-runner --list
pnpm setup:broker # first time: requires Rust and a C++ toolchain
pnpm broker # keep running in a separate terminal
pnpm exec playwright install chromium # needed for --sync-node profiles
Quick testing with Alice and Bob
With the broker running, create disposable wallets from the command line:
pnpm setup:test-wallets
# In separate terminals:
pnpm db-app-runner db-table-editor-atomic --sync-node alice
pnpm db-app-runner db-table-editor-native --sync-node bob
The setup command generates and registers two real wallets locally and prints
their encrypted file paths. Import alice.ngw into Alice's runner and unlock it
with alice-test-only; import bob.ngw into Bob's runner and use bob-test-only.
You do not need to choose a password or generate a key manually for this
testing path. These public passwords are only for disposable sample data.
Rerunning the setup command reuses its wallet files; --out /path/to/directory
selects another output directory. The default is
~/.local/share/db-app-runner/test-wallets (or under $XDG_DATA_HOME).
Use the same local broker for setup and both runners. Alice and Bob have distinct
identities and separate private stores. To compare the native and Atomic views
of the same data, import Alice's file into both profiles instead. Sharing a
document between different identities requires native NextGraph authorization.
Your own wallet
pnpm db-app-runner expenses-react --open
For your own identity, create or import a wallet directly on the local page and
choose your own password. The default address is http://localhost:5183.
The password stays in the browser, the encrypted wallet is
saved in IndexedDB, and the native WASM verifier runs in that browser. There is
no hosted login or iframe and no dependency on nextgraph.eu or nextgraph.net.
Export the encrypted wallet file for backup or import it into another runner.
pnpm setup:broker builds a pinned ngd into the runner's data directory. On
macOS, install Apple's Command Line Tools; on Linux, install a C++ compiler,
libclang and OpenSSL development headers. Use NGD_BIN=/path/to/ngd pnpm broker
if you already have a compatible binary. The broker listens only on loopback
port 14400 and allows local demo-wallet registration. Complete the first wallet
setup before creating another wallet. Its one-time broker invitation is handled
locally. --broker http://127.0.0.1:<port> selects another local broker.
To make the executable available as db-app-runner, use npm link in this
checkout. You can also run ./bin/db-app-runner.mjs expenses-react directly.
db-app-runner expenses-vue --port 5185
db-app-runner expenses-solid-js --build
db-app-runner expenses-solid-js --preview --port 5186
--build builds only the selected app into dist/<app>/. pnpm build builds
all twelve separately. Use --help for the full option list.
First database app: expense tracker
So far, each app can:
- Create expenses and categories; edit titles, descriptions, item quantities, euro totals, category links, and payment status.
- Filter by status or category, sort by purchase date, quantity, or price, and paginate in groups of 5, 10, or 15.
- Edit the same records through the shared table editor below the selected app, including purchase dates and recurring-expense fields.
- Expand Show RDF details to inspect full graph/subject identifiers and predicates for the ORM's shape projection.
Local wallet-free test screenshot with sample data. Quantity is the number of items; Total is the expense price in euros.
Without --graph, the app uses the authenticated user's private store. There is
no Yjs wrapper, simulated replica, or online/offline switch. Writes and graph
subscriptions go directly through the native NextGraph session.
Shopping list
pnpm db-app-runner shopping-list-react
The React shopping list uses the same local wallet and graph selection as the expense demos. Type in the empty row and press Enter or leave the field to add an item. Edit item text directly, remove it with the minus button, and drag its handle up or down to reorder it. A focused handle also supports Arrow Up and Arrow Down. There are no categories or expense table in this app.
Each ShoppingListItem is an RDF subject with title and hidden variable-length
string position keys. The position-strings generator creates a unique key
between destination neighbors, and a drag updates only the moved item's position.
Keys and subject IDs use fixed code-unit ordering, independent of browser locale.
The stored keys are absolute sort keys; there are no RDF linked-list or
"after item X" relationships.
The canonical shape allows one or more string positions so concurrent moves cannot invalidate an item just by exceeding the position cardinality. When multiple positions survive an RDF merge, the UI uses the greatest key: the rightmost concurrent placement wins. A subsequent move replaces every placement that client has observed with a fresh key. This is a deterministic conflict policy, not physical-time last-writer-wins or a promise to preserve all conflicting intentions.
A compatibility projection reads old integer positions and upgrades them in place, retaining subject IDs and titles. An integer-only list keeps its numeric order. In mixed data, string-ranked items come first and remaining legacy items are appended in numeric order during upgrade. Upgrade all clients: old clients that keep writing integers do not implement this policy. Competing upgrades can leave alternative string keys, resolved by the same greatest-key rule. The position property is an ORM Set, normally containing one key.
See ordering implementation and limits.
Create tables from templates
pnpm db-app-runner db-table-editor-templates
Choose Create from template to create tables from all fourteen Atomic Server starting points. The native table editor handles record editing, search and sorting; table schemas and records reopen from NextGraph after reload.
This draft experiments with content-addressed semantic definitions for Properties, Classes, Tags and Ontologies. Normative meaning, types and class constraints are hashed; drive identities, table names and presentation are not. Tables from the same template share definition IDs and keep their records separate. These are experimental definitions, not official Atomic Server schemas. See the identity format, generation, supported features and verification.
Native and Atomic table editors
pnpm db-app-runner db-table-editor-native --sync-node native
pnpm db-app-runner db-table-editor-atomic --sync-node atomic
Both editors share the native table UI and ORM editing path: Expenses and
Categories tabs, exact-value filtering, sorting, inline row controls, immediate
validated writes, and Show RDF details. The runtime grids and ELFA Tables
editable grid use the ORM’s where, orderBy and page navigation APIs, retaining
at most 100 records and rendering the viewport. Filters match the primary field
exactly, including case; they do not perform substring search. Drafts survive
page and tab changes in the runtime grids. See ORM query behavior and historical
scaling measurements.
The title and engine badge identify the editor.
The Atomic editor bundles a checked-in
Atomic JSON-AD schema generated
from the native expense and category ORM snapshots. pnpm build:atomic
regenerates it. At startup, the existing runtime converter calls defineShape
to reconstruct the native NG ORM shapes. Metadata retains the Atomic datatypes,
validation rules and content-addressed property identities that compact ORM
shapes do not contain. A round-trip check rejects lossy reverse conversions.
Both editors retain schema editing and verified useDiscrete revisions. The
checked-in schema is the baseline; an activated saved revision takes precedence.
The Atomic editor creates or finds a YMap / data:map document and persists
the initial schema there. Its RDF records and schema revisions share the same
document NURI. Schema edits keep earlier revisions and activate verified contents.
The Atomic editor's record writes no longer use an Atomic Resource adapter.
To compare the same records in another expense app, import the same encrypted
wallet and pass the Atomic editor's displayed document NURI with --graph.
Existing private-store records stay in their original graph. An explicitly
selected document must have an object-root discrete part; graph-only documents
fail visibly instead of creating a detached schema document.
Separate wallets have separate stores. Neither requires an Atomic Server.
See schema generation and runtime conversion.
Joep’s NextGraph table editor
pnpm db-app-runner db-table-editor-joep --sync-node alice
This additional app imports Joep’s table editor
from commit 605d9193e20454e7947af54c1686eaffbf73862d.
It keeps the upstream task demo: title, description, done, priority, due date,
and status (Todo, InProgress, Blocked, Done). It uses the same local wallet,
broker and --graph selection as the other apps. Import Alice’s existing wallet
to use her identity; tasks and expenses are different RDF shapes and records.
Stop a running Alice instance before starting another app with that profile.
The spreadsheet grid comes from Atomic Server’s frontend, but reads and writes
through NextGraph useShape directly, without @tomic/lib or @tomic/react.
Select a cell and press Enter to edit, Escape to leave, or type into the last
blank row to create a task. Arrow keys navigate, Delete clears selected cells,
and selecting a row number then pressing Delete removes that task. Columns can
be resized, and selections can be copied or pasted as HTML table cells.
The shape builder derives columns at runtime from the task schema. Open Edit schema to add/remove columns, rename predicates, and change types or required fields. The saved schema follows the selected NextGraph graph and survives reloads. The editor does not provide an Atomic Server resource browser, permissions management, or undo history. See upstream provenance and integration details.
Local wallet-free test screenshot. Real wallet persistence is verified separately.
Two runners on one laptop
pnpm exec playwright install chromium
# In separate terminals:
db-app-runner expenses-react --sync-node alice
db-app-runner expenses-vue --sync-node bob
--sync-node opens a separate persistent Chromium profile for that named runner
and assigns a local port on first use. Both the profile and address are reused
on restart so IndexedDB retains the same wallet. It isolates each native verifier
and wallet. Restarting the same name reuses its profile; do not
run the same name twice simultaneously. Profiles are stored at
$XDG_DATA_HOME/db-app-runner/nodes/<name>/browser, or
~/.local/share/db-app-runner/nodes/<name>/browser when XDG_DATA_HOME is unset.
A profile name is not a NextGraph user ID. Create/import and authenticate a wallet in each profile on its local page. Importing the same wallet gives two instances of the same user; separate wallets give separate users. The runner shows the actual NextGraph user ID. The local broker carries encrypted native NextGraph synchronization traffic.
Separate users initially have separate private stores. To edit together, give both users native NextGraph access to the same RDF document and pass its graph NURI to both runners:
db-app-runner expenses-react --sync-node alice --graph 'did:ng:o:<document-id>'
db-app-runner expenses-vue --sync-node bob --graph 'did:ng:o:<document-id>'
Replace <document-id> with the real 44-character document identifier. This
selects the graph for every expense/category subscription and insert; it does
not grant access to another user's private store. Cross-user synchronization
still needs a shared authorized document. Native synchronization has been tested
between independent browser verifiers using the same imported wallet, including
wallet persistence and graph recovery after restart. Separate-wallet identities
were also verified to have separate private stores. The app shows the runner
name, user ID and document; it does not yet display per-edit author attribution.
See local sync setup and native RDF conflict behaviour.
Development and tests
pnpm build:shapes # optional snapshots: Atomic JSON-AD -> NextGraph + Atomic bindings
pnpm exec tsc -p tsconfig.atomic.json # check the Atomic integration
pnpm test # unit tests
pnpm exec playwright install chromium
pnpm test:e2e # each frontend, including runtime schema edits
pnpm test:runtime # the three schema-editable table editors
pnpm build # production builds of all registered apps
pnpm test:native # real wallets + sync; starts a disposable broker on port 14400
NextGraph browser tests cover frontend/table edits, filters, pagination, selected graph
routing, and persistent profile isolation. They use the real ORM and framework
adapters with a local in-memory protocol fixture. The fixture does not verify
native encryption, persistence, permissions, network synchronization, or RDF CRDT
conflicts.
NG_E2E=1 is restricted to local test servers and rejected in builds.
Stop a running pnpm broker before pnpm test:native, which starts its own
isolated broker on the same port. The native test uses the real WASM
wallet/verifier and local ngd to check
creation, distinct identities, export/import, native sync, incorrect-password
rejection, persistence across restarts, and edits between the native demo and
both table editors. It blocks external HTTP traffic and
checks that WebSocket connections stay on localhost. The Forgejo workflow runs
both suites and builds on pull requests and pushes to main.
This repository was copied from
ELFA/nextgraph's expense-tracker-rdf example,
and uses published @ng-org/orm, @ng-org/lib-wasm, and @ng-org/shex-orm packages.
The authored expense schema is Atomic JSON-AD.
db-app-runner <app> --build regenerates the shared schemas before compiling.
See the schema conversion profile and
the Schema constraints and implemented Atomic Data mapping.
For the planned authored data evolution experiment, see the intent-sourcing plan and agent handoff. It records the design and next milestones; intent sourcing is not yet implemented.
Atomic issue tracker
Run pnpm db-app-runner db-table-editor-issue-tracker for the tenth CLI app.
It uses the existing local wallet and native NextGraph graph, with Issue, Tag,
status-cell and priority-cell shapes constructed at runtime from
Atomic JSON-AD metadata.
Create, edit, delete, search, close/reopen and use the status board. Ordered RDF
lists preserve multiple status/priority selections; the app explicitly checks
cycles, enum membership and missing tails. See the
app and validation boundaries.
JSON-AD to NextGraph
The offline converter reads a complete Atomic export with Class/Property definitions and writes an ORM schema, validation rules, typed JSON-LD and provenance mappings without a ShEx intermediate. The sample Atomic issue export contains three issues and seven tags. Array order, duplicates and empty arrays become explicit RDF lists; permissions, document creation and broker import are separate operations.
The generic editor companion specification defines a future stricter profile: NURI identifiers, at most one object per subject–predicate pair, no language tags, one graph-wide predicate type and one runner graph. The converter currently emits general RDF, retaining standard vocabulary/datatype IRIs and potentially multiple classes. It does not yet meet that strict profile. Use the living PRD for current product direction.
pnpm test:conflicts characterizes actual concurrent offline quantity edits
through two engines and a disposable broker. See the
conflict experiment and its limits.
License
Licensed under either Apache-2.0 or MIT, at your
option. SPDX-License-Identifier: Apache-2.0 OR MIT
All apps construct their ORM shapes at runtime through the shared defineShape
builder. Table columns and controls derive from runtime metadata; generated
schema snapshots are compatibility artifacts and are not required to start or
build an app. Handwritten expense cards retain their domain TypeScript contracts.
Editable schema definitions are persisted through NextGraph useDiscrete in a
JSON CRDT document. RDF retains only the document pointer and active schema
revision; useMemo derives the ORM schema. Existing RDF-stored schema definitions
move to discrete storage when next saved. See runtime schemas.
App layout
Existing exploratory apps live under experimental/ and retain their CLI names.
Delivery apps live under apps/; each supplies an app.json title, pages and app-local tests.
The runner discovers these manifests automatically. Shared renderer dependencies and
CI discovery are prepared centrally so each delivery app can be reviewed in its own folder.
