Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c25837d63e | ||
|
|
c4737f33a5 | ||
|
|
0b0196893e | ||
|
|
3e51472b4c |
@@ -0,0 +1,110 @@
|
||||
# Findings — 2026-09-04
|
||||
|
||||
**Author:** Clawdia
|
||||
**Reason:** Preserve a clear record of what was actually true at this point in the project, and what is still unknown / pending. The previous evening's chat log was incomplete and did not fully capture the state of the repo, the Gitea PRs, or the live OpenClaw Gateway. This file is the canonical "where we are right now" snapshot so we don't lose progress while the project is paused.
|
||||
|
||||
No code or runtime state was changed to write this file. No live MeshCentral calls were made.
|
||||
|
||||
---
|
||||
|
||||
## 1. Verified reality at this checkpoint
|
||||
|
||||
### 1.1 Local repository
|
||||
|
||||
- **Path:** `~/.gitea-staging/meshcentral-openclaw-bridge/`
|
||||
- **Branch:** `main` — clean working tree, in sync with Gitea.
|
||||
- **Remote:** `origin` → `https://gitea.ledrew.me/ledadmin/meshcentral-openclaw-bridge.git` (auth: `ledadmin`).
|
||||
|
||||
**Merged PRs on `main` (Gitea confirmed):**
|
||||
|
||||
| PR | Title | Merge commit |
|
||||
|---|---|---|
|
||||
| #1 | Integrate upstream-compatible read-only MeshCentral transport | `ad03d23` |
|
||||
| #2 | Add narrow OpenClaw MeshCentral read-only plugin | `3e51472` |
|
||||
| #3 | Fix OpenClaw plugin approved target matching | `c4737f3` |
|
||||
|
||||
PR #3 was the "case-insensitive device matching + remove redundant meshid filter" fix. It is in the merged source but is **not yet reflected in the running OpenClaw plugin artifact** — see §1.3.
|
||||
|
||||
**Local verification gates (re-run today, all green):**
|
||||
|
||||
| Gate | Result |
|
||||
|---|---|
|
||||
| `implementation/` — `npm test --runInBand` | 13 suites, 93 tests passed |
|
||||
| `implementation/` — `npm run build` (tsc) | passed |
|
||||
| `implementation/` — `npm run lint` (eslint + tsc --noEmit) | passed |
|
||||
| `openclaw-plugin/` — `npm run build` (tsc) | passed |
|
||||
| `openclaw-plugin/` — `npm test` (static safety tests) | 2/2 passed |
|
||||
| `openclaw-plugin/` — `npm run plugin:validate` | `Plugin meshcentral-readonly is valid.` |
|
||||
|
||||
**Repository hygiene:** `openclaw-plugin/{dist,node_modules,coverage}/` are properly listed in `.gitignore` and are not tracked. `openclaw-plugin/package-lock.json` **is** tracked, which is the intended behavior for an installable package.
|
||||
|
||||
### 1.2 Bridge library (`implementation/`)
|
||||
|
||||
- Read-only upstream-compatible transport merged in PR #1.
|
||||
- MeshCentral 1.2.5 on `mesh.ledrew.me` (LXC on PVE2, internal `10.10.10.177:80`).
|
||||
- Live read-only probe against `Servers` / `PVE3` succeeded previously (per `RESUME-HANDOFF.md` and `PROJECT-STATUS-2026-08-25.md`); the standalone bridge path is verified.
|
||||
- Allowed operations are still strictly: `serverversion` (probe-only), `meshes`, `nodes`, `deviceinfo`. Prohibited: commands, diagnostics, power ops, file transfer, administration, state changes, PVE1, PVE2.
|
||||
|
||||
### 1.3 OpenClaw Gateway (live, runtime state)
|
||||
|
||||
- **Service:** `openclaw-gateway.service` — user systemd, **active/running** (pid 1467816, OpenClaw 2026.7.1-2).
|
||||
- **Plugin installed:** `meshcentral-readonly` v0.1.0, status `loaded`, format `openclaw`, install path `~/.openclaw/npm/projects/ledrew-openclaw-meshcentral-readonly-…/node_modules/@ledrew/openclaw-meshcentral-readonly/`.
|
||||
- **Plugin config (current):**
|
||||
- `url`: `https://mesh.ledrew.me`
|
||||
- `username`: `sa_clawdia`
|
||||
- `passwordEnv`: `__OPENCLAW_REDACTED__` (stored as env-var name only; password is in the protected runtime env file, not in `openclaw.json`)
|
||||
- `groupName`: `Servers`
|
||||
- `deviceName`: `PVE3`
|
||||
- **Plugin allowlist:** `plugins.allow` contains `meshcentral-readonly`.
|
||||
- **Tool policy:** `tools.alsoAllow` was set to `["meshcentral-readonly"]` during the prior session (the additive form that survived the existing coding profile).
|
||||
- **Installed artifact vs. merged source:** the running `dist/index.js` is the **pre-PR#3 build** (installed at `2026-09-03T23:34:00Z` UTC). The PR #3 case-insensitive + meshid-filter fix is in the repo source but **has not been rebuilt and reinstalled** in the live Gateway. A rebuild + reinstall is pending — see §2.
|
||||
|
||||
### 1.4 Plugin package (`openclaw-plugin/`)
|
||||
|
||||
- **Manifest (`openclaw.plugin.json`):** declares exactly the four read-only tools — `meshcentral_health`, `meshcentral_list_groups`, `meshcentral_list_devices`, `meshcentral_device_status`.
|
||||
- **Config schema:** requires `url`, `username`, `passwordEnv`, `groupName`, `deviceName`. `additionalProperties: false`. `activation.onStartup: true`.
|
||||
- **Source (`openclaw-plugin/src/meshcentral-readonly.ts`):** implements a single authenticated WSS connection per call, with 750 ms post-open startup delay (to match upstream `meshctrl.js` timing), 1 MB response cap, 30 s timeouts, TLS verification on, and clean connection close in `finally`.
|
||||
- **Target matching:** the `meshes` filter and the device filter are both **case-insensitive** on `groupName` / `deviceName`; the redundant `node.meshid` filter that the chat log mentioned was removed.
|
||||
- **Test surface:** two static safety tests (tool allowlist, fixed-target + env-var password only).
|
||||
|
||||
---
|
||||
|
||||
## 2. Open items (pending, not yet done)
|
||||
|
||||
These are the things the prior session did **not** fully close out, in priority order:
|
||||
|
||||
1. **Live PVE3 status call never confirmed working.** The previous session's chat log ends at `7:35 PM` mid-retry after the Gateway restart. There is no recorded evidence that `meshcentral_device_status` (or any of the four tools) was ever called successfully **through the live OpenClaw Gateway** after PR #3's fix. The standalone bridge path was verified; the Gateway path is unverified in writing.
|
||||
2. **Running plugin artifact is stale relative to merged source.** PR #3 is in the repo but the Gateway's installed `dist/index.js` predates it. A rebuild + reinstall (and a one-time gateway restart) would bring runtime to match source.
|
||||
3. **Stale in-repo documentation.** The following files still describe a much earlier state and contradict reality. They will confuse future-us (and any audit) if left as-is:
|
||||
- `PROJECT-PROGRESS.json` — `status: working`, `lastActivityAt: 2026-08-26`, milestones stop at 2026-09-03 18:25.
|
||||
- `TODO.md` — Build / Live Verification sections are marked complete but do not reflect PR #2 or #3, the plugin package, or the Gateway activation. The "Remaining Deployment/Review Work" section still says "Review the uncommitted diff" — false.
|
||||
- `RESUME-HANDOFF.md` — checkpoint labeled `2026-09-03 18:25 EDT` and the file's own status line says "Local changes are uncommitted and require review before any push or deployment." That is no longer true.
|
||||
4. **No single CHANGELOG / PR history doc** in the repo. Adding one (or refreshing `PROJECT-STATUS-2026-08-25.md` to a current status) would make the project easier to resume later.
|
||||
5. **`story-so-far.md`** has not been updated for PR #2 and #3.
|
||||
6. **Scheduler state:** the `meshcentral-project-progress` cron was paused on Rob's instruction; remains paused. Re-enable only when Rob asks.
|
||||
7. **The chat log's "Exec failed" entries** (e.g. `~/.gitea-staging/meshcentral-openclaw-bridge` inspection, `~/.openclaw/workspace` Gitea token lookup, the runtime plugin cleanup loop) were operational noise during the prior session; they did not result in any untracked file changes that need to be recovered. No data loss from them is suspected, but they are worth knowing about for context.
|
||||
|
||||
---
|
||||
|
||||
## 3. Recommended resume order (when time is available)
|
||||
|
||||
The previous session's plan, refreshed to match actual state:
|
||||
|
||||
1. **Update project docs** (`PROJECT-PROGRESS.json`, `TODO.md`, `RESUME-HANDOFF.md`, optionally `CHANGELOG.md` / `PROJECT-STATUS-2026-09-04.md`) to match reality, push as a docs-only PR. This is purely additive; no live calls, no gateway restart.
|
||||
2. **Rebuild and reinstall the plugin** in the Gateway so the running artifact includes PR #3's case-insensitive + meshid-filter fix. Steps: `cd openclaw-plugin && npm run plugin:build`, then `openclaw plugins install …`, then restart the user Gateway. Confirm the install timestamp moves past the merge.
|
||||
3. **Live verification** — invoke the four tools through the Gateway, starting with `meshcentral_device_status` for `Servers` / `PVE3`. Already inside the approved read-only / PVE3 scope; no new approval needed beyond Rob's standing project-level approval, but explicitly get Rob's go-ahead before connecting.
|
||||
4. **Optional hardening** — capture the verification result, then mark the project `complete` for the read-only MVP and archive the work loop.
|
||||
|
||||
---
|
||||
|
||||
## 4. What I did and did not do today
|
||||
|
||||
- ✅ Read-only inspection of the repo, the live OpenClaw Gateway, the installed plugin, and the Gitea PR list.
|
||||
- ✅ Re-ran the local verification gates (bridge tests/build/lint, plugin build/tests/manifest validation) — all green.
|
||||
- ✅ Wrote this `FINDINGS-2026-09-04.md` and committed it.
|
||||
- ❌ Did **not** call any MeshCentral endpoint.
|
||||
- ❌ Did **not** rebuild, reinstall, or restart the plugin in the live Gateway.
|
||||
- ❌ Did **not** modify `PROJECT-PROGRESS.json`, `TODO.md`, `RESUME-HANDOFF.md`, or any other existing project file beyond adding this note.
|
||||
- ❌ Did **not** enable, re-enable, or modify the paused `meshcentral-project-progress` cron.
|
||||
|
||||
Nothing in the live Gateway or MeshCentral was touched.
|
||||
@@ -68,7 +68,7 @@ export async function inventory(config: PluginConfig): Promise<{ groups: unknown
|
||||
const meshesResponse = await request('meshes');
|
||||
const meshes = (meshesResponse.meshes ?? []).map((mesh) => ({
|
||||
id: mesh.id ?? mesh._id ?? '', name: mesh.name, description: mesh.description ?? mesh.desc,
|
||||
})).filter((mesh) => mesh.id && mesh.name === config.groupName);
|
||||
})).filter((mesh) => mesh.id && mesh.name.toLowerCase() === config.groupName.toLowerCase());
|
||||
if (meshes.length !== 1) throw new Error('Approved MeshCentral group was not found uniquely');
|
||||
|
||||
const group = meshes[0];
|
||||
@@ -77,7 +77,10 @@ export async function inventory(config: PluginConfig): Promise<{ groups: unknown
|
||||
id: node.id ?? node._id ?? '', name: node.name, groupId: node.meshid ?? groupId,
|
||||
online: node.online ?? node.conn === 1, os: node.device?.os ?? node.osdesc,
|
||||
ipAddresses: node.device?.ip ?? node.ip,
|
||||
}))).filter((node) => node.id && node.groupId === group.id && node.name === config.deviceName);
|
||||
// The nodes request is already scoped to the approved group. MeshCentral
|
||||
// may omit or normalize the per-node meshid differently, so do not apply
|
||||
// a second brittle group-id comparison here.
|
||||
}))).filter((node) => node.id && node.name.toLowerCase() === config.deviceName.toLowerCase());
|
||||
return { groups: meshes, devices };
|
||||
} finally {
|
||||
await new Promise<void>((resolve) => {
|
||||
|
||||
Reference in New Issue
Block a user