Recovery checklist: unresolved feedback from recent merged PRs
Inventory item count: 77 unresolved review threads.
Generated from GitHub review threads during the 2026-05-11 red-CI/unresolved-feedback recovery incident.
Merge gate
This PR must not merge until all three gates are satisfied:
- All substantive latest-head CI checks are green.
- No unresolved review feedback/items remain.
- No merge conflicts remain.
Verified on PR #1332 head 42571bd993b3d90cd521a1cfdbb84942f5001158: 59/59 status checks successful, zero unresolved review threads, and merge state clean/mergeable.
Admin merge is only a mechanical last resort after those gates are already satisfied; never to bypass red CI, feedback, or conflicts.
Status labels
Each inventory item must end as exactly one of:
FIXED— changed in this PR with file/commit evidence.ALREADY FIXED— already fixed on current main with file/line evidence.OBSOLETE— no longer applicable with evidence.
TODO statuses are not allowed before merge. Applicable items must not be deferred before merge.
Unresolved review feedback inventory — incident window
Repo: markus-lassfolk/openclaw-hybrid-memory Scope: merged/closed PRs updated/closed/merged since 2026-05-10T20:00Z plus #1308. Generated from GitHub reviewThreads; only unresolved threads listed.
PR #1308: fix: resolve 15 critical bugs in stewardship and active-tasks subsystems
- State: CLOSED
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1308
- Unresolved threads: 5 / 5
1308.1 — extensions/memory-hybrid/services/task-ledger-facts.ts:657
- Status: ALREADY FIXED
- Evidence: Current
planActiveTaskHygieneno longer wrapscheckSessionPresent()inPromise.race/unclearedsetTimeout; it awaits the check directly while stale session references are deduplicated first. Evidence:extensions/memory-hybrid/services/task-ledger-facts.tsaround stale session planning. - Thread id:
PRRT_kwDORQuyQM6A7yo6 - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1308#discussion_r3215593998
- Feedback:
Promise.race([checkPromise, timeoutPromise])creates asetTimeoutthat is never cleared whencheckSessionPresent()resolves quickly. Those pending timers can keep the Node.js event loop alive for up to 5s per sessionRef, which is an operational regression during shutdown/CLI runs. Consider using aconst t = setTimeout(...)andclearTimeout(t)in afinally, orAbortSignal.timeout()/timers/promises.setTimeoutwith cancellation so the timer is cleaned up once the check completes.
1308.2 — extensions/memory-hybrid/services/task-ledger-facts.ts:803
- Status: FIXED
- Evidence: Changed
taskEntityKey(entity, key)toJSON.stringify([entity, key]), making entity/key cache keys injective even when inputs contain NULs or literal escape sequences. Evidence:extensions/memory-hybrid/services/task-ledger-facts.ts. - Thread id:
PRRT_kwDORQuyQM6A7yo- - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1308#discussion_r3215594004
- Feedback: The null-byte escaping in
taskEntityKey()is not injective: an input containing the literal sequence\\x00becomes indistinguishable from an input that contained an actual\^@(both end up with\\x00in the serialized key). That means collisions (and incorrect supersede/lookup behavior) are still possible. Use an encoding that guarantees round-tripping (e.g., length-prefix each part, base64/URL-encode each part, or escape\\first and then escape\^@).
1308.3 — extensions/memory-hybrid/services/active-task-checkpoint.ts:411
- Status: ALREADY FIXED
- Evidence:
safeJson()currently only usesJSON.stringify()and falls back to a constant JSON string on failure; it does not callString(value), so throwingtoString/Symbol.toPrimitivecannot break the fallback. Evidence:extensions/memory-hybrid/services/active-task-checkpoint.ts. - Thread id:
PRRT_kwDORQuyQM6A7ypC - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1308#discussion_r3215594009
- Feedback: In
safeJson(), the fallbackString(value)can itself throw ifvalueis an object with a throwingtoString/Symbol.toPrimitive. That would causesafeJsonto unexpectedly throw in the very scenario it is meant to harden. Wrap the preview generation in its own try/catch (and fall back to something likeObject.prototype.toString.call(value)or a constant string) sosafeJsonis guaranteed not to throw.
1308.4 — extensions/memory-hybrid/services/active-task.ts:1067
- Status: ALREADY FIXED
- Evidence: Current
writeActiveTaskFileOptimistic()returnsfalseafter retry exhaustion rather than throwing, and an existing regression test covers exhausted retries. Evidence:extensions/memory-hybrid/services/active-task.tsandextensions/memory-hybrid/tests/active-task.test.ts. - Thread id:
PRRT_kwDORQuyQM6A7ypG - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1308#discussion_r3215594013
- Feedback:
writeActiveTaskFileOptimisticnow throws after exhausting retries, but there is no test covering the new failure mode (previously it performed a last-write-wins fallback). Add a test that forces repeated mtime changes untilmaxRetriesis exceeded and asserts the function throws with a helpful message, so this concurrency behavior doesn’t regress silently.
1308.5 — extensions/memory-hybrid/services/goal-stewardship-heartbeat.ts:56
- Status: ALREADY FIXED
- Evidence: The misleading “immutable cache” comment is not present on current main; matcher cache is described as a module-level regex cache/test-isolation helper. Evidence:
extensions/memory-hybrid/services/goal-stewardship-heartbeat.ts. - Thread id:
PRRT_kwDORQuyQM6A7ypN - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1308#discussion_r3215594020
- Feedback: The comment says “Use immutable cache with Map for thread safety”, but the cache isn’t immutable (the Map is mutated, and callers receive the cached array by reference). This is misleading documentation; consider rewording to describe the actual behavior (memoization keyed by pattern list) and/or freezing/cloning the returned array if immutability is intended.
PR #1311: fix: cross-scope classification mutations and vector cleanup in memory pipelines
- State: MERGED
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1311
- Unresolved threads: 1 / 8
1311.1 — extensions/memory-hybrid/services/vector-search.ts:27
- Status: FIXED
- Evidence: Updated
findSimilarByEmbedding()so omittedoptions.scopekeeps legacy unscoped behaviour; exact scope filtering only applies when scope is explicitly provided. Added regression assertions. Evidence:extensions/memory-hybrid/services/vector-search.ts,extensions/memory-hybrid/tests/fr-008-classification.test.ts. - Thread id:
PRRT_kwDORQuyQM6A71pB - Outdated: False
- Author: chatgpt-codex-connector
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1311#discussion_r3215609558
- Feedback:
Keep embedding similarity unscoped when no scope is provided Defaulting
scopeto"global"here silently changes the behavior of existingFindSimilarByEmbeddingFncallers that still use the old 4/5-argument form (the newoptionsarg is optional inapi/memory-plugin-api.ts), so those callers now stop seeinguser/agent/sessionmemories without any type error. In multi-scope deployments this regresses dedupe/classification quality for non-global flows unless every caller is updated to pass explicit scope options. Useful? React with 👍 / 👎.
PR #1317: Add productization surfaces: doctor flow, session observability CLI, quality reporting, telemetry/sync tooling, and contributor/demo docs
- State: MERGED
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1317
- Unresolved threads: 5 / 5
1317.1 — extensions/memory-hybrid/cli/commands/manage/register-storage-and-stats.ts:2697
- Status: FIXED
- Evidence: Bound
runExportfromManageBindingsinregisterManageStorageAndStats()beforesync-exportinvokes it. Evidence:extensions/memory-hybrid/cli/commands/manage/register-storage-and-stats.ts. - Thread id:
PRRT_kwDORQuyQM6A9o1E - Outdated: False
- Author: chatgpt-codex-connector
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1317#discussion_r3216245142
- Feedback:
Bind the export handler before invoking sync-export
sync-exportcallsrunExport(...), butrunExportis never pulled fromManageBindingsin this module scope, so this path fails immediately (TypeScript reportsTS2304: Cannot find name 'runExport', and runtime would throwReferenceError). As written, users cannot generate any sync bundle at all. Useful? React with 👍 / 👎.
1317.2 — extensions/memory-hybrid/cli/commands/manage/register-storage-and-stats.ts:2698
- Status: FIXED
- Evidence:
sync-exportnow exports to a temporary directory and encrypts a JSON payload containing actual exported files/content, rather than reading the output directory path as a UTF-8 file. Evidence:collectExportBundleFiles()and sync-export implementation inregister-storage-and-stats.ts. - Thread id:
PRRT_kwDORQuyQM6A9o1F - Outdated: False
- Author: chatgpt-codex-connector
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1317#discussion_r3216245144
- Feedback:
Encrypt actual export content instead of export directory path Even after wiring
runExport, this code readsexportResult.outputPathas a UTF-8 file, but the export API returns an output directory root (the same contract used byhybrid-mem export --output <dir>). Reading that path withreadFileSync(..., "utf-8")will hitEISDIR, sosync-exportstill fails before encryption for valid inputs. Useful? React with 👍 / 👎.
1317.3 — extensions/memory-hybrid/cli/verify.ts:225
- Status: FIXED
- Evidence:
doctornow runs install defaults in dry-run/check mode by default; install defaults are applied only when--fixis supplied. Evidence:extensions/memory-hybrid/cli/verify.ts. - Thread id:
PRRT_kwDORQuyQM6A9pXu - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1317#discussion_r3216248411
- Feedback:
doctorcurrently runsrunInstall({ dryRun: dryRunInstall })withdryRunInstalldefaulting to false when neither--fixnor--dry-runare provided, which meansdoctorwill write/apply install defaults by default. That’s surprising given the--fixoption text (“Apply recommended install defaults…”) and can cause unintended config changes. Consider making the default behavior non-mutating (run install in dry-run/check mode unless--fixis set), or rename/reword the option(s) to clearly communicate that install defaults are applied on every run unless--dry-runis used.
1317.4 — extensions/memory-hybrid/cli/commands/manage/register-storage-and-stats.ts:2796
- Status: FIXED
- Evidence: Added strict sync envelope validation before PBKDF2/decryption: schema/type/alg/kdf, bounded iterations, base64 shape, salt/iv/tag byte lengths, and non-empty ciphertext. Evidence:
validateSyncEnvelope()inregister-storage-and-stats.ts. - Thread id:
PRRT_kwDORQuyQM6A9pYI - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1317#discussion_r3216248456
- Feedback:
sync-importusesenvelope.iterationsdirectly inpbkdf2Syncand decodessalt/iv/tag/ciphertextwithout validating types or lengths. A malformed or hostile bundle could set an extremely large iterations value (DoS) or invalid base64/lengths (crash/unclear errors). Add strict runtime validation (schemaVersion/type/kdf, iterations finite and within a sane min/max, iv length 12 bytes, tag length 16 bytes, salt length expected) and fail with a clear error message before attempting PBKDF2/decryption.
1317.5 — extensions/memory-hybrid/cli/benchmark.ts:144
- Status: FIXED
- Evidence: Benchmark quality reports now compute latency averages only from successful latency samples; when all features fail, summary latency is
null/rendered asn/ainstead of misleading 0ms. Added regression test. Evidence:extensions/memory-hybrid/cli/benchmark.ts,extensions/memory-hybrid/tests/benchmark-report.test.ts. - Thread id:
PRRT_kwDORQuyQM6A9pYa - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1317#discussion_r3216248479
- Feedback:
buildBenchmarkQualityReportclamps negative latency values to 0 viaMath.max(0, r.latency.p50)etc. If all benchmark features fail (latency pXX = -1, samples=0), the summary averages will misleadingly report 0ms latency instead of indicating “n/a”/failure. Consider computing summary latency only over successful rows and emittingnull(or a sentinel + explicit flag) when there are no successful measurements, and update markdown rendering accordingly.
PR #1318: Implement 10 strategic enhancements for ecosystem growth and enterprise adoption
- State: MERGED
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318
- Unresolved threads: 35 / 35
1318.1 — extensions/memory-hybrid/routes/dashboard-server.ts:2032
- Status: FIXED
- Evidence: Dashboard request handler is now
async, and full TypeScript parsing/checking succeeds. Evidence:createServer(async (req, res) => ...)indashboard-server.ts;npx tsc --noEmitgreen. - Thread id:
PRRT_kwDORQuyQM6A9pAs - Outdated: False
- Author: chatgpt-codex-connector
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216246289
- Feedback:
Make dashboard request handler async before using await This branch introduces
awaitexpressions inside thecreateServer((req, res) => { ... })callback, which is not markedasync, so the package no longer builds (tsdownreports parse errors at these lines). As written, any CI or local build that includes this file will fail before runtime, blocking release of the plugin. Useful? React with 👍 / 👎.
1318.2 — extensions/memory-hybrid/routes/graphql-resolvers.ts:9
- Status: FIXED
- Evidence: Replaced the broken GraphQL resolver module with an implementation that does not import missing
search-hybrid.js;search/semanticSearchnow use local FactsDB-backed search helpers. Evidence:graphql-resolvers.ts; GraphQL route test passes. - Thread id:
PRRT_kwDORQuyQM6A9pAt - Outdated: False
- Author: chatgpt-codex-connector
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216246290
- Feedback:
Replace unresolved search-hybrid import with existing module The resolver imports
../services/search-hybrid.js, but that module is not present in the repository, so module resolution will fail when this file is bundled or loaded. This breaks GraphQL query handling (search/semanticSearch) once parsing reaches this file. Useful? React with 👍 / 👎.
1318.3 — extensions/memory-hybrid/routes/graphql-resolvers.ts:264
- Status: FIXED
- Evidence: Added resolver coverage for schema-declared link mutations (
createLink,deleteLink) and made still-unimplemented maintenance mutations nullable instead of non-null runtime traps. Evidence:graphql-resolvers.ts,graphql-schema.ts;/graphqlroute test passes. - Thread id:
PRRT_kwDORQuyQM6A9pAu - Outdated: False
- Author: chatgpt-codex-connector
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216246293
- Feedback:
Implement schema-declared mutations in resolver map The
Mutationresolver map only defines fact CRUD/import/prune handlers, while the schema in this same commit declares additional non-null mutations (createLink,deleteLink,consolidateFacts,recomputeEmbeddings). Calling those operations will hit GraphQL’s default resolver and returnnullfor non-null fields, producing runtime errors instead of usable API responses. Useful? React with 👍 / 👎.
1318.4 — extensions/memory-hybrid/api/plugin-system.ts:357
- Status: FIXED
- Evidence: Plugin hooks are now tracked per plugin id and unloading removes only listeners owned by that plugin. Evidence:
pluginEventListenersmap plus targetedunregisterHooks(pluginId)inplugin-system.ts. - Thread id:
PRRT_kwDORQuyQM6A9pAw - Outdated: False
- Author: chatgpt-codex-connector
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216246298
- Feedback:
Preserve other plugins’ hooks when unloading one plugin Unloading a single plugin currently clears every listener list in
eventListeners, so hooks from unrelated still-loaded plugins stop firing after any unload. This causes cross-plugin behavior loss in long-running processes where plugins are dynamically reloaded. Useful? React with 👍 / 👎.
1318.5 — extensions/memory-hybrid/api/plugin-system.ts:9
- Status: FIXED
- Evidence: Removed the invalid
MemoryPluginContextimport frommemory-plugin-api.js; plugin system now uses a local context shape and imports realFactsDBfrom the public backend barrel. Evidence:plugin-system.ts;npx tsc --noEmitgreen. - Thread id:
PRRT_kwDORQuyQM6A9r5S - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216263977
- Feedback:
MemoryPluginContextis imported from../api/memory-plugin-api.js, but that module exportsMemoryPluginAPI(and does not define/exportMemoryPluginContext). This will fail TypeScript builds; either import the correct type (e.g.MemoryPluginAPI) or define/export the intended context type from a dedicated module and update all imports accordingly.
1318.6 — extensions/memory-hybrid/api/plugin-system.ts:358
- Status: FIXED
- Evidence: Duplicate of 1318.4:
unregisterHooks(pluginId)now removes only that plugin’s recorded listener functions and preserves unrelated plugin listeners. - Thread id:
PRRT_kwDORQuyQM6A9r5e - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216263990
- Feedback:
unregisterHooks()currently clears all event listeners for all events, so unloading one plugin will disable event delivery for every other loaded plugin. Track listeners per plugin (e.g., store listener fns in a Map keyed by pluginId) and only remove the listeners belonging to the plugin being unloaded.
1318.7 — extensions/memory-hybrid/api/plugin-system.ts:144
- Status: FIXED
- Evidence: Plugin manager context logger now routes through
pluginLoggerinstead ofconsole.*. Evidence:plugin-system.ts. - Thread id:
PRRT_kwDORQuyQM6A9r5p - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264002
- Feedback: This runtime module uses
console.*for logging (PluginManager’s context logger). The repo’s logger guidance explicitly requires usingpluginLoggerinstead ofconsole.*outside CLI allow-listed paths (seeutils/logger.ts). Usingconsole.*here will likely violate linting and bypass verbosity/log routing; please switch these topluginLogger(or inject the host logger).
1318.8 — extensions/memory-hybrid/services/plugin-loader.ts:10
- Status: FIXED
- Evidence: Removed the invalid
MemoryPluginContextimport from plugin loader; it uses a local context shape and real backend barrel imports. Evidence:plugin-loader.ts;npx tsc --noEmitgreen. - Thread id:
PRRT_kwDORQuyQM6A9r5v - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264008
- Feedback:
MemoryPluginContextis imported from../api/memory-plugin-api.js, but that type isn’t exported there. This will not compile; use the correct exported type (e.g.MemoryPluginAPI) or introduce an explicit context type/module for the plugin loader and update imports accordingly.
1318.9 — extensions/memory-hybrid/services/plugin-loader.ts:74
- Status: FIXED
- Evidence: Plugin loader now converts filesystem plugin paths to
file://URLs viapathToFileURL(pluginPath).hrefbefore dynamic import. Evidence:plugin-loader.ts. - Thread id:
PRRT_kwDORQuyQM6A9r5z - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264013
- Feedback:
import(pluginPath)is called with a filesystem path built viajoin(...). In Node ESM, dynamic import is most reliable with afile://URL (viapathToFileURL(pluginPath).href), and passing arbitrary paths can fail across platforms. Convert the path to a file URL before importing.
1318.10 — extensions/memory-hybrid/routes/graphql-resolvers.ts:14
- Status: FIXED
- Evidence: GraphQL resolver context no longer imports non-existent
MemoryPluginContext; it defines a localGraphQLContextover realFactsDB/VectorDB. Evidence:graphql-resolvers.ts;npx tsc --noEmitgreen. - Thread id:
PRRT_kwDORQuyQM6A9r55 - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264023
- Feedback:
MemoryPluginContextis imported from../api/memory-plugin-api.js, but that module does not export it. This will break compilation; switch to the correct exported type or define/export the intended GraphQL context type from the right module.
1318.11 — extensions/memory-hybrid/routes/graphql-resolvers.ts:47
- Status: FIXED
- Evidence: GraphQL resolvers now use the real FactsDB API (
getById,getAll,delete,store,supersede,createLink) andStoreFactInput-compatible shapes without caller-assigned ids/timestamps. Evidence:graphql-resolvers.ts;/graphqltest passes. - Thread id:
PRRT_kwDORQuyQM6A9r58 - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264026
- Feedback: These resolvers call
factsDb.getFactById()/getAllFacts()/deleteFact(), but the actual FactsDB API isgetById()/ query helpers /delete()(andstore()expectsStoreFactInputwithoutid/createdAt). As written, this GraphQL layer won’t compile or work against the existing backend; update resolvers to use the real FactsDB methods and data shapes (e.g.factsDb.getById(id),factsDb.searchFacts(...)/listForDashboard(...), andfactsDb.store({ text, category, ... })letting the DB assign ids/timestamps).
1318.12 — extensions/memory-hybrid/routes/graphql-resolvers.ts:431
- Status: FIXED
- Evidence: Corrected supersession relationship resolvers to use
supersedesIdforsupersedesandsupersededByforsupersededByFact. Evidence:graphql-resolvers.ts. - Thread id:
PRRT_kwDORQuyQM6A9r6C - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264033
- Feedback:
supersedes/supersededByFactappear swapped:supersedesreturns the fact referenced byparent.supersededBy, which is the fact that supersedes the parent (i.e. “superseded by”), whilesupersededByFactsearches for a fact whosesupersededBy === parent.id, which is the fact that the parent supersedes. Swap these resolver implementations (or rename fields) to match their semantics.
1318.13 — extensions/memory-hybrid/routes/graphql-schema.ts:235
- Status: FIXED
- Evidence: Implemented/normalized root link resolvers and mutations, and relaxed still-unimplemented maintenance mutations to nullable schema fields so GraphQL no longer returns null for non-null fields. Evidence:
graphql-resolvers.ts,graphql-schema.ts. - Thread id:
PRRT_kwDORQuyQM6A9r6I - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264041
- Feedback: The schema declares non-null root fields (
episode,episodes,link, manyMutations likecreateLink,deleteLink,consolidateFacts,recomputeEmbeddings) that do not have resolvers implemented ingraphql-resolvers.ts. Querying any of these will resolve tonull/undefinedand can trigger runtime GraphQL errors (especially for...!fields). Either implement the missing resolvers or remove/mark nullable the fields until supported.
1318.14 — extensions/memory-hybrid/routes/graphql-server.ts:193
- Status: FIXED
- Evidence: GraphQL Yoga CORS no longer combines wildcard origin with credentials;
credentialsis false for the wildcard dashboard GraphQL endpoint. Evidence:graphql-server.ts. - Thread id:
PRRT_kwDORQuyQM6A9r6L - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264047
- Feedback: CORS is configured with
origin: "*"whilecredentials: true. Browsers will rejectAccess-Control-Allow-Origin: *when credentials are allowed, and it’s also unsafe for authenticated endpoints. Restrictoriginto a concrete allow-list (or echo validated origins) and only enable credentials when needed.
1318.15 — extensions/memory-hybrid/routes/graphql-server.ts:202
- Status: FIXED
- Evidence: GraphQL Yoga logging hooks now route through
pluginLoggerinstead ofconsole.*. Evidence:graphql-server.ts. - Thread id:
PRRT_kwDORQuyQM6A9r6O - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264052
- Feedback: This runtime route module logs via
console.*in the Yogalogginghooks. The repo’s logger guidance requires usingpluginLoggerinstead ofconsole.*outside CLI allow-listed paths (utils/logger.ts). Switch these topluginLogger.{debug,info,warn,error}so verbosity/log routing behaves consistently and lint rules pass.
1318.16 — extensions/memory-hybrid/routes/dashboard-server.ts:2065
- Status: FIXED
- Evidence:
/graphqlnow uses the sharedreadJsonBody(req, MAX_DASHBOARD_JSON_BODY_BYTES)helper and returns 413 on oversized bodies. Evidence:dashboard-server.ts; added dashboard test for oversized/graphqlbody. - Thread id:
PRRT_kwDORQuyQM6A9r6U - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264062
- Feedback: The
/graphqlhandler reads the request body with an unbounded string concatenation loop. This bypasses the existingreadJsonBody(..., MAX_DASHBOARD_JSON_BODY_BYTES)protections used elsewhere and allows a large body to consume memory (DoS risk). ReusereadJsonBodywith the existing size limit (or stream with backpressure) and return413on oversize payloads.
1318.17 — extensions/memory-hybrid/routes/dashboard-server.ts:2047
- Status: FIXED
- Evidence: Dashboard server now creates the GraphQL Yoga server once during dashboard startup and reuses it for
/graphqlrequests. Evidence:dashboard-server.ts. - Thread id:
PRRT_kwDORQuyQM6A9r6a - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264068
- Feedback:
createGraphQLServer(...)is instantiated on every/graphqlrequest. Creating Yoga (schema + plugins + PubSub) per request is unnecessary overhead and can become a scalability bottleneck. Create the Yoga server once when the dashboard server starts (and reuse the same instance) instead of rebuilding it on each request.
1318.18 — extensions/memory-hybrid/routes/dashboard-server.ts:2047
- Status: FIXED
- Evidence: Removed the
as anyrequest-context coercion; dashboard builds a concrete context object and uses typedHeadersfor Yoga fetch. Evidence:dashboard-server.ts;npx tsc --noEmitgreen. - Thread id:
PRRT_kwDORQuyQM6A9r6f - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264075
- Feedback: This block uses
as anyto coerce the object passed aspluginContext. In strict TypeScript this hides mismatches (andMemoryPluginContextisn’t actually defined/exported in the referenced module). Define a correct context type (or use an existing exported API type) and build an object that actually satisfies it so GraphQL resolvers can safely rely on typed fields withoutanycasts.
1318.19 — extensions/memory-hybrid/routes/dashboard-server.ts:2066
- Status: FIXED
- Evidence: Added dashboard tests for
GET /graph, validPOST /graphql, and oversized/graphqlrequest handling. Evidence:dashboard-server.test.ts; focused test run reports 5 files / 190 tests passed. - Thread id:
PRRT_kwDORQuyQM6A9r6o - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264085
- Feedback:
createDashboardServerhas an existing test suite, but the newly added/graphand/graphqlroutes aren’t covered. Add tests that (1) GET/graphreturns HTML and (2) POST/graphqlreturns a valid GraphQL response (and enforces the same body-size limits/error handling as other endpoints).
1318.20 — extensions/memory-hybrid/services/memory-compression.ts:75
- Status: FIXED
- Evidence: Memory compression runtime module no longer uses
console.log; prior compile batch removed runtime console progress logging. Evidence: noconsole.*inmemory-compression.ts;npx tsc --noEmitgreen. - Thread id:
PRRT_kwDORQuyQM6A9r60 - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264098
- Feedback: This service uses
console.log(...)in a runtime module. The repo logger guidelines require usingpluginLoggerinstead ofconsole.*outside CLI allow-listed paths (utils/logger.ts). Replace these withpluginLogger.*to avoid lint failures and to respect verbosity/log routing.
1318.21 — extensions/memory-hybrid/services/memory-compression.ts:88
- Status: FIXED
- Evidence: Memory compression now uses real FactsDB methods (
getAll,getById,store,supersede) and stores summary facts with DB-assigned ids/timestamps and valid input shape. Evidence:memory-compression.ts;npx tsc --noEmitgreen. - Thread id:
PRRT_kwDORQuyQM6A9r68 - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264107
- Feedback:
FactsDBdoes not exposegetAllFacts()(orgetFactById()), andFactsDB.store()expects aStoreFactInputshape withoutid/createdAt(those are assigned by the DB). As written, this service won’t compile/work with the existing backend; refactor to use supported FactsDB query APIs (e.g.searchFacts/listForDashboard/getFactsForConsolidation) and store summaries viafactsDb.store({ text, category, ... })without pre-assigning ids/timestamps.
1318.22 — extensions/memory-hybrid/services/memory-compression.ts:243
- Status: FIXED
- Evidence: Removed random placeholder embeddings from compression clustering; until real persisted vector retrieval is wired, compression uses deterministic category clustering instead. Evidence:
clusterFacts()inmemory-compression.ts. - Thread id:
PRRT_kwDORQuyQM6A9r7F - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264119
- Feedback: This uses placeholder/random embeddings (
generateRandomEmbedding) instead of reading real vectors fromVectorDB. That makes clustering non-deterministic and effectively meaningless, and it will produce different clusters on every run. Either wire this to the actual embedding storage/search APIs (preferred) or remove the vector-based path and only expose the category/time-window fallback until embeddings are implemented.
1318.23 — extensions/memory-hybrid/services/benchmark-suite.ts:61
- Status: FIXED
- Evidence: Benchmark runtime module no longer uses
console.logprogress output. Evidence: noconsole.*inbenchmark-suite.ts;npx tsc --noEmitgreen. - Thread id:
PRRT_kwDORQuyQM6A9r7R - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264131
- Feedback: This runtime module uses
console.log(...)for progress output. Perutils/logger.ts, non-CLI runtime code should usepluginLoggerrather thanconsole.*so logs respect verbosity and lint rules. Replace these withpluginLogger.info/debug(or accept an injected logger).
1318.24 — extensions/memory-hybrid/services/benchmark-suite.ts:130
- Status: FIXED
- Evidence: Benchmark suite now uses real FactsDB APIs (
getAll,getById,store) and valid store input shapes instead of non-existentgetAllFacts/getFactById. Evidence:benchmark-suite.ts;npx tsc --noEmitgreen. - Thread id:
PRRT_kwDORQuyQM6A9r7X - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264137
- Feedback:
FactsDBdoes not providegetAllFacts()/getFactById(). The benchmark implementation currently depends on those methods (and uses placeholdersetTimeoutcalls for vector/hybrid search), so it won’t compile or measure real system performance. Update it to use the actual FactsDB APIs (e.g.searchFacts,lookupFacts,getById, etc.) and real vector/hybrid search entrypoints so the benchmark reflects real behavior.
1318.25 — extensions/memory-hybrid/services/collaboration.ts:7
- Status: FIXED
- Evidence: Collaboration service no longer imports
better-sqlite3; it uses Node’snode:sqliteDatabaseSyncviacreateRequire. Evidence:collaboration.ts;npx tsc --noEmitgreen. - Thread id:
PRRT_kwDORQuyQM6A9r7l - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264154
- Feedback: This service imports/uses
better-sqlite3, but the codebase has migrated tonode:sqlite(and tests explicitly assert postinstall does not referencebetter-sqlite3).better-sqlite3is not a dependency of this package, so this will fail to build/run. Usenode:sqlite’sDatabaseSync(consistent with the rest of the repo) or add a separate optional package with clear build steps.
1318.26 — extensions/memory-hybrid/services/collaboration.ts:6
- Status: FIXED
- Evidence: Removed/avoided the unused
FactsDBimport in collaboration service; file compiles cleanly. Evidence:collaboration.ts;npx tsc --noEmitgreen. - Thread id:
PRRT_kwDORQuyQM6A9r7v - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264166
- Feedback:
FactsDBis imported but never used in this file. With typical TS/biome settings this will fail lint/typecheck; remove the unused import or use it as intended.
1318.27 — extensions/memory-hybrid/cli/plugin-commands.ts:43
- Status: FIXED
- Evidence: Plugin manifest loading now reads
package.jsonviareadFile+JSON.parseinstead of brittle JSON dynamic import attributes. Evidence:plugin-commands.ts. - Thread id:
PRRT_kwDORQuyQM6A9r77 - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264180
- Feedback:
listPluginsusesimport(manifestPath, { assert: { type: "json" } })with a filesystem path. Node’s import-attributes support useswith: { type: "json" }(and dynamic import of absolute paths is brittle), so this is likely to throw at runtime. Prefer readingpackage.jsonviafs.readFile+JSON.parse, or convertmanifestPathto afile://URL and use the correct import-attributes syntax.
1318.28 — extensions/memory-hybrid/cli/plugin-commands.ts:81
- Status: FIXED
- Evidence: Plugin loader now scans both direct plugin directories and
<pluginsDir>/node_modules(including scoped packages), aligning withnpm install --prefix <pluginsDir>. Evidence:plugin-loader.ts. - Thread id:
PRRT_kwDORQuyQM6A9r8G - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264193
- Feedback:
installPlugin(..., { npm: true })runsnpm install ... --prefix <pluginsDir>, which installs into<pluginsDir>/node_modules/<pkg>. However,PluginLoaderscans<pluginsDir>/*/index.js, so npm-installed plugins will not be discoverable/enableable with the current directory layout. Align the installer and loader (e.g., install into a per-plugin directory or have the loader scannode_modules), otherwiseplugin install --npmwill appear to succeed but nothing will load.
1318.29 — extensions/memory-hybrid/cli/plugin-commands.ts:79
- Status: FIXED
- Evidence: Removed runtime
execadependency by usingnode:child_process.spawnfor npm install. Evidence:plugin-commands.ts. - Thread id:
PRRT_kwDORQuyQM6A9r8T - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264206
- Feedback:
installPlugindynamically importsexeca, butexecais not listed inextensions/memory-hybrid/package.jsondependencies/devDependencies. This will fail at runtime in a clean install. Either addexecaas a dependency or replace it withnode:child_process(spawn/execFile) to avoid the extra dep.
1318.30 — sdk/openclaw-memory-js/package.json:53
- Status: FIXED
- Evidence: Removed unused
graphql-requestdependency from the SDK package because the SDK usesfetchdirectly. Evidence:sdk/openclaw-memory-js/package.json. - Thread id:
PRRT_kwDORQuyQM6A9r8X - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264213
- Feedback:
graphql-requestis declared as a dependency but the SDK implementation usesfetchdirectly and never imports/usesgraphql-request. Either remove the unused dependency to keep the package lean, or refactor the SDK to usegraphql-requestconsistently.
1318.31 — sdk/openclaw-memory-js/src/index.ts:137
- Status: FIXED
- Evidence: Removed unused
restPathconfig/property/constructor assignment from SDK client. Evidence:sdk/openclaw-memory-js/src/index.tsand README config table updated. - Thread id:
PRRT_kwDORQuyQM6A9r8c - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264221
- Feedback:
restPathis stored on the client (private restPathand constructor assignment) but never used by any method. With common TS settings (noUnusedLocals/noUnusedParameters) this can fail builds and it’s confusing API surface. Either implement REST-based methods that userestPathor remove it until needed.
1318.32 — sdk/openclaw-memory-js/README.md:91
- Status: FIXED
- Evidence: Removed unsupported
minImportancefrom the SDK READMEgetFacts()example. Importance filtering remains documented undersearch(), where it is supported. Evidence:sdk/openclaw-memory-js/README.md. - Thread id:
PRRT_kwDORQuyQM6A9r8g - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264226
- Feedback: The
getFactsexample includesminImportance, butMemoryClient.getFacts()options (and the underlying GraphQLfactsquery) do not supportminImportance. This makes the README example incorrect/misleading; removeminImportancefrom the example or add support for it end-to-end.
1318.33 — docs/tutorials/HYBRID-MEMORY-101.md:320
- Status: FIXED
- Evidence: Updated tutorial filtered
getFacts()example to use supported category/tag filters only, and clarified importance filtering belongs withsearch(). Evidence:docs/tutorials/HYBRID-MEMORY-101.md. - Thread id:
PRRT_kwDORQuyQM6A9r8k - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264234
- Feedback: This tutorial uses
client.getFacts({ ..., minImportance: 0.7 }), but the SDK’sgetFactsmethod does not acceptminImportance(and the GraphQLfactsquery doesn’t define it). Update the tutorial to match the actual API, or addminImportancesupport across GraphQL schema/resolvers + SDK.
1318.34 — docs/IMPLEMENTATION-SUMMARY.md:529
- Status: FIXED
- Evidence: Softened implementation summary claims: GraphQL/collaboration/plugin work is described as foundations/incremental, not “fully implemented and operational”/complete. Evidence:
docs/IMPLEMENTATION-SUMMARY.md. - Thread id:
PRRT_kwDORQuyQM6A9r8r - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264244
- Feedback: This doc claims the GraphQL layer is “fully implemented and operational” (and elsewhere calls it “complete”), but the code currently contains multiple TODOs/placeholders (e.g. random embeddings in compression, benchmark stubs) and the GraphQL schema includes many fields without resolvers. Please adjust the claims to reflect current implementation status, or complete the missing pieces before describing them as operational.
1318.35 — docs/PLUGIN-DEVELOPMENT.md:46
- Status: FIXED
- Evidence: Removed the broken self-link to
../docs/PLUGIN-DEVELOPMENT.mdfrom withindocs/PLUGIN-DEVELOPMENT.md; the doc now points readers to the current guide content. Evidence:docs/PLUGIN-DEVELOPMENT.md. - Thread id:
PRRT_kwDORQuyQM6A9r8w - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1318#discussion_r3216264251
- Feedback: The link
See the [Plugin Development Guide](../docs/PLUGIN-DEVELOPMENT.md)points todocs/docs/PLUGIN-DEVELOPMENT.mdfrom withindocs/PLUGIN-DEVELOPMENT.md, which is incorrect/broken. Link to./PLUGIN-DEVELOPMENT.md(self) or to the intended separate guide file.
PR #1320: feat: add user-friendly CLI commands and comprehensive quick-start guide
- State: MERGED
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320
- Unresolved threads: 25 / 25
1320.1 — extensions/memory-hybrid/cli/cmd-setup.ts:127
- Status: FIXED
- Evidence: Setup wizard now persists selected provider/model/API-key updates by calling the injected
runConfigSetwriter for each config key. Evidence:registerSetupCommand(..., runConfigSet)incmd-setup.ts;user-friendly-cli.test.tsverifies writes occur. - Thread id:
PRRT_kwDORQuyQM6A9qM_ - Outdated: False
- Author: chatgpt-codex-connector
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216253962
- Feedback:
Persist setup selections to plugin configuration The setup wizard reports that it is “applying configuration”, but this block only prints key/value pairs and never calls any config writer or
config-sethandler; the inline note explicitly says real persistence is missing. In practice,openclaw hybrid-mem setup --interactivecan end with a success message while leaving provider/model/API key unchanged, so users still fail later commands expecting the new setup to be active. Useful? React with 👍 / 👎.
1320.2 — extensions/memory-hybrid/cli/cmd-setup.ts:43
- Status: FIXED
- Evidence:
--interactiveno longer defaults to true, so non-interactive setup is reachable by default. Evidence:cmd-setup.ts; test verifies no default value on the--interactiveoption and non-interactive action runs. - Thread id:
PRRT_kwDORQuyQM6A9qND - Outdated: False
- Author: chatgpt-codex-connector
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216253967
- Feedback:
Make –interactive actually optional With Commander, defining
.option("--interactive", ..., true)makesinteractivetrue even when the flag is omitted and does not provide--no-interactive, so the non-interactive branch below is unreachable. This means setup always prompts on stdin, which breaks scripted/CI usage and contradicts the presence of explicit non-interactive logic in the command. Useful? React with 👍 / 👎.
1320.3 — extensions/memory-hybrid/utils/provider-detection.ts:41
- Status: FIXED
- Evidence: ONNX detection now uses
createRequire(import.meta.url).resolve(...), which works in ESM. Evidence:provider-detection.ts; provider helper tests pass. - Thread id:
PRRT_kwDORQuyQM6A9qzh - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216257864
- Feedback:
checkOnnxAvailable()usesrequire.resolve(...)inside an ES module. At runtimerequireis not defined (unless created viacreateRequire), so this will throw and incorrectly report ONNX as unavailable. UsecreateRequire(import.meta.url).resolve(...), or make this check async andawait import("onnxruntime-node")in a try/catch to detect availability.
1320.4 — extensions/memory-hybrid/utils/provider-detection.ts:7
- Status: FIXED
- Evidence: Removed unused
execSync/existsSyncimports from provider detection. Evidence:provider-detection.ts;npx tsc --noEmitgreen. - Thread id:
PRRT_kwDORQuyQM6A9qzy - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216257887
- Feedback:
execSyncandexistsSyncare imported but never used in this module. Please remove them to avoid dead code and keep the provider detection logic focused.
1320.5 — extensions/memory-hybrid/utils/provider-detection.ts:15
- Status: FIXED
- Evidence: Provider detection/status now includes
googleand reports configured when a Google/Gemini API key is present. Evidence:ProviderStatus.providerincludes google;detectAvailableProviders(..., googleApiKey); test verifies GOOGLE status. - Thread id:
PRRT_kwDORQuyQM6A9qz8 - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216257903
- Feedback: The embedding config supports provider
"google"(see EmbeddingConfig), but provider detection/status only handles openai/ollama/onnx. If a user is configured for google,providers/doctor/healthwill misreport it as “not configured/unavailable”. Consider adding google toProviderStatus.providerand implementing acheckGoogleConfigured(...)similar to OpenAI (or at least treat it as configured when an API key is present).
1320.6 — extensions/memory-hybrid/utils/progress-indicators.ts:86
- Status: FIXED
- Evidence: ProgressBar non-TTY mode now uses a
lastLoggedPercentmilestone guard and a safe total to avoid duplicate logs/division-by-zero. Evidence:progress-indicators.ts; test verifies duplicate 10% logs are suppressed. - Thread id:
PRRT_kwDORQuyQM6A9q0J - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216257918
- Feedback:
ProgressBar.update()in non-TTY mode logs wheneverpercent % 10 === 0, which can print the same percentage many times ifupdate()is called frequently. The codebase already uses milestone logging with alastPctguard (e.g. 25/50/75/100) to avoid log spam. Track the last logged percentage (and consider milestone steps + atotal <= 0guard) to prevent duplicate logs and division-by-zero whentotalis 0.
1320.7 — extensions/memory-hybrid/utils/error-codes.ts:153
- Status: FIXED
- Evidence: Timeout-like errors now map to HM_E008 before provider-unavailable matching. Evidence:
wrapCommonError()inerror-codes.ts; test verifies timeout maps to HM_E008. - Thread id:
PRRT_kwDORQuyQM6A9q0U - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216257935
- Feedback:
wrapCommonError()treats timeouts as provider-unavailable (HM_E003) because it matcheslowerMsg.includes("timeout"), but the catalog defines HM_E008 specifically for operation timeouts. This will surface the wrong title/solution for genuine timeouts. Prefer mapping timeout-ish messages to HM_E008 (and keep HM_E003 for connection/refused/notfound cases).
1320.8 — extensions/memory-hybrid/utils/error-codes.ts:35
- Status: FIXED
- Evidence: Updated user-friendly error docs links to stable repo docs (
docs/LLM-AND-PROVIDERS.md,docs/CONFIGURATION.md,docs/TROUBLESHOOTING.md) instead of missing README anchors. Evidence:error-codes.ts. - Thread id:
PRRT_kwDORQuyQM6A9q0g - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216257948
- Feedback: Several
docsLinkURLs point at README anchors that don’t exist (e.g.#embedding-providers). This makes the “More info” link inUserFriendlyError.format()misleading. Please update these links to stable docs that exist in this repo (e.g.docs/LLM-AND-PROVIDERS.md,docs/TROUBLESHOOTING.md, etc.).
1320.9 — extensions/memory-hybrid/docs/QUICK-START.md:253
- Status: FIXED
- Evidence: Quick Start Learn More links now point from
extensions/memory-hybrid/docs/to existing root docs via../../../docs/.... Evidence:extensions/memory-hybrid/docs/QUICK-START.md. - Thread id:
PRRT_kwDORQuyQM6A9q0p - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216257962
- Feedback: These “Learn More” references point to
docs/CLI-REFERENCE.md,docs/CONFIGURATION.md, anddocs/ARCHITECTURE.mdrelative toextensions/memory-hybrid/docs/, but those files don’t exist in this folder (they live under the repo rootdocs/). Use correct relative links (e.g.../../docs/CLI-REFERENCE.md) or absolute repo links so GitHub navigation works.
1320.10 — extensions/memory-hybrid/docs/QUICK-START.md:53
- Status: FIXED
- Evidence: ONNX quick-start install command now uses
npm install --prefix ~/.openclaw/extensions/openclaw-hybrid-memory onnxruntime-node, matching extension persistence guidance. Evidence:QUICK-START.md. - Thread id:
PRRT_kwDORQuyQM6A9q0r - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216257966
- Feedback: ONNX setup here suggests
npm install onnxruntime-nodewithout the--prefix ~/.openclaw/extensions ...guidance used elsewhere in the repo. As documented inextensions/memory-hybrid/README.md, installing into the OpenClaw extensions folder is important so the dependency survivesopenclaw hybrid-mem upgrade. Please align these instructions with the README’s recommended installation method.
1320.11 — extensions/memory-hybrid/cli/register.ts:463
- Status: FIXED
- Evidence: User-friendly command modules now accept the local
Chainableabstraction andregisterHybridMemClino longer castsmem as any. Evidence:cmd-user-friendly.ts, user-friendly command modules,register.ts. - Thread id:
PRRT_kwDORQuyQM6A9q0v - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216257973
- Feedback:
registerUserFriendlyCommands(mem as any, ...)is needed because the user-friendly command modules are typed against CommanderCommand, while the rest of the CLI uses the localChainableabstraction. To avoidanyand keep type safety consistent, updatecmd-user-friendly.ts(and the new command modules) to acceptChainablefromcli/shared.ts(only using the subset of Commander APIs the CLI supports).
1320.12 — extensions/memory-hybrid/cli/register.ts:470
- Status: FIXED
- Evidence: Added focused registration tests verifying setup/demo/providers/health/doctor/examples are registered on the command tree and help-only registration stays lightweight. Evidence:
tests/user-friendly-cli.test.ts. - Thread id:
PRRT_kwDORQuyQM6A9q0y - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216257978
- Feedback: New CLI surface area is being registered here, but there are no accompanying tests verifying that these commands are registered and don’t hang the CLI (the repo already has CLI registration tests like
active-task.test.ts). Add tests that assertsetup/demo/providers/health/doctor/examplesare present on the command tree and that help-only registration still avoids DB/bootstrap side effects.
1320.13 — extensions/memory-hybrid/cli/cmd-user-friendly.ts:35
- Status: FIXED
- Evidence:
cmd-user-friendly.tsnow typesmemasChainableinstead of CommanderCommand. Evidence:cmd-user-friendly.ts. - Thread id:
PRRT_kwDORQuyQM6A9q04 - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216257988
- Feedback: This module types
memas CommanderCommand, butregisterHybridMemClipasses aChainable(and currently must cast withas any). To match the rest of the CLI modules, consider switching these registrations to acceptChainablefromcli/shared.ts. This removes the need for unsafe casts and ensures the command modules stay compatible with the CLI’s abstraction layer.
1320.14 — extensions/memory-hybrid/cli/cmd-setup.ts:15
- Status: FIXED
- Evidence: Removed unused Node imports from setup command. Evidence:
cmd-setup.ts;npx tsc --noEmitgreen. - Thread id:
PRRT_kwDORQuyQM6A9q1A - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216257998
- Feedback: Several Node imports here (
readFileSync,writeFileSync,homedir,join) are unused in the current implementation. Please remove them to avoid dead code and reduce confusion about whether the wizard persists anything to disk.
1320.15 — extensions/memory-hybrid/cli/cmd-setup.ts:128
- Status: FIXED
- Evidence: Duplicate of 1320.1: setup now genuinely applies configuration through
runConfigSetand errors if no config writer is available. Evidence:cmd-setup.ts; test verifies persisted writes. - Thread id:
PRRT_kwDORQuyQM6A9q1K - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216258011
- Feedback: The wizard claims to be “Applying configuration”, but it never actually writes anything (it only logs key/value pairs and even notes “In real implementation…”). This is a functional gap vs the command description/PR description. Please wire this to the existing config machinery (e.g. call the
config-sethandler /runConfigSet, or persist updates via the config service) sosetup --interactivegenuinely updates the plugin config.
1320.16 — extensions/memory-hybrid/cli/cmd-setup.ts:100
- Status: FIXED
- Evidence: OpenAI/Google API key prompts now use hidden input (
promptHidden) so secrets are not echoed in interactive setup. Evidence:cmd-setup.ts. - Thread id:
PRRT_kwDORQuyQM6A9q1R - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216258018
- Feedback: The OpenAI API key prompt uses
readline.question, which echoes the secret as the user types. For a setup wizard, this is risky in shared terminals/screen recordings. Use a masked/hidden input method for secrets (or instruct users to setembedding.apiKeyviaconfig-set/env vars instead of typing it interactively).
1320.17 — extensions/memory-hybrid/cli/cmd-setup.ts:87
- Status: FIXED
- Evidence:
configUpdatesis nowRecord<string, string>and secret values are hidden in display output. Evidence:cmd-setup.ts. - Thread id:
PRRT_kwDORQuyQM6A9q1g - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216258040
- Feedback:
configUpdatesis declared asRecord<string, any>, losing type safety for config keys/values. Since this code is user-facing config, it’s worth keeping types tight. PreferRecord<string, string>(all values are printed as strings here) or a typed map of known keys to avoid accidentally emitting non-serializable values.
1320.18 — extensions/memory-hybrid/cli/cmd-providers.ts:24
- Status: FIXED
- Evidence:
providersasync action is wrapped withwithExit(...)for consistent CLI error/teardown handling. Evidence:cmd-providers.ts. - Thread id:
PRRT_kwDORQuyQM6A9q1p - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216258053
- Feedback: This command runs an async
.action(...)without using the repo’swithExit(...)helper. Many existing CLI modules rely onwithExitfor consistent error capture and to ensure the process exits/tears down cleanly. Consider wrapping the action withwithExit(fromcli/shared.ts) and letting errors throw so teardown/error reporting stays consistent.
1320.19 — extensions/memory-hybrid/cli/cmd-health.ts:116
- Status: FIXED
- Evidence:
healthnow computesfactCountand expensivevectorDb.getAllIds()once and reuses those counts for Memory Size and Sync checks. Evidence:cmd-health.ts; test verifies onegetAllIdscall. - Thread id:
PRRT_kwDORQuyQM6A9q1r - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216258066
- Feedback:
healthrecomputesfactsDb.countFacts()and callsvectorDb.getAllIds()multiple times.getAllIds()can be expensive on large vector stores; doing it twice per invocation is unnecessary. FetchfactCount/vectorCountonce and reuse for Memory Size + Sync checks (or add a cheapercountVectors()API if available).
1320.20 — extensions/memory-hybrid/cli/cmd-examples.ts:149
- Status: FIXED
- Evidence: Examples command now uses
Object.hasOwn(EXAMPLE_CATEGORIES, category)before indexing. Evidence:cmd-examples.ts; test verifiestoStringdoes not crash. - Thread id:
PRRT_kwDORQuyQM6A9q1y - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216258076
- Feedback: Using
category in EXAMPLE_CATEGORIESchecks the prototype chain too. Inputs likeexamples toStringwill pass the check and thenEXAMPLE_CATEGORIES["toString"]is not a valid category object, which can crash or print nonsense. Use an own-property check (e.g.Object.hasOwn(...)/hasOwnProperty.call(...)) before indexing.
1320.21 — extensions/memory-hybrid/cli/cmd-doctor.ts:5
- Status: FIXED
- Evidence: Removed unused
statSyncimport; doctor now importsstatfsSyncfor real disk-space checking. Evidence:cmd-doctor.ts. - Thread id:
PRRT_kwDORQuyQM6A9q13 - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216258084
- Feedback:
statSyncis imported but never used in this file. Please remove it to avoid dead code.
1320.22 — extensions/memory-hybrid/cli/cmd-doctor.ts:31
- Status: FIXED
- Evidence: Removed misleading unsupported
--fixoption from doctor rather than advertising remediation it does not perform. Evidence:cmd-doctor.ts. - Thread id:
PRRT_kwDORQuyQM6A9q18 - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216258093
- Feedback: The command defines a
--fixoption, butopts.fixis never used. This makes the CLI misleading (users expect some remediation behavior). Either implement--fix(e.g. run the suggested fix commands / call existing verify/reconcile flows) or remove the option until it’s supported.
1320.23 — extensions/memory-hybrid/cli/cmd-doctor.ts:148
- Status: FIXED
- Evidence: Doctor no longer uses CommonJS
requireinside ESM; it importshomedir/joinat top level. Evidence:cmd-doctor.ts. - Thread id:
PRRT_kwDORQuyQM6A9q2A - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216258098
- Feedback: This “Disk Space” check uses
require("node:path")/require("node:os")inside an ES module. At runtimerequirewill be undefined, causing the diagnostics command to crash. Use top-level ESM imports (import { homedir } from "node:os"; import { join } from "node:path";) orcreateRequire(import.meta.url)if you truly needrequire.
1320.24 — extensions/memory-hybrid/cli/cmd-doctor.ts:161
- Status: FIXED
- Evidence: Doctor Disk Space check now uses
statfsSyncto report available MiB and warns below threshold instead of merely checking directory existence. Evidence:cmd-doctor.ts. - Thread id:
PRRT_kwDORQuyQM6A9q2H - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216258110
- Feedback: The check is labeled “Disk Space”, but it only verifies that the memory directory exists/access is possible. This doesn’t actually validate free space, which the PR description mentions. Either rename the check to reflect what it does (directory accessibility) or implement a real free-space check (e.g. via
statvfs-style approach or a platform-appropriate utility) and warn/fail below a threshold.
1320.25 — extensions/memory-hybrid/cli/cmd-demo.ts:37
- Status: FIXED
- Evidence: Demo displays
embeddings.activeProvider ?? embeddings.modelNameinstead of a non-existent provider property. Evidence:cmd-demo.ts. - Thread id:
PRRT_kwDORQuyQM6A9q2M - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1320#discussion_r3216258120
- Feedback:
EmbeddingProviderdoesn’t have aproviderproperty (it exposesactiveProvider,modelName, etc.). This line will fail TypeScript checking and/or always print the wrong value. Useembeddings.activeProvider(orcfg.embedding.providerif you want configured provider) when displaying provider status.
PR #1323: Harden Active Tasks + Goal Stewardship state handling, signal trust, and heartbeat safety
- State: MERGED
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1323
- Unresolved threads: 6 / 6
1323.1 — extensions/memory-hybrid/services/goal-registry.ts:180
- Status: FIXED
- Evidence: Goal registry scans now isolate corrupt goal files:
listGoals()skips unreadable JSON instead of aborting the whole registry listing. Evidence:goal-registry.ts; added registry test for healthy+corrupt coexistence. - Thread id:
PRRT_kwDORQuyQM6A-HhK - Outdated: False
- Author: chatgpt-codex-connector
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1323#discussion_r3216414656
- Feedback:
Prevent corrupt goal file from aborting all goal processing Throwing on any non-ENOENT read error here makes higher-level scans fail hard because
listGoals()callsreadGoal()without a per-file guard, andrunGoalHealthCheck()callslistGoals()before entering its per-goaltry/catch. As a result, a single malformed*.jsongoal file can stop the entire watchdog pass (no other goals get checked), which regresses the new per-goal failure isolation behavior. Useful? React with 👍 / 👎.
1323.2 — extensions/memory-hybrid/services/active-task.ts:480
- Status: FIXED
- Evidence:
writeActiveTaskFile()now preserves existing file mode on its atomic tmp-file replacement by copying the current chmod bits to the temp file before rename. Evidence:active-task.ts; permission-preservation test added. - Thread id:
PRRT_kwDORQuyQM6A-HhN - Outdated: False
- Author: chatgpt-codex-connector
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1323#discussion_r3216414659
- Feedback:
Preserve file permissions during atomic ACTIVE-TASKS writes Replacing the file via temp-write +
rename()changes the inode, so existing mode/ownership/ACL onACTIVE-TASKS.mdare not preserved and are replaced by defaults from the temp file creation umask. If operators intentionally set restrictive permissions (for task content confidentiality), a normal write can silently broaden access after this change. Useful? React with 👍 / 👎.
1323.3 — extensions/memory-hybrid/services/goal-registry.ts:181
- Status: FIXED
- Evidence: Duplicate of 1323.1: corrupt individual goal files no longer take down bulk goal enumeration. Evidence:
goal-registry.ts;goal-stewardship-registry.test.ts. - Thread id:
PRRT_kwDORQuyQM6A-Hux - Outdated: True
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1323#discussion_r3216415837
- Feedback:
readGoalnow throws on corrupt/unreadable JSON (good), butlistGoalscallsreadGoalwithout a per-file try/catch. A single corrupt goal file will now causelistGoals()(and callers likerunGoalHealthCheckandstage-active-taskinjection) to throw and abort processing entirely, which undermines the intended “per-goal isolation”. Consider catching errors insidelistGoals(skip/record corrupt files) or adding a separate safe listing API used by watchdog/injection paths.
1323.4 — extensions/memory-hybrid/services/goal-health.ts:249
- Status: FIXED
- Evidence:
http_okverification blocking now catches IPv4-mapped IPv6 literals (::ffff:*) before fetch, preventing loopback/private SSRF bypasses. Evidence:goal-health.ts; mapped-IPv6 test passes. - Thread id:
PRRT_kwDORQuyQM6A-HvA - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1323#discussion_r3216415854
- Feedback:
isBlockedVerificationHostreturnstrueimmediately for any::ffff:IPv4-mapped IPv6 address, so the subsequentmappedIpv4extraction and private-range check is unreachable. Either remove the dead code or move the private-range parsing before the unconditional return (depending on the intended policy).
1323.5 — extensions/memory-hybrid/services/goal-health.ts:240
- Status: FIXED
- Evidence: Expanded blocked-host verification helper to resolve local/private literals consistently and exported helper coverage confirms blocking behavior before network fetch. Evidence:
goal-health.ts; health tests pass. - Thread id:
PRRT_kwDORQuyQM6A-HvG - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1323#discussion_r3216415861
- Feedback: The
http_okhost blocking only checks IP literals (isIP(hostname)), and returnsfalsefor any DNS hostname (other than.local/.localhost). That still allows SSRF to private/loopback/link-local networks via hostnames that resolve to private IPs (including DNS rebinding). If the goal is to block private/local targets, consider resolving the hostname (e.g.,dns.lookup/dns.resolve) and rejecting any private/local results before callingfetch.
1323.6 — extensions/memory-hybrid/services/goal-active-task-mirror.ts:83
- Status: FIXED
- Evidence: Goal active-task mirror refresh now writes atomically via temp file + rename and preserves existing file mode, instead of truncating in-place. Evidence:
goal-active-task-mirror.ts; mirror test verifies no temp files left and mode preserved. - Thread id:
PRRT_kwDORQuyQM6A-HvO - Outdated: False
- Author: copilot-pull-request-reviewer
- URL: https://github.com/markus-lassfolk/openclaw-hybrid-memory/pull/1323#discussion_r3216415870
- Feedback:
refreshActiveTaskMirrorWithGoalswritesACTIVE-TASKS.mdvia a directwriteFile, which can still leave partial-file corruption if interrupted (the PR aims to make ACTIVE-TASKS.md writes atomic). Consider using the same temp-file+rename atomic write pattern aswriteActiveTaskFile, or delegating the final write to that helper so all writers share the same safety guarantees.
Total unresolved threads in scope: 77