fix(memory-wiki): route bridge CLI through gateway#72615
Conversation
Greptile SummaryRoutes Confidence Score: 4/5Safe to merge; one minor concern about redundant All changes are well-scoped, have focused regression tests, and the offline fallback path is preserved. The only finding is a P2: extensions/memory-wiki/src/cli.ts — specifically the Prompt To Fix All With AIThis is a comment left during a code review.
Path: extensions/memory-wiki/src/cli.ts
Line: 162-168
Comment:
**`json` flag forwarded to Gateway but also applied locally**
`callWikiGateway` passes `params.json` to `callGatewayFromCli`, then `runWikiStatus`/`runWikiDoctor` still apply their own JSON-vs-render logic to whatever the Gateway returns. The CLI always formats the result locally (lines 287–290, 313–315), so the Gateway never needs to know the `json` preference. If `callGatewayFromCli` ever honours the flag and returns a serialized string instead of a structured object when `json: true`, the subsequent `renderMemoryWikiStatus(status)` call (when `--json` is absent) would receive a string and produce incorrect output. The new tests only cover the `json: true` gateway path, leaving the `json: undefined` / `json: false` gateway path untested.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(memory-wiki): route bridge CLI throu..." | Re-trigger Greptile |
da66702 to
08af363
Compare
08af363 to
9f7be2f
Compare
|
Is there anything else required in this PR to get it merged. Happy to help. |
4c82f9c to
a1d1ce3
Compare
|
Codex review: keeping this open for maintainer follow-up; there is still a little grit to resolve. Keep open. This PR is protected by maintainer signals, and current main still has the Memory Wiki CLI status, doctor, and bridge import paths running local sync instead of the Gateway RPC route proposed here. The PR remains an active implementation candidate for the linked bridge/runtime mismatch reports, carrying forward #67208 and #71479 with related context from #70185. Best possible solution: Keep this PR open for maintainer review. The best path is to review or land the Gateway-routing implementation after addressing the remaining security/review discussion and validating the focused Memory Wiki CLI tests plus the changed gate; current main does not yet solve the intended CLI/runtime context mismatch. What I checked:
Remaining risk / open question:
Codex review notes: model gpt-5.5, reasoning high; reviewed against 5915489631d7. |
705b50b to
33b3fbd
Compare
🔒 Aisle Security AnalysisWe found 2 potential security issue(s) in this PR:
1. 🟡 DoS via unbounded JSON serialization of Gateway responses with extra properties
DescriptionWhen the CLI routes bridge operations through the Gateway ( As a result:
Vulnerable code paths:
Vulnerable snippets: function isMemoryWikiStatus(value: unknown): value is MemoryWikiStatus {
if (!isRecord(value)) {
return false;
}
// ...checks only expected fields...
return (
isBoundedGatewayString(value.vaultMode, GATEWAY_RESPONSE_MAX_CODE_CHARS) &&
// ...
isWarningList(value.warnings)
);
}
function formatGatewayJsonOrText<T>(result: T, json: boolean | undefined, render: (result: T) => string): string {
return json
? escapeGatewayJsonForTerminal(JSON.stringify(result, null, 2))
: sanitizeGatewayStringForTerminal(render(result));
}RecommendationHarden Gateway response handling so unexpected properties cannot balloon serialization cost. Recommended fixes (any combination):
Example (pick/normalize before rendering): function pickMemoryWikiStatus(value: MemoryWikiStatus): MemoryWikiStatus {
return {
vaultMode: value.vaultMode,
renderMode: value.renderMode,
vaultPath: value.vaultPath,
vaultExists: value.vaultExists,
bridgePublicArtifactCount: value.bridgePublicArtifactCount,
bridge: { enabled: value.bridge.enabled },
obsidianCli: {
enabled: value.obsidianCli.enabled,
requested: value.obsidianCli.requested,
available: value.obsidianCli.available,
command: value.obsidianCli.command,
},
unsafeLocal: {
allowPrivateMemoryCoreAccess: value.unsafeLocal.allowPrivateMemoryCoreAccess,
pathCount: value.unsafeLocal.pathCount,
},
pageCounts: value.pageCounts,
sourceCounts: value.sourceCounts,
warnings: value.warnings,
};
}
const validated = validateWikiGatewayResult(method, result);
const normalized = method === "wiki.status" ? pickMemoryWikiStatus(validated) : validated;
return formatGatewayJsonOrText(normalized, json, render);
2. 🟡 TOCTOU symlink race in atomic vault writes can move written file outside vault
Description
Key issues:
This is exploitable in scenarios where the vault directory (or its subdirectories like Vulnerable code: await assertWritablePageDir(params);
const tempPath = path.join(params.pageDir, `.openclaw-wiki-${process.pid}-${randomUUID()}.tmp`);
...
await assertWritablePageDir(params);
await validateDestinationForReplace(params.filePath, params.pagePath);
await fs.rename(tempPath, params.filePath);RecommendationEliminate path-based TOCTOU by anchoring operations to a trusted directory file descriptor and using *at()-style syscalls where available. On POSIX, use a directory FD for the resolved
If Node.js APIs don’t provide safe
Also document/enforce that the vault directory must not be writable by untrusted users/processes if strong containment is required. Analyzed PR: #72615 at commit Last updated on: 2026-04-28T10:24:40Z |
f3ac28c to
b7516b5
Compare
b7516b5 to
e72e350
Compare
|
Maintainer follow-up is done here.
Review notes:
Proof:
Thanks @prasad-yashdeep — nothing else needed from you on this one. |
Summary
wiki status,wiki doctor, andwiki bridge importCLI operations through the Gateway RPC path so they share the runtime memory plugin context.Credit
Based on the Gateway-routing direction from #67208 by @moorsecopers99 and the scoped maintainer draft #71479 by @vincentkoc. Related CLI-metadata capability work in #70185 by @prasad-yashdeep informed the issue analysis.
Validation
pnpm -s vitest run extensions/memory-wiki/src/cli.test.tspnpm check:changedFixes #65722
Fixes #65976
Fixes #66082
Fixes #67979
Fixes #68371
Fixes #68828
Fixes #69019
Fixes #70181
Fixes #70242
Fixes #70842
ProjectClownfish replacement details: