Skip to content

Developing xNet from inside xNet: the spec→plugin loop (0331) - #525

Merged
crs48 merged 8 commits into
mainfrom
claude/implement-0331-a3d74f
Jul 15, 2026
Merged

Developing xNet from inside xNet: the spec→plugin loop (0331)#525
crs48 merged 8 commits into
mainfrom
claude/implement-0331-a3d74f

Conversation

@crs48

@crs48 crs48 commented Jul 15, 2026

Copy link
Copy Markdown
Owner

Implements exploration 0331 — the workspace-plugin runtime that closes the spec→plugin loop at Patchwork speed without adopting Patchwork's trust model. Plugin source lives in the workspace as a synced node, builds in the browser, loads only inside an opaque-origin iframe, registers contributions over RPC, hot-reloads on source change, and feeds console/errors back to the authoring agent.

What landed (13/13 implementation items)

  • PluginSource schema (packages/plugins/src/schemas/plugin-source.ts) — multi-file files map + entry + data manifest + spec-Page relation + publishedHash; syncs/branches/drafts like any node.
  • Module builder (workspace-plugins/builder.ts) — per-file transpile (injected @swc/wasm-web), relative-import resolution across the files map, bare-import validation against a pinned import map (no npm, no remote). Structured diagnostics for plugin_build.
  • Sandboxed host (frame.ts, host.ts, store-rpc.ts, session.ts) — SandboxedPluginHost generalizes IframeWidgetHost: code loads only in an allow-scripts (never same-origin) iframe whose CSP connect-src derives from the manifest network allowlist; data-declared contributions land in the shared ContributionRegistry with handlers proxied over MessagePort; store access is gated three-deep — denylist-wins (identity/plugin-source/membership always unreachable), then read grants, then write grants.
  • Agent loop (agent-tools.ts, preview.ts) — plugin_scaffold / _read_file / _write_file / _build / _preview / _preview_feedback / _publish_request, folded into the AI surface's extraTools (new MCPServerConfig.extraTools). The writing-xnet-plugins skill is exported to external agents via the workspace exporter.
  • Hot reload (watcher.ts) — Yjs subscribe + 250ms debounce → rebuild → swap; failed rebuild keeps the old version; crash → auto-disable + last-good hash (the 0190 remediation rule).
  • Hash pinning (hash.ts) — activation pins publishedHash; drift renders as diff-and-consent, never a silent update (0327-E).
  • DraftsPluginSource is forkable, so agent plugin_write_file edits land in an agent-draft clone and merge is the review (0329), proven end-to-end in packages/history.
  • Publish (publish.ts) — P2P pin-and-share + community.json export for the public marketplace.
  • Electron parity — hardened-renderer compatibility test (frame uses only sandbox-safe Web APIs, no node/same-origin); the check-electron-parity waiver reason is refined to record the sandbox rung is now renderer-portable.

Validation (8/8)

Loop latency (build well under budget), no host-realm execution (canary sandbox tests + CSP assertions), capability floor + denylist, trust/provenance/revocation, agent-loop-closes (the chitter-chatter test: spec Page → broken module → self-debug via feedback → live composing view, no human relay), composition (workspace + bundled commands share the palette; plugin-extends-plugin by registry id), spec→plugin end-to-end, and the guard scripts (check:cloud-boundary, check:electron-parity, humane-patterns, typecheck, lint) stay green.

New tests: 58 across packages/plugins (738 total pass) + packages/history.

Scope note

Increment 5b (Electron parity) verifies the sandbox rung under the hardened renderer and consciously records the parity decision, but keeps the /lab editor route waived — porting the Labs editor UI to the desktop shell is a separate lift beyond 0331's package-level spine. Two pre-existing fallow dead-code findings (.storybook/workspace-aliases.ts, a fast-check import in packages/data) are untouched by this change and not a required gate.

🤖 Generated with Claude Code

xNet Test added 5 commits July 15, 2026 20:44
…builder, sandboxed host, contribution RPC

Exploration 0331 increments 1a-2: plugin source lives in the workspace as a
PluginSource node (multi-file files map + entry + data manifest), builds to a
module graph in the host (never executed there), loads only inside an
opaque-origin iframe whose CSP derives connect-src from the manifest network
allowlist, and registers data-declared contributions into the shared
ContributionRegistry with every handler proxied over MessagePort RPC. Store
access is gated three-deep: denylist (identity/plugin-source/membership always
unreachable) then read grants then guardStore-style write grants.

Signed-off-by: xNet Test <test@xnet.dev>
…reload, hash pinning, drafts, publish

Exploration 0331 increments 3a-5a + 4c: the plugin_scaffold/read_file/
write_file/build/preview/preview_feedback/publish_request tool surface (folded
into the AI surface's extraTools beside lab_*), the writing-xnet-plugins skill
exported to external agents, the SourceWatcher + hot reloader (250ms debounce →
rebuild → swap; crash → auto-disable + last-good hash), content-hash pinning
with diff-and-consent on drift, drafts integration (PluginSource is forkable so
agent writes land in a draft transparently), and both publish paths (P2P
pin-and-share + community.json export). The spec→plugin end-to-end test drives
the whole chitter-chatter loop: spec Page → scaffold → broken module →
self-debug via feedback → live composing view, no human relay.

Signed-off-by: xNet Test <test@xnet.dev>
…complete

Increment 5b: hardened-renderer compatibility test proving the workspace-plugin
frame uses only sandbox-safe Web APIs (no node, no same-origin), and a refined
electron-parity waiver reason recording that the sandbox rung is now
renderer-portable (only the Labs editor UI remains web-first). Cross-links added
from 0190/0192/0327; 0190 notes the bridge daemon has shipped. All 8 validation
items pass: loop latency, no host-realm execution, capability floor + denylist,
trust/provenance/revocation, agent-loop-closes, composition, spec→plugin e2e,
and the guard scripts (cloud-boundary, electron-parity, typecheck, lint).

Signed-off-by: xNet Test <test@xnet.dev>
… plugin loop

Signed-off-by: xNet Test <test@xnet.dev>
@crs48
crs48 temporarily deployed to pr-525 July 15, 2026 18:59 — with GitHub Actions Inactive
@crs48
crs48 temporarily deployed to pr-525 July 15, 2026 19:05 — with GitHub Actions Inactive
github-actions Bot added a commit that referenced this pull request Jul 15, 2026
@github-actions

github-actions Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

Preview removed for PR #525.

github-actions Bot added a commit that referenced this pull request Jul 15, 2026
@crs48
crs48 temporarily deployed to pr-525 July 15, 2026 19:13 — with GitHub Actions Inactive
@crs48
crs48 merged commit fd50ca5 into main Jul 15, 2026
19 of 20 checks passed
@crs48
crs48 deleted the claude/implement-0331-a3d74f branch July 15, 2026 19:19
github-actions Bot added a commit that referenced this pull request Jul 15, 2026
crs48 added a commit that referenced this pull request Jul 18, 2026
This PR was opened by the [Changesets
release](https://github.com/changesets/action) GitHub action. When
you're ready to do a release, you can merge this and the packages will
be published to npm automatically. If you're not ready to do a release
yet, that's fine, whenever you add more changesets to main, this PR will
be updated.


# Releases
## @xnetjs/cli@0.2.0

### Minor Changes

- [#533](#533)
[`0a4a1de`](0a4a1de)
Thanks [@crs48](https://github.com/crs48)! - Agent Passports and signed
agent audit trails (exploration 0337).
- `@xnetjs/data`: new agent schema pack — `AgentPassport`,
`AgentSession`,
`AgentAction`, `AgentApproval`, `AgentNotification` — with deterministic
id
    helpers (`agentActionId`, …) and `redactInstruction`.
- `@xnetjs/identity`: `mintAgentPassport` / `verifyAgentPassport`
(per-agent
    `did:key` + operator-delegated, attenuation-checked UCAN; wildcards
    rejected) and `rootIssuers` for delegation-chain root inspection.
- `@xnetjs/plugins`: `AgentAuditRecorder` wraps the AI surface so every
tool
call lands as an `AgentAction` node and medium+ risk calls park behind a
risk-tiered approval ceremony (chat nonce with TTL for medium;
xNet-surface
only for high/critical); ceremony tools (`xnet_approve`, `xnet_deny`,
`xnet_pending_approvals`, `xnet_undo`) and the `xnet_poll_notifications`
outbox tool; `MCPServerConfig.agentAudit` wires it into the MCP server;
`NodeStoreAPI.create` now accepts an optional deterministic `id`; new AI
    scopes `agent.approve` and `agent.notifications`.
  - `@xnetjs/cli`: `xnet agent enroll <name>` mints and stores passports
(`~/.xnet/agents`, 0600) and prints OpenClaw/Hermes config; `xnet mcp
serve
--agent <name> [--db <path>]` serves an agent-scoped session over an
    agent-signed local store.

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de),
[`fa93e2f`](fa93e2f)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/identity@2.1.0
  - @xnetjs/plugins@2.1.0
  - @xnetjs/runtime@0.5.1
  - @xnetjs/sync@2.1.0
  - @xnetjs/sqlite@2.1.0
  - @xnetjs/crypto@2.1.0
  - @xnetjs/core@2.1.0
## @xnetjs/data@2.1.0

### Minor Changes

- [#533](#533)
[`0a4a1de`](0a4a1de)
Thanks [@crs48](https://github.com/crs48)! - Agent Passports and signed
agent audit trails (exploration 0337).
- `@xnetjs/data`: new agent schema pack — `AgentPassport`,
`AgentSession`,
`AgentAction`, `AgentApproval`, `AgentNotification` — with deterministic
id
    helpers (`agentActionId`, …) and `redactInstruction`.
- `@xnetjs/identity`: `mintAgentPassport` / `verifyAgentPassport`
(per-agent
    `did:key` + operator-delegated, attenuation-checked UCAN; wildcards
    rejected) and `rootIssuers` for delegation-chain root inspection.
- `@xnetjs/plugins`: `AgentAuditRecorder` wraps the AI surface so every
tool
call lands as an `AgentAction` node and medium+ risk calls park behind a
risk-tiered approval ceremony (chat nonce with TTL for medium;
xNet-surface
only for high/critical); ceremony tools (`xnet_approve`, `xnet_deny`,
`xnet_pending_approvals`, `xnet_undo`) and the `xnet_poll_notifications`
outbox tool; `MCPServerConfig.agentAudit` wires it into the MCP server;
`NodeStoreAPI.create` now accepts an optional deterministic `id`; new AI
    scopes `agent.approve` and `agent.notifications`.
  - `@xnetjs/cli`: `xnet agent enroll <name>` mints and stores passports
(`~/.xnet/agents`, 0600) and prints OpenClaw/Hermes config; `xnet mcp
serve
--agent <name> [--db <path>]` serves an agent-scoped session over an
    agent-signed local store.

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de)]:
  - @xnetjs/identity@2.1.0
  - @xnetjs/sync@2.1.0
  - @xnetjs/storage@2.1.0
  - @xnetjs/sqlite@2.1.0
  - @xnetjs/crypto@2.1.0
  - @xnetjs/core@2.1.0
## @xnetjs/identity@2.1.0

### Minor Changes

- [#533](#533)
[`0a4a1de`](0a4a1de)
Thanks [@crs48](https://github.com/crs48)! - Agent Passports and signed
agent audit trails (exploration 0337).
- `@xnetjs/data`: new agent schema pack — `AgentPassport`,
`AgentSession`,
`AgentAction`, `AgentApproval`, `AgentNotification` — with deterministic
id
    helpers (`agentActionId`, …) and `redactInstruction`.
- `@xnetjs/identity`: `mintAgentPassport` / `verifyAgentPassport`
(per-agent
    `did:key` + operator-delegated, attenuation-checked UCAN; wildcards
    rejected) and `rootIssuers` for delegation-chain root inspection.
- `@xnetjs/plugins`: `AgentAuditRecorder` wraps the AI surface so every
tool
call lands as an `AgentAction` node and medium+ risk calls park behind a
risk-tiered approval ceremony (chat nonce with TTL for medium;
xNet-surface
only for high/critical); ceremony tools (`xnet_approve`, `xnet_deny`,
`xnet_pending_approvals`, `xnet_undo`) and the `xnet_poll_notifications`
outbox tool; `MCPServerConfig.agentAudit` wires it into the MCP server;
`NodeStoreAPI.create` now accepts an optional deterministic `id`; new AI
    scopes `agent.approve` and `agent.notifications`.
  - `@xnetjs/cli`: `xnet agent enroll <name>` mints and stores passports
(`~/.xnet/agents`, 0600) and prints OpenClaw/Hermes config; `xnet mcp
serve
--agent <name> [--db <path>]` serves an agent-scoped session over an
    agent-signed local store.

### Patch Changes

- Updated dependencies []:
  - @xnetjs/crypto@2.1.0
  - @xnetjs/core@2.1.0
## @xnetjs/plugins@2.1.0

### Minor Changes

- [#533](#533)
[`0a4a1de`](0a4a1de)
Thanks [@crs48](https://github.com/crs48)! - Agent Passports and signed
agent audit trails (exploration 0337).
- `@xnetjs/data`: new agent schema pack — `AgentPassport`,
`AgentSession`,
`AgentAction`, `AgentApproval`, `AgentNotification` — with deterministic
id
    helpers (`agentActionId`, …) and `redactInstruction`.
- `@xnetjs/identity`: `mintAgentPassport` / `verifyAgentPassport`
(per-agent
    `did:key` + operator-delegated, attenuation-checked UCAN; wildcards
    rejected) and `rootIssuers` for delegation-chain root inspection.
- `@xnetjs/plugins`: `AgentAuditRecorder` wraps the AI surface so every
tool
call lands as an `AgentAction` node and medium+ risk calls park behind a
risk-tiered approval ceremony (chat nonce with TTL for medium;
xNet-surface
only for high/critical); ceremony tools (`xnet_approve`, `xnet_deny`,
`xnet_pending_approvals`, `xnet_undo`) and the `xnet_poll_notifications`
outbox tool; `MCPServerConfig.agentAudit` wires it into the MCP server;
`NodeStoreAPI.create` now accepts an optional deterministic `id`; new AI
    scopes `agent.approve` and `agent.notifications`.
  - `@xnetjs/cli`: `xnet agent enroll <name>` mints and stores passports
(`~/.xnet/agents`, 0600) and prints OpenClaw/Hermes config; `xnet mcp
serve
--agent <name> [--db <path>]` serves an agent-scoped session over an
    agent-signed local store.

- [#525](#525)
[`fa93e2f`](fa93e2f)
Thanks [@crs48](https://github.com/crs48)! - Add the workspace-plugin
runtime (exploration 0331): author, hot-load, and
compose plugins whose source lives in the workspace as a `PluginSource`
node.
New public surface: `PluginSourceSchema` + `readPluginSourceNode`, an
in-browser
module builder (`buildPluginModuleGraph`) with a pinned import map, the
`SandboxedPluginHost` (`activateWorkspacePlugin`) that loads plugin code
only in
  an opaque-origin iframe and registers data-declared contributions over
MessagePort RPC, a gated store RPC (`createPluginStoreRpc`,
denylist-wins), a
250ms-debounce hot reloader (`createWorkspacePluginHotReloader`),
content-hash
pinning + drift diffing (`computePluginSourceHash`,
`assessPluginUpdate`), the
  `plugin_*` agent tools (`createWorkspacePluginAgentTools`) and the
`WRITING_XNET_PLUGINS_SKILL_MD` authoring skill, and both publish paths
(`requestWorkspacePluginPublish`, `buildCommunityRegistryEntry`).
`MCPServerConfig`
gains an `extraTools` field to expose the new tools beside the
built-ins.

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/abuse@2.1.0
  - @xnetjs/core@2.1.0
## @xnetjs/react@2.1.0

### Minor Changes

- [#534](#534)
[`5473a29`](5473a29)
Thanks [@crs48](https://github.com/crs48)! - `useGridDatabase` now pages
database rows through a growing window instead of a fixed 500-row page:
new `fetchMoreRows()` grows the window by `pageSize` (default 500) up to
`maxLoaded` (default 2000, configurable via options), and the result
exposes `totalRowCount` (exact matching count), `hasMoreRows`, and
`isFetchingMoreRows` so grids can render honest totals and infinite
scroll. Existing consumers keep working unchanged — rows still arrive
sorted by `sortKey` on the live query path.

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de),
[`fa93e2f`](fa93e2f)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/identity@2.1.0
  - @xnetjs/plugins@2.1.0
  - @xnetjs/data-bridge@2.1.0
  - @xnetjs/history@2.1.0
  - @xnetjs/runtime@0.5.1
  - @xnetjs/sync@2.1.0
  - @xnetjs/crypto@2.1.0
  - @xnetjs/core@2.1.0
## @xnetjs/abuse@2.1.0

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de)]:
  - @xnetjs/identity@2.1.0
  - @xnetjs/crypto@2.1.0
## @xnetjs/crypto@2.1.0

### Patch Changes

- Updated dependencies []:
  - @xnetjs/core@2.1.0
## @xnetjs/data-bridge@2.1.0

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/sync@2.1.0
  - @xnetjs/sqlite@2.1.0
  - @xnetjs/core@2.1.0
## @xnetjs/history@2.1.0

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/sync@2.1.0
  - @xnetjs/core@2.1.0
## @xnetjs/runtime@0.5.1

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de),
[`fa93e2f`](fa93e2f)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/identity@2.1.0
  - @xnetjs/plugins@2.1.0
  - @xnetjs/data-bridge@2.1.0
  - @xnetjs/history@2.1.0
  - @xnetjs/sync@2.1.0
  - @xnetjs/storage@2.1.0
  - @xnetjs/crypto@2.1.0
  - @xnetjs/core@2.1.0
## @xnetjs/storage@2.1.0

### Patch Changes

- Updated dependencies []:
  - @xnetjs/sqlite@2.1.0
  - @xnetjs/crypto@2.1.0
  - @xnetjs/core@2.1.0
## @xnetjs/sync@2.1.0

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de)]:
  - @xnetjs/identity@2.1.0
  - @xnetjs/crypto@2.1.0
  - @xnetjs/core@2.1.0
## @xnetjs/core@2.1.0


## @xnetjs/sqlite@2.1.0


## xnet-cloud@0.0.19

### Patch Changes

- Updated dependencies []:
  - @xnetjs/telemetry@0.0.1
  - @xnetjs/crypto@2.1.0
  - @xnetjs/core@2.1.0
  - @xnetjs/cloud@0.0.1
## xnet-demos@0.1.3

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de),
[`5473a29`](5473a29)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/identity@2.1.0
  - @xnetjs/react@2.1.0
  - @xnetjs/devtools@0.1.0
## @xnetjs/brain@0.0.20

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/vectors@0.0.1
## @xnetjs/comms@0.0.20

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/crypto@2.1.0
## @xnetjs/dashboard@0.0.20

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de),
[`5473a29`](5473a29),
[`fa93e2f`](fa93e2f)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/plugins@2.1.0
  - @xnetjs/react@2.1.0
  - @xnetjs/social@0.0.20
## @xnetjs/labs@0.0.20

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de),
[`fa93e2f`](fa93e2f)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/plugins@2.1.0
## @xnetjs/licenses@0.0.20

### Patch Changes

- Updated dependencies []:
  - @xnetjs/crypto@2.1.0
## @xnetjs/maps@0.0.20

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de)]:
  - @xnetjs/data@2.1.0
## @xnetjs/meetings@0.0.13

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de),
[`fa93e2f`](fa93e2f)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/plugins@2.1.0
## @xnetjs/server@0.0.19

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/identity@2.1.0
  - @xnetjs/data-bridge@2.1.0
  - @xnetjs/crypto@2.1.0
## @xnetjs/social@0.0.20

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de)]:
  - @xnetjs/data@2.1.0
  - @xnetjs/crypto@2.1.0
## @xnetjs/unreal@0.0.20

### Patch Changes

- Updated dependencies
[[`0a4a1de`](0a4a1de)]:
  - @xnetjs/data@2.1.0
## xnet-desktop@2.1.0

Desktop shell release riding the @xnetjs/core 2.1.0 train.
Desktop-specific changes are not tracked here; see the core packages'
changelogs for what shipped.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant