Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The build checkout intentionally installs development dependencies, including th
pinned OpenClaw `2026.6.34` SDK compatibility baseline. Deployments do not need
that development tree.

From an npm-managed local OpenClaw `2026.7.2-beta.6` or newer checkout, install the built working directory:
From an npm-managed local OpenClaw `2026.6.34` or newer checkout, install the built working directory:

```bash
npm install --omit=dev /absolute/path/to/openclaw-armada-dm
Expand All @@ -35,9 +35,9 @@ For a standard OpenClaw installation, pack and install the managed artifact:

```bash
npm pack
sha256sum openclaw-armada-dm-0.1.2.tgz > openclaw-armada-dm-0.1.2.tgz.sha256
sha256sum --check openclaw-armada-dm-0.1.2.tgz.sha256
openclaw plugins install npm-pack:/absolute/path/openclaw-armada-dm-0.1.2.tgz
sha256sum openclaw-armada-dm-0.1.3.tgz > openclaw-armada-dm-0.1.3.tgz.sha256
sha256sum --check openclaw-armada-dm-0.1.3.tgz.sha256
openclaw plugins install npm-pack:/absolute/path/openclaw-armada-dm-0.1.3.tgz
openclaw plugins enable armada-dm
openclaw gateway restart
```
Expand All @@ -53,16 +53,16 @@ Maintainers can publish the package and checksum in the repository's Releases
section by pushing a version tag after its version bump reaches `main`:

```bash
git tag -a v0.1.2 -m "v0.1.2"
git push origin v0.1.2
git tag -a v0.1.3 -m "v0.1.3"
git push origin v0.1.3
```

The tag must exactly match `v` followed by the version in `package.json`. The
release workflow repeats the install, test, build, package-validation, pack, and
checksum sequence before creating the GitHub release. It attaches
`openclaw-armada-dm-0.1.2.tgz` and its `.sha256` checksum as release assets.
`openclaw-armada-dm-0.1.3.tgz` and its `.sha256` checksum as release assets.

The published `setup-entry.js` uses only the OpenClaw `2026.6.34` public SDK compatibility baseline, while deployment requires patched OpenClaw `2026.7.2-beta.6` or newer. It does not run a wizard, prompt for values, edit configuration, read the secret file, publish events, or start relay connections.
The published `setup-entry.js` uses only the OpenClaw `2026.6.34` public SDK compatibility baseline, and deployment requires OpenClaw `2026.6.34` or newer. It does not run a wizard, prompt for values, edit configuration, read the secret file, publish events, or start relay connections.

## Migrating another Nostr channel

Expand Down
4 changes: 2 additions & 2 deletions SECURITY.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ Report suspected vulnerabilities privately to the repository maintainers. Do not

Use a dedicated Nostr bot identity. Store its single `nsec` at `/path/to/.openclaw/secrets/nostr_nsec` in a mode-0700 directory and a mode-0600 file, configure OpenClaw's `nostr` single-value file provider, and reference it from `channels.nostr.privateKey`. The plugin never opens that file directly and must never expose the resolved key through configuration, logs, errors, or status.

Deploy only on OpenClaw `2026.7.2-beta.6` or newer. The plugin deliberately compiles and typechecks against the narrower `2026.6.34` public SDK surface for compatibility, but npm currently reports advisories in that exact development-only package tree, so it is not the approved smoke-test or runtime host.
OpenClaw `2026.6.34` is the minimum supported host and the exact public-SDK baseline. npm currently reports advisories in that host's dependency tree. Operators who remain on the minimum version must review and accept or mitigate those host-level findings; upgrading OpenClaw remains the preferred risk reduction when deployment constraints allow it.

`npm run audit` checks the complete dependency tree as well as production dependencies. It fails for any advisory outside the nested, development-only `openclaw@2026.6.34` SDK baseline, and it independently verifies that the deployable host tree is the patched version above. Findings attached to the exact SDK baseline are reported explicitly, never shipped in the plugin package, and never accepted in the runtime smoke host.
`npm run audit` checks the complete dependency tree as well as production dependencies. It requires zero findings in the plugin's shipped production dependencies and fails for any finding outside the nested, development-only `openclaw@2026.6.34` SDK/runtime smoke tree. Findings in that host mirror are reported explicitly and are not shipped in the plugin package. This repository check does not certify an installed OpenClaw host as vulnerability-free; audit the installed host separately before deployment.

NIP-17 is transport end-to-end encryption. Plaintext exists on the OpenClaw host and is provided to the operator's configured model provider. Use least-privilege tools and sandboxing for every agent reachable through this channel.

Expand Down
22 changes: 11 additions & 11 deletions docs/IMPLEMENTATION_PLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ Crypto and relay code must not import OpenClaw agent/runtime internals. OpenClaw
└── relay-session.test.ts
```

`AGENTS.md` should retain the project's TDD, strict TypeScript, zero-runtime-vulnerability, and key-hygiene rules, updated for the OpenClaw plugin structure. `dist/` is generated by the build, included in the npm package, and verified rather than hand-edited.
`AGENTS.md` should retain the project's TDD, strict TypeScript, dependency-audit, and key-hygiene rules, updated for the OpenClaw plugin structure. `dist/` is generated by the build, included in the npm package, and verified rather than hand-edited.

## 7. Template adaptation map

Expand Down Expand Up @@ -234,7 +234,7 @@ Do not port Buzz room discovery, membership, directory groups, group allowlists,
- `openclaw.extensions: ["./dist/index.js"]`;
- `openclaw.setupEntry: "./dist/setup-entry.js"`;
- channel metadata with ID `nostr`;
- `openclaw.install.npmSpec: "openclaw-armada-dm"`, `minHostVersion: ">=2026.7.2-beta.6"`, and npm as the default remote choice if the package is ever published;
- `openclaw.install.npmSpec: "openclaw-armada-dm"`, `minHostVersion: ">=2026.6.34"`, and npm as the default remote choice if the package is ever published;
- `openclaw.compat.pluginApi: ">=2026.6.34"`;
- `openclaw.build.openclawVersion` and `openclaw.build.pluginSdkVersion` set to `2026.6.34`;
- all runtime imports, including `nostr-tools`, declared in `dependencies`; OpenClaw remains a `peerDependency` and test/dev dependency.
Expand All @@ -254,14 +254,14 @@ Because `nostr` is a shared channel ID, installation must fail clearly if anothe

### OpenClaw 2026.6.34 compatibility baseline

OpenClaw `2026.6.34` at full commit `5c38f996d4059ebd9080cf74dc611ec3a17f4d50` is the exact public-SDK baseline. Deployments require patched OpenClaw `2026.7.2-beta.6` or newer:
OpenClaw `2026.6.34` at full commit `5c38f996d4059ebd9080cf74dc611ec3a17f4d50` is both the exact public-SDK baseline and the minimum supported host:

- compile and typecheck against exactly `openclaw@2026.6.34`, not a floating newer SDK;
- run package discovery, setup-entry import, SecretRef resolution, channel registration, single-owner ingress, reply delivery, status, and gateway lifecycle smoke tests against that exact host build;
- use built JavaScript directly in `openclaw.extensions`/`openclaw.setupEntry`; do not emit the later `runtimeExtensions` or `runtimeSetupEntry` fields;
- use `resolveStableChannelMessageIngress`, `dispatchInboundDirectDmWithRuntime`, and `createClaimableDedupe`, which are present in this revision;
- do not import the later durable ingress monitor, ingress effect-once, or later-only setup/runtime helpers;
- fail installation on hosts older than `2026.7.2-beta.6` through `openclaw.install.minHostVersion` and `peerDependencies`, while `openclaw.compat.pluginApi` records the narrower API surface used by the plugin.
- fail installation on hosts older than `2026.6.34` through `openclaw.install.minHostVersion` and `peerDependencies`, while `openclaw.compat.pluginApi` records the narrower API surface used by the plugin.

CI must run an API-baseline test that imports every declared `openclaw/plugin-sdk/*` subpath from an installed `openclaw@2026.6.34` package. Documentation from `main` is informative only; the pinned source tree is authoritative for v1.

Expand Down Expand Up @@ -354,7 +354,7 @@ Field behavior:

Environment fallbacks may support only the non-secret `ARMADA_DM_RELAYS` and `ARMADA_DM_DISCOVERY_RELAYS` lists. The Nostr private key has no environment or inline fallback in v1. Secret values must never be copied into status objects, thrown errors, or logs.

The manifest's `channelConfigs.nostr.schema` must mirror the runtime Zod schema exactly and use `additionalProperties: false`. The plugin-entry `configSchema` is separately strict and empty for single-account v1. Set `peerDependencies.openclaw` to `>=2026.7.2-beta.6`, compile and typecheck against exactly `openclaw@2026.6.34`, and upgrade the baseline deliberately with contract tests. Do not import an SDK symbol merely because it exists in newer OpenClaw documentation.
The manifest's `channelConfigs.nostr.schema` must mirror the runtime Zod schema exactly and use `additionalProperties: false`. The plugin-entry `configSchema` is separately strict and empty for single-account v1. Set `peerDependencies.openclaw` to `>=2026.6.34`, compile and typecheck against exactly `openclaw@2026.6.34`, and upgrade the baseline deliberately with contract tests. Do not import an SDK symbol merely because it exists in newer OpenClaw documentation.

### Relay URL and outbound-network policy

Expand Down Expand Up @@ -578,7 +578,7 @@ Slices are sequential: an agent starts only after every dependency's exit gate i

- Manifest recognizes exactly the `nostr` channel under plugin ID `armada-dm`.
- Package name, install hint, plugin ID, channel ID, source entries, and built runtime entries are mutually consistent.
- Manifest uses `kind: "channel"`; package entries point directly to built JavaScript; compatibility/build metadata name the OpenClaw `2026.6.34` API baseline, install metadata names the patched `2026.7.2-beta.6` minimum host, and later-only runtime-entry fields are absent.
- Manifest uses `kind: "channel"`; package entries point directly to built JavaScript; compatibility/build and install metadata name OpenClaw `2026.6.34` as the API baseline and minimum host, and later-only runtime-entry fields are absent.
- Every imported `openclaw/plugin-sdk/*` subpath resolves and typechecks from exactly `openclaw@2026.6.34`.
- Startup fails with a clear ownership diagnostic when another enabled plugin already registers channel `nostr`; migration preserves configuration but never silently replaces a runtime owner.
- Runtime and JSON schemas accept the pre-provisioned `nostr` file provider and matching `channels.nostr.privateKey` SecretRef plus valid relay/DM-policy configuration.
Expand All @@ -594,8 +594,8 @@ Slices are sequential: an agent starts only after every dependency's exit gate i
**Exit**

- `npm test`, `npm run lint`, `npm run build`, package validation, and `npm pack --dry-run` pass.
- `npm run audit` reports zero production and deploy-host vulnerabilities, checks the complete tree, and rejects every finding outside the explicitly isolated development-only `openclaw@2026.6.34` SDK baseline.
- A clean npm-managed local patched OpenClaw host discovers the plugin after `npm install --omit=dev /absolute/path/to/openclaw-armada-dm`; a clean managed patched host also discovers the packed tarball through `npm-pack:`.
- `npm run audit` reports zero plugin production vulnerabilities, checks the complete tree, and rejects every finding outside the explicitly isolated development-only `openclaw@2026.6.34` SDK/runtime smoke tree; operators are told to audit the installed host separately.
- A clean npm-managed local OpenClaw `2026.6.34` host discovers the plugin after `npm install --omit=dev /absolute/path/to/openclaw-armada-dm`; a clean managed `2026.6.34` host also discovers the packed tarball through `npm-pack:`.
- The migration smoke test disables the prior Nostr plugin, preserves `secrets.providers.nostr` and `channels.nostr`, configures exactly one owner, enables plugin `armada-dm`, audits/reloads secrets, restarts the gateway, and proves existing `nostr` pairing approvals are ignored rather than deleted or imported.

### Coverage group 2 — NIP-17 cryptographic core
Expand Down Expand Up @@ -721,7 +721,7 @@ Slices are sequential: an agent starts only after every dependency's exit gate i
- Run a full encrypted round trip: disposable Armada-like sender -> relay -> plugin -> mocked OpenClaw dispatch -> encrypted reply -> sender decrypt.
- Assert kind-1059 carrier events contain neither message plaintext nor the real sender pubkey outside encrypted layers. Separately assert and document that a relay receiving a NIP-42 AUTH event can observe the authenticating bot pubkey even though AUTH is not published as a stored DM event.
- Assert package import, setup import, and disabled-channel discovery do not start background work.
- Run tests, coverage, lint, build, native package/manifest validation, the 2026.6.34 SDK-import baseline, both local-install smoke paths, package dry-run, package-content allowlist, and the complete-tree/zero-runtime-vulnerability audit in CI.
- Run tests, coverage, lint, build, native package/manifest validation, the 2026.6.34 SDK-import baseline, both local-install smoke paths, package dry-run, package-content allowlist, and the complete-tree dependency audit in CI.

**Manual staging**

Expand All @@ -737,7 +737,7 @@ Slices are sequential: an agent starts only after every dependency's exit gate i

**Release**

- Pack an initial prerelease and test both local `npm install --omit=dev` and OpenClaw-managed `npm-pack:` installation against the exact `2026.6.34` API baseline and a deployable OpenClaw `2026.7.2-beta.6` or newer host. Registry publication is optional.
- Pack an initial prerelease and test both local `npm install --omit=dev` and OpenClaw-managed `npm-pack:` installation against the exact `2026.6.34` API baseline and a deployable OpenClaw `2026.6.34` or newer host. Registry publication is optional.
- Promote to `1.0.0` only after the current Armada client initiates a conversation, receives an automatic reply, and the bot safely recognizes its recovery copy.

## 15. Required documentation
Expand All @@ -762,7 +762,7 @@ The README should include:
The first release is complete when all of the following are true:

- An npm-managed local OpenClaw checkout can discover the plugin after local `npm install --omit=dev`, and a clean standard OpenClaw installation can install the packed package through `npm-pack:`; both can configure, enable, disable, inspect, and remove it.
- All required manual configuration, secret, channel, single-owner ingress, reply-delivery, status, and lifecycle flows use only the OpenClaw `2026.6.34` public SDK surface, and the package advertises patched OpenClaw `2026.7.2-beta.6` as its minimum deployable host.
- All required manual configuration, secret, channel, single-owner ingress, reply-delivery, status, and lifecycle flows use only the OpenClaw `2026.6.34` public SDK surface, and the package advertises OpenClaw `2026.6.34` as its minimum deployable host.
- A pre-existing owner of channel `nostr` produces a clear conflict; migration to plugin `armada-dm` preserves the operator's `channels.nostr` and `secrets.providers.nostr` configuration only after the previous owner is disabled or removed.
- The plugin exposes direct text chat and encrypted inbound-media capability only.
- A valid Armada NIP-17 kind-14 DM reaches the intended OpenClaw agent once under cross-relay replay, rewrapping, reconnect, and concurrent-delivery tests; residual process-crash semantics are documented accurately rather than described as absolute exactly-once execution.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ This is an operator-facing slice. It does not yet exchange Nostr messages.
- npm package `openclaw-armada-dm`;
- plugin ID `armada-dm`;
- channel ID `nostr`;
- exact plugin API baseline `2026.6.34` and minimum deployable host `2026.7.2-beta.6`.
- exact plugin API baseline `2026.6.34` and minimum deployable host `2026.6.34`.
- Add import-safe built runtime and setup entry points.
- Register the single-account text-DM channel using only public SDK exports present at the pinned OpenClaw commit.
- Add strict runtime and manifest schemas for `channels.nostr`.
Expand Down Expand Up @@ -62,9 +62,9 @@ This is an operator-facing slice. It does not yet exchange Nostr messages.

## Exit gate

- Tests, lint, typecheck/build, package validation, `npm pack --dry-run`, and the complete-tree/zero-runtime-vulnerability audit pass.
- A clean npm-managed OpenClaw `2026.7.2-beta.6` or newer checkout discovers the plugin after `npm install --omit=dev /absolute/path/to/openclaw-armada-dm`.
- A clean OpenClaw `2026.7.2-beta.6` or newer instance discovers the packed artifact through `openclaw plugins install npm-pack:/absolute/path/to/package.tgz`.
- Tests, lint, typecheck/build, package validation, `npm pack --dry-run`, and the complete-tree dependency audit pass.
- A clean npm-managed OpenClaw `2026.6.34` or newer checkout discovers the plugin after `npm install --omit=dev /absolute/path/to/openclaw-armada-dm`.
- A clean OpenClaw `2026.6.34` or newer instance discovers the packed artifact through `openclaw plugins install npm-pack:/absolute/path/to/package.tgz`.
- With the documented pre-provisioned SecretRef, status shows the correct bot `npub` and never the secret.
- No relay connection or message processing exists yet.

Expand Down
2 changes: 1 addition & 1 deletion docs/implementation-slices/04-allowlisted-ai-roundtrip.md
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ With `dmPolicy: "allowlist"` and the operator's user `npub` in `allowFrom`:

## Exit gate

- The complete encrypted request/AI-response path typechecks against the exact OpenClaw `2026.6.34` SDK baseline and passes on the patched deployable host with a mocked model response.
- The complete encrypted request/AI-response path typechecks against and passes on the exact OpenClaw `2026.6.34` minimum host with a mocked model response.
- Two different allowlisted senders receive independent direct sessions.
- A user without a valid kind-10050 gets a clear delivery failure; the plugin does not silently publish to Ditto/Dreamith.
- All earlier slice tests remain green.
Expand Down
Loading
Loading