Skip to content

Commit 7f3dab6

Browse files
authored
feat(ui): run Nondominium as a Moss tool in weave dev mode (#180)
Adds weave/ (dev config with two agents and one group, kept outside the root workspaces so CI never installs Electron), bun run tool-dev, @theweave/api in ui/, and ui/src/lib/moss/: host detection, the Moss connection mode and an empty AppletServices. The standalone connection modes are unchanged. Documents the Moss integration in documentation/specifications/moss-integration.md.
1 parent 2a2d4d2 commit 7f3dab6

27 files changed

Lines changed: 1355 additions & 9 deletions

‎CHANGELOG.md‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ NDO over a live DHT.
2222

2323
### Added
2424

25+
- **Moss tool scaffold.** Nondominium runs as a Moss tool in `weave` dev mode: a dev config
26+
with two agents and one group (`bun run tool-dev`), `@theweave/api` in the UI, and a
27+
connection mode that takes the conductor client from Moss. The standalone build is
28+
unchanged. See `documentation/specifications/moss-integration.md`.
2529
- **Lobby DNA** as the entry point. Groups are announced here for discovery, and NDOs are
2630
browsed and filtered across every group the agent belongs to.
2731
- **Group DNA, one cloned cell per group.** Each group is its own DHT with its own

‎bun.lock‎

Lines changed: 132 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎documentation/DOCUMENTATION_INDEX.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,7 @@ nondominium implements a **Governance-as-Operator** architecture that separates
149149
| **[Private Participation Receipts](specifications/governance/private-participation-receipt.md)** | PPR system full specification | ✅ Complete |
150150
| **[Governance Model (Legacy)](specifications/governance/governance.md)** | Legacy governance model and decision-making processes | 📦 Reference |
151151
| **[UI Architecture](specifications/ui_architecture.md)** | Frontend design patterns & component structure | ✅ Complete |
152+
| **[Moss Integration](specifications/moss-integration.md)** | Running Nondominium as a Moss tool (v0.1.0 pilot): dev config, host seam, what Moss does to our roles | 🔄 In progress (#163 to #165) |
152153
| **[ValueFlows Action Usage](specifications/VfAction_Usage.md)** | ValueFlows implementation with governance examples | ✅ Complete |
153154
| **[Protocol Bridge Specifications](specifications/protocol-bridge-specifications.md)** | Bun Protocol Bridge architecture for platform integration (Tiki, Odoo) | ✅ Complete |
154155
| **[API Reference](API_REFERENCE.md)** | Complete function reference across all zomes | ✅ Complete |

‎documentation/IMPLEMENTATION_STATUS.md‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,18 @@ There is no `get_all_groups` extern in a Group cell; each cell represents one is
291291

292292
---
293293

294+
## Moss Tool 🔄 In progress (v0.1.0 pilot, #163 to #165)
295+
296+
Nondominium runs as a Moss tool in `weave` dev mode. Standalone (Lobby, Group DNA, invite codes) is unchanged.
297+
298+
- ✅ **Scaffold (#163).** `weave/weave.dev.config.ts` (two agents, one group, tool served from `localhost:8888`), `bun run tool-dev`, `@theweave/api` in `ui/`, host detection and the Moss connection mode in `ui/src/lib/moss/`, an empty `AppletServices`. The UI connects through the applet client Moss hands it.
299+
- ❌ **Moss group context (#164).** Profiles from Moss, roles from `myAccountabilitiesPerGroup()`, the instance's `group` cell as the Nondominium group, NDO clones through the `WeaveClient`. Not yet implemented: inside Moss the Lobby and invite-code flows are not adapted.
300+
- ❌ **NDOs as assets (#165).** WAL, `getAssetInfo`, `search`, asset view.
301+
302+
See [moss-integration.md](specifications/moss-integration.md).
303+
304+
---
305+
294306
## NDO Federation Extensions ✅ Implemented (PR #103)
295307

296308
The governance zome includes three additional public entry families:

‎documentation/SUMMARY.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
- [NDO v1 Architecture Design](specifications/ndo-v1-architecture-design.md)
4444
- [Architecture Components](ARCHITECTURE_COMPONENTS.md)
4545
- [UI Architecture](specifications/ui_architecture.md)
46+
- [Moss Integration](specifications/moss-integration.md)
4647
- [VfAction Usage](specifications/VfAction_Usage.md)
4748
- [Protocol Bridge Specifications](specifications/protocol-bridge-specifications.md)
4849
- [API Reference](API_REFERENCE.md)

‎documentation/specifications/lobby-architecture.md‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -802,6 +802,8 @@ NdoView.svelte
802802

803803
> **Superseded in part (2026-11-03).** The feature map below assumes Moss replaces the Group DNA and the Lobby. The Group DNA now stays in both modes, and in Moss there is one Nondominium group per Moss group, the group cell of the tool instance, joined automatically. Read the group rows of the table through ADR-014 (`adr/ADR-014-work-contexts-in-group-dht.md`) and REQ-GROUP-19 to REQ-GROUP-23 in `../requirements/lobby-dna.md`.
804804
805+
> **Partly superseded (v0.1.0 Moss pilot).** [moss-integration.md](moss-integration.md) is authoritative. Differences from the table and the sketch below: there is no Nondominium Lobby Tool DHT in Moss (every tool instance in every Moss group is its own network, so the Lobby DNA's global seed does not survive as an inter-group lobby), the Moss group is the federation layer, the instance's provisioned `group` cell is the one Nondominium group of that Moss group, and `AppletServices` in `@theweave/api` `0.7.0-rc.3` has `search`, `getAssetInfo` and `creatables` only (opening an asset is a render view, not a method). The entry-point sketch below calls `get_all_ndo_descriptors` on `lobby`, which does not exist; NDOs come from the group cell's `NdoAnchor` entries.
806+
805807
When deployed inside Moss, Nondominium appears as **one Tool applet**. Moss handles: group
806808
invites, agent identity at the surface, and the app sidebar. Nondominium owns its internal
807809
complexity (Group DHTs, NDO DHTs, hard links, smart agreements).
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Moss Integration
2+
3+
**Status:** v0.1.0 pilot, in progress. The tool scaffold and dev config are implemented (#163). The Moss group context (#164) and NDOs as assets (#165) follow. Supersedes the "Moss Integration Contract" in [lobby-architecture.md](lobby-architecture.md) §9 where they differ.
4+
5+
Moss is the Weave host (lightningrodlabs/moss). In the v0.1.0 pilot Nondominium runs as a **tool** inside Moss, started with the `weave` CLI in dev mode. The standalone build (Lobby DNA, Group DNA, invite codes) keeps compiling and running unchanged; the pilot ships Moss only.
6+
7+
## Decisions
8+
9+
- The pilot runs `@theweave/cli` in dev mode with a shared dev config and our own bootstrap and relay. Not the Moss app, not a curation list.
10+
- Inside Moss the Moss group is the federation layer. There is one Nondominium group per Moss group: the tool instance's `group` cell.
11+
- Each NDO is a clone cell of the `ndo` role. Profiles come from Moss, roles from `myAccountabilitiesPerGroup()`, NDOs are exposed as Moss assets.
12+
- v0.1.0 ships no work context.
13+
14+
## Running the tool in dev mode
15+
16+
Moss is built on Holochain 0.7.1 only in its `0.16` release candidates. The pilot uses `@theweave/cli` `0.16.0-rc.5`, which downloads a patched Holochain `0.7.1-mdns.8` that cannot see stock Holochain peers.
17+
18+
```bash
19+
bun run build:happ # inside nix develop, produces workdir/nondominium.happ
20+
bun run moss:install # installs weave/ (Electron and the weave CLI), once
21+
bun run tool-dev # Vite on :8888 plus two Moss windows, Alice and Bob
22+
bun run tool-dev-1 # the same with Alice only
23+
```
24+
25+
`weave/` is a separate package outside the root workspaces so that CI and the standalone build never install Electron. `weave/weave.dev.config.ts` defines one group, `Nondominium Pilot`, created by agent 1 and joined by agent 2, with the tool served from `localhost:8888` and the `.happ` from `workdir/`.
26+
27+
Click the group in the Moss sidebar, then the Nondominium tool.
28+
29+
**Two machines.** Every `weave` call must pass the same `--bootstrap-url` and `--relay-url` of a server both machines reach (`kitsune2-bootstrap-srv` serves the relay on `/relay`), and the same CLI version. The group `networkSeed` in the shared config is what puts both agents in the same group.
30+
31+
### Gotchas
32+
33+
- `weave` loads the config through `ts-node` inside Electron. It needs TypeScript 5.x (TypeScript 7 has no JS API and the CLI crashes), `tslib` (not declared by the CLI) and a tsconfig with `"module": "commonjs"`. `weave/package.json` and `weave/tsconfig.json` carry all three.
34+
- A tool served from localhost must call `initializeHotReload()` before `WeaveClient.connect()`, or `connect()` waits forever. `ui/src/lib/moss/connect.ts` does it when `detectHost` sees the dev-mode iframe.
35+
- The group icon is limited to about 200 KB. `ui/static/icon.png` is a 128 px version of the logo.
36+
- `weave` opens an Electron window per agent. On a shared desktop, a nested X server keeps them contained: `Xephyr :99 -screen 1500x950 &` then `DISPLAY=:99 bun run tool-dev`.
37+
38+
## What the Moss manifest does to our roles
39+
40+
Verified in the #162 spike (see [issue #162](https://github.com/Sensorica/nondominium/issues/162)). Moss installs `workdir/happ.yaml` unchanged, deferred roles included, but it installs `group` and `ndo` as **provisioned** cells next to `lobby`, `nondominium` and `hrea`. So every tool instance already has its own `group` cell, which is the instance's group DHT and the one Nondominium group of that Moss group, and an unused `ndo` cell. NDO clones come on top. Clone limits of 64 and 512 were not refused.
41+
42+
## The UI seam
43+
44+
```
45+
hc-connect.ts connectHolochainClient()
46+
detectCurrentHost() moss/host.ts standalone, or Moss (with or without hot reload)
47+
connectMoss() moss/connect.ts WeaveClient.connect + applet client
48+
standalone modes launcher, manifest, env (unchanged)
49+
```
50+
51+
- `moss/host.ts` decides from the page itself: the `applet://` protocol or an injected `__WEAVE_API__` is a packaged tool; a dev-build iframe carrying Moss's iframe-kind hash is a tool in dev mode; anything else is standalone. The standalone path is not touched when the host is not Moss.
52+
- `moss/connect.ts` runs hot reload when needed, connects the `WeaveClient` with our `AppletServices`, and returns the applet client Moss hands the tool, the group hash and the applet hash. Inside Moss the client signs through Moss, so none of the standalone signing-credential code runs.
53+
- `moss/applet-services.ts` is the `AppletServices` object. In #163 it declares no creatables and no assets; #165 fills `search` and `getAssetInfo`.
54+
- The connection result carries `moss` so later slices reach the `WeaveClient` through the client service (`holochainClient.moss`).
55+
56+
Moss mode is a connection mode (`HolochainConnectionMode` gains `'moss'`). The cross-group view is not implemented: a cross-group render throws.
57+
58+
## Open items
59+
60+
- `weaveClient.createCloneCell(req, true)` fails whenever `req.modifiers.properties` is set, which NDO clones need. See the #162 result and #164.
61+
- `AppletServices` in `@theweave/api` `0.7.0-rc.3` has `getAssetInfo`, `search` and `creatables`. Opening an asset is not a method on it: Moss renders the tool with an `asset` view (`renderInfo.view.type === 'asset'`), and the tool calls `weaveClient.openAsset` to open other assets.

‎documentation/specifications/ui_architecture.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,8 @@ On top of this hierarchy, the **next** UI iteration adds a cross-cutting **Persp
102102

103103
Dependencies only point down: routes render components, components read stores, stores call services, services call the Holochain client. The domain layer sits beside the services and is imported by stores and components. The three rules that keep it that way are enforced by a script (see [§17](#17-architecture-invariants)).
104104

105+
**Moss host (`lib/moss/`).** When the UI runs inside Moss it is a tool, not a page that owns its conductor connection. `lib/moss/` holds that seam as plain TypeScript beside the service layer: `host.ts` (pure host detection), `connect.ts` (the `WeaveClient` connection, injectable for tests) and `applet-services.ts` (what the tool tells Moss about itself). Only `utils/hc-connect.ts` imports it, as one more connection mode (§15.4), so components, stores and services see the same `AppClient` whether the host is Moss or a standalone conductor. Details in [moss-integration.md](moss-integration.md).
106+
105107
---
106108

107109

@@ -740,6 +742,7 @@ Each agent gets a **dedicated port = dedicated origin**, which yields fully isol
740742
| `launcher` | `window.__HC_LAUNCHER_ENV__` present | hc-spin Electron path (legacy/optional) |
741743
| `manifest` | `/hc-connection.json` has agents | **Primary web path**; picks the entry matching `getDevAgentIndex()`; polls up to 5 min while conductors install |
742744
| `env` | `VITE_HC_ADMIN_WS_URL` + `VITE_HC_APP_WS_URL` | manual override |
745+
| `moss` | `detectCurrentHost()` reports Moss | Checked first. The UI runs as a Moss tool: `connectMoss()` returns the applet client Moss hands the tool; Moss owns the conductor and signing, so there is no admin URL and no credential authorization. See [moss-integration.md](moss-integration.md) |
743746

744747

745748
In `manifest`/`env` modes the result carries the `adminWsUrl` so the UI can authorize signing credentials for **runtime-created group clone cells**.

‎package.json‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
"sweettest:verbose": "bun run build:happ && CARGO_TARGET_DIR=target/native-tests cargo test -p nondominium_sweettest -- --nocapture",
1717
"sweettest:only": "CARGO_TARGET_DIR=target/native-tests cargo test -p nondominium_sweettest",
1818
"launch:happ": "node scripts/launch-happ.mjs",
19+
"moss:install": "bun install --cwd weave",
20+
"tool-dev": "concurrently -k \"UI_PORT=8888 bun run --filter ui start\" \"bun run --cwd weave agent1\" \"bun run --cwd weave agent2\"",
21+
"tool-dev-1": "concurrently -k \"UI_PORT=8888 bun run --filter ui start\" \"bun run --cwd weave agent1\"",
1922
"e2e": "bun run --filter ui test:e2e",
2023
"e2e:ui": "bun run --filter ui test:e2e:ui",
2124
"package": "npm run build:happ && npm run --filter ui package && hc web-app pack workdir --recursive",

‎ui/package.json‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"@holochain/client": "^0.21.1",
5151
"@msgpack/msgpack": "^3.0.0",
5252
"@nondominium/shared-types": "workspace:*",
53+
"@theweave/api": "0.7.0-rc.3",
5354
"@valueflows/vf-graphql-holochain": "file:../vendor/valueflows-vf-graphql-holochain-0.700.0-rc.0.tgz",
5455
"effect": "4.0.0",
5556
"melt": "^0.44.0"

0 commit comments

Comments
 (0)