Skip to content

fix: harden generic Cortex owner context#34

Merged
100yenadmin merged 1 commit into
mainfrom
codex/cortex-owner-context-hardening
May 17, 2026
Merged

fix: harden generic Cortex owner context#34
100yenadmin merged 1 commit into
mainfrom
codex/cortex-owner-context-hardening

Conversation

@100yenadmin
Copy link
Copy Markdown
Member

@100yenadmin 100yenadmin commented May 17, 2026

Summary

  • add an explicit ownerIdMode config with server_resolved as the hosted/proxy-safe default
  • remove caller-supplied owner_id parameters from generic Cortex ask, contradiction, commitment, and open-loop tools
  • centralize owner forwarding so configured ownerId is sent only when ownerIdMode: "configured" is explicitly selected for self-host installs
  • disable the local SQLite memory cache in server-resolved mode to avoid config-owner cache reuse in shared hosted plugin processes
  • update README/manifest/dist artifacts and add owner-context coverage

Why

Company Brain tools now use an explicit account-scoped HTTP path, but the older generic Cortex plugin tools still allowed per-call owner overrides or relied on config-owner forwarding. For hosted multi-tenant paths, the effective owner should come from Cortex/proxy auth, not mutable tool params.

Validation

  • npm test

Closes #33

Summary by CodeRabbit

  • New Features

    • Added ownerIdMode option with server_resolved (default) and configured.
    • Centralized ownership handling; generic Cortex tools no longer accept per-call owner overrides.
    • Local cache now only enables when a configured owner is present and valid.
  • Documentation

    • Updated Quick Start, config table, and self-host guidance for ownerId/ownerIdMode.
    • Added cortex_insights to Tools.
  • Tests

    • Added/updated tests covering ownerIdMode behavior and manifest parity.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f1f27a4e-f7db-4fff-9405-c26bd354089e

📥 Commits

Reviewing files that changed from the base of the PR and between 181e38b and 2ff906c.

⛔ Files ignored due to path filters (11)
  • dist/__tests__/owner-context.test.d.ts is excluded by !**/dist/**
  • dist/__tests__/owner-context.test.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/__tests__/owner-context.test.js is excluded by !**/dist/**
  • dist/__tests__/owner-context.test.js.map is excluded by !**/dist/**, !**/*.map
  • dist/__tests__/plugin-manifest-parity.test.js is excluded by !**/dist/**
  • dist/__tests__/plugin-manifest-parity.test.js.map is excluded by !**/dist/**, !**/*.map
  • dist/index.d.ts is excluded by !**/dist/**
  • dist/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/index.js is excluded by !**/dist/**
  • dist/index.js.map is excluded by !**/dist/**, !**/*.map
  • dist/openclaw.plugin.json is excluded by !**/dist/**
📒 Files selected for processing (6)
  • README.md
  • openclaw.plugin.json
  • package.json
  • src/__tests__/owner-context.test.ts
  • src/__tests__/plugin-manifest-parity.test.ts
  • src/index.ts
🚧 Files skipped from review as they are similar to previous changes (4)
  • openclaw.plugin.json
  • src/tests/plugin-manifest-parity.test.ts
  • README.md
  • src/index.ts

📝 Walkthrough

Walkthrough

This PR implements owner context hardening by introducing OwnerContextMode ("server_resolved" | "configured"), centralizing ownership application in CortexClient helpers, removing per-call owner_id from generic cortex_* tools, updating plugin schema and README, gating local SQLite cache on configured ownership, and adding tests enforcing the new behavior.

Changes

Owner Context Mode & Multi-Tenant Safety

Layer / File(s) Summary
README quickstart & tools documentation
README.md
Quick Start now uses ownerIdMode: "server_resolved"; README adds self-host snippet showing ownerId + ownerIdMode: "configured", documents cortex_insights, and notes generic tools don't accept per-call owner_id.
Plugin schema: ownerIdMode property
openclaw.plugin.json, src/index.ts
Adds ownerIdMode enum (server_resolved,configured) defaulting to server_resolved; clarifies ownerId is only used when ownerIdMode is configured.
Tests and package.json wiring
src/__tests__/owner-context.test.ts, src/__tests__/plugin-manifest-parity.test.ts, package.json
Adds owner-context test validating parse/behavior and enforcement; updates manifest parity test to require ownerIdMode; appends built owner-context test to npm test.
OwnerContextMode type and config parsing
src/index.ts
Adds OwnerContextMode type, extends EvaMemoryConfig with ownerIdMode, and sets parse default to server_resolved.
Ownership helper functions
src/index.ts
Exports shouldSendConfiguredOwner and withConfiguredOwner; addOwnerParam updated to inject owner_id only when mode is configured and owner is valid.
CortexClient ownership helpers
src/index.ts
CortexClient accepts ownerIdMode and adds ownerBody, ownerParams, and withQuery to consistently apply ownership to request bodies and query strings.
Core memory endpoints update
src/index.ts
retrieve, remember, search, forget, and bulk listing use ownerBody/ownerParams/withQuery instead of embedding per-call owner_id.
Dialectic and entity methods
src/index.ts
ask, contradictions, commitments, insights, and open-loop methods refactored to remove per-call owner overrides and rely on centralized ownership helpers.
Company Brain ownership
src/index.ts
Company Brain builders and queryCompanyBrain updated to apply ownership via helpers and clamp limit.
Plugin registration & cache gating
src/index.ts
Plugin registers CortexClient with ownerIdMode; local SQLite cache enabled only when sqlite present and shouldSendConfiguredOwner returns true; logs explicit disablement and includes ownerMode in registration log.
Tool schema simplification
src/index.ts, README.md
Removes owner_id from generic cortex_* tool schemas and updates executors to call client methods without per-call owner overrides; documents cortex_insights.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 I hopped through configs late at night,

Swapped owner bits to keep tenants right,
Server-resolved for hosted skies,
Configured when local setups rise,
Now memories stay where they belong — polite!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: harden generic Cortex owner context' directly matches the main change: adding explicit owner context handling and removing caller-supplied owner parameters from generic Cortex tools.
Linked Issues check ✅ Passed The PR meets all coding requirements from issue #33: adds ownerIdMode config property, removes per-call owner_id from generic tools, centralizes owner forwarding to configured mode, disables cache in server_resolved mode, and includes tests validating owner-context behavior.
Out of Scope Changes check ✅ Passed All changes are in-scope: configuration schema updates, tool ownership refactoring, test coverage for owner-context, and documentation updates directly support the requirement to harden generic Cortex owner context.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/cortex-owner-context-hardening

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Comment @coderabbitai help to get the list of available commands and usage tips.

@100yenadmin 100yenadmin marked this pull request as ready for review May 17, 2026 18:52
@100yenadmin
Copy link
Copy Markdown
Member Author

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 17, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (2)
README.md (1)

53-55: ⚡ Quick win

Clarify quick-start by omitting ownerId in server_resolved example.

Including ownerId in the default hosted/proxy example can imply it is used in that mode. Prefer showing only ownerIdMode: "server_resolved" in the baseline example, and move ownerId to a separate self-host (configured) example.

Suggested doc tweak
         "config": {
           "cortexUrl": "https://your-cortex-server.example.com",
           "apiKey": "your-api-key",
-          "ownerId": "default",
           "ownerIdMode": "server_resolved"
         }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@README.md` around lines 53 - 55, Update the quick-start example in README so
it does not include "ownerId" when demonstrating the hosted/proxy mode;
specifically remove the "ownerId": "default" field from the example that shows
"ownerIdMode": "server_resolved" and instead present a separate
self-hosted/configured example that includes "ownerId" and "ownerIdMode":
"configured" to avoid implying ownerId is used in server_resolved mode.
src/__tests__/owner-context.test.ts (1)

34-36: ⚡ Quick win

Harden the schema assertion to avoid brittle false passes/fails.

Checking only "owner_id: Type.Optional" is too narrow. It can miss other owner_id schema shapes or fail on harmless formatting changes. Use a broader pattern scoped to generic tool schema blocks.

Suggested assertion update
-  assert.equal(
-    source.includes("owner_id: Type.Optional"),
-    false,
-    "generic tool schemas must not expose caller-supplied owner_id",
-  );
+  assert.equal(
+    /cortex_(ask|list_contradictions|resolve_contradiction|add_commitment|update_commitment|list_commitments|add_open_loop|resolve_open_loop|list_open_loops)[\s\S]{0,2000}\bowner_id\b/.test(source),
+    false,
+    "generic tool schemas must not expose caller-supplied owner_id",
+  );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/__tests__/owner-context.test.ts` around lines 34 - 36, The current
assertion uses source.includes("owner_id: Type.Optional") which is brittle;
update the test in owner-context.test.ts to assert that no owner_id is present
anywhere inside the generic tool schema block by replacing the simple includes
check on the source variable with a regex-based check scoped to the generic tool
schema definition (e.g., locate the GenericToolSchema/definition block in source
and assert
/GenericToolSchema\s*[:=]\s*Type\.(Object|Record)[\s\S]*owner_id\s*:/s.test(source)
is false); keep the assertion logic but use this broader pattern so any owner_id
shape (optional, required, different spacing) inside the generic tool schema
fails the test.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/index.ts`:
- Around line 144-160: The code must ensure "configured" mode only takes effect
when a real owner namespace exists (not the fallback "default"); keep
shouldSendConfiguredOwner(ownerId, ownerIdMode) as the single canonical guard
and replace any direct checks of ownerIdMode === "configured" (e.g.,
cache/registration/SQLite setup paths mentioned in the review) with calls to
shouldSendConfiguredOwner(ownerId, ownerIdMode); update spots that enable the
SQLite cache/registration logic to require shouldSendConfiguredOwner(...) so a
fallback ownerId of "default" (or empty) will not enable configured behavior or
persist into memories-default.db, and leave withConfiguredOwner and
addOwnerParam to rely on the same helper for consistency.
- Around line 1776-1780: The runtime JSON schema for ownerIdMode in
cortexPlugin.configSchema.jsonSchema is missing the default value, causing a
mismatch with parseConfig() and openclaw.plugin.json; update the ownerIdMode
schema definition (the object containing "type", "enum", and "description") to
include "default": "server_resolved" so the in-process schema matches
parseConfig() and the plugin manifest; ensure the change is applied where
cortexPlugin.configSchema.jsonSchema is defined and leave parseConfig() and
openclaw.plugin.json unchanged.

---

Nitpick comments:
In `@README.md`:
- Around line 53-55: Update the quick-start example in README so it does not
include "ownerId" when demonstrating the hosted/proxy mode; specifically remove
the "ownerId": "default" field from the example that shows "ownerIdMode":
"server_resolved" and instead present a separate self-hosted/configured example
that includes "ownerId" and "ownerIdMode": "configured" to avoid implying
ownerId is used in server_resolved mode.

In `@src/__tests__/owner-context.test.ts`:
- Around line 34-36: The current assertion uses source.includes("owner_id:
Type.Optional") which is brittle; update the test in owner-context.test.ts to
assert that no owner_id is present anywhere inside the generic tool schema block
by replacing the simple includes check on the source variable with a regex-based
check scoped to the generic tool schema definition (e.g., locate the
GenericToolSchema/definition block in source and assert
/GenericToolSchema\s*[:=]\s*Type\.(Object|Record)[\s\S]*owner_id\s*:/s.test(source)
is false); keep the assertion logic but use this broader pattern so any owner_id
shape (optional, required, different spacing) inside the generic tool schema
fails the test.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 49ef526e-65b8-4ab3-ae3b-0704e66264ff

📥 Commits

Reviewing files that changed from the base of the PR and between 6c15f47 and 3a76fb1.

⛔ Files ignored due to path filters (11)
  • dist/__tests__/owner-context.test.d.ts is excluded by !**/dist/**
  • dist/__tests__/owner-context.test.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/__tests__/owner-context.test.js is excluded by !**/dist/**
  • dist/__tests__/owner-context.test.js.map is excluded by !**/dist/**, !**/*.map
  • dist/__tests__/plugin-manifest-parity.test.js is excluded by !**/dist/**
  • dist/__tests__/plugin-manifest-parity.test.js.map is excluded by !**/dist/**, !**/*.map
  • dist/index.d.ts is excluded by !**/dist/**
  • dist/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/index.js is excluded by !**/dist/**
  • dist/index.js.map is excluded by !**/dist/**, !**/*.map
  • dist/openclaw.plugin.json is excluded by !**/dist/**
📒 Files selected for processing (6)
  • README.md
  • openclaw.plugin.json
  • package.json
  • src/__tests__/owner-context.test.ts
  • src/__tests__/plugin-manifest-parity.test.ts
  • src/index.ts

Comment thread src/index.ts
Comment thread src/index.ts
@100yenadmin 100yenadmin force-pushed the codex/cortex-owner-context-hardening branch from 3a76fb1 to 546bc83 Compare May 17, 2026 18:57
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/__tests__/owner-context.test.ts (1)

33-43: ⚡ Quick win

Expand owner-context guard coverage for cortex_insights.

Given this PR’s owner-hardening scope across generic Cortex tools, consider adding cortex_insights to this regression list so schema-level owner_id reintroduction is caught early.

Suggested test diff
   const genericOwnerScopedTools = [
     "cortex_ask",
     "cortex_list_contradictions",
     "cortex_resolve_contradiction",
     "cortex_add_commitment",
     "cortex_update_commitment",
     "cortex_list_commitments",
+    "cortex_insights",
     "cortex_add_open_loop",
     "cortex_resolve_open_loop",
     "cortex_list_open_loops",
   ];
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/__tests__/owner-context.test.ts` around lines 33 - 43, Add
"cortex_insights" to the genericOwnerScopedTools array in the owner-context test
so the owner-context guard covers that tool; update the array defined as
genericOwnerScopedTools in src/__tests__/owner-context.test.ts to include
"cortex_insights" alongside the other tool names (e.g., "cortex_ask",
"cortex_list_contradictions", etc.) and rerun tests to ensure schema-level
owner_id regressions are caught.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/__tests__/owner-context.test.ts`:
- Around line 33-43: Add "cortex_insights" to the genericOwnerScopedTools array
in the owner-context test so the owner-context guard covers that tool; update
the array defined as genericOwnerScopedTools in
src/__tests__/owner-context.test.ts to include "cortex_insights" alongside the
other tool names (e.g., "cortex_ask", "cortex_list_contradictions", etc.) and
rerun tests to ensure schema-level owner_id regressions are caught.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 4472cd31-8332-40ac-9026-a98adbfff662

📥 Commits

Reviewing files that changed from the base of the PR and between 3a76fb1 and 546bc83.

⛔ Files ignored due to path filters (11)
  • dist/__tests__/owner-context.test.d.ts is excluded by !**/dist/**
  • dist/__tests__/owner-context.test.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/__tests__/owner-context.test.js is excluded by !**/dist/**
  • dist/__tests__/owner-context.test.js.map is excluded by !**/dist/**, !**/*.map
  • dist/__tests__/plugin-manifest-parity.test.js is excluded by !**/dist/**
  • dist/__tests__/plugin-manifest-parity.test.js.map is excluded by !**/dist/**, !**/*.map
  • dist/index.d.ts is excluded by !**/dist/**
  • dist/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/index.js is excluded by !**/dist/**
  • dist/index.js.map is excluded by !**/dist/**, !**/*.map
  • dist/openclaw.plugin.json is excluded by !**/dist/**
📒 Files selected for processing (6)
  • README.md
  • openclaw.plugin.json
  • package.json
  • src/__tests__/owner-context.test.ts
  • src/__tests__/plugin-manifest-parity.test.ts
  • src/index.ts
✅ Files skipped from review due to trivial changes (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • package.json
  • src/tests/plugin-manifest-parity.test.ts
  • src/index.ts

@100yenadmin 100yenadmin force-pushed the codex/cortex-owner-context-hardening branch from 546bc83 to 181e38b Compare May 17, 2026 19:00
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/__tests__/owner-context.test.ts`:
- Around line 57-60: The test currently hard-codes a regex to detect owner_id
being passed in client.execute-like calls, which can drift from the canonical
list in genericOwnerScopedTools; update the test to derive its execute-method
checks from the same source as genericOwnerScopedTools (or iterate that array)
instead of a separate regex. Specifically, replace the static regex usage with
logic that builds expected method names/patterns from genericOwnerScopedTools
(or uses that list to assert no caller-supplied owner_id is forwarded),
referencing the test helper/assertion block that checks for
client.(ask|listContradictions|...) and the genericOwnerScopedTools variable so
both stay in sync.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 8170b9e7-a029-4f95-8430-a7d42cc89ae3

📥 Commits

Reviewing files that changed from the base of the PR and between 546bc83 and 181e38b.

⛔ Files ignored due to path filters (11)
  • dist/__tests__/owner-context.test.d.ts is excluded by !**/dist/**
  • dist/__tests__/owner-context.test.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/__tests__/owner-context.test.js is excluded by !**/dist/**
  • dist/__tests__/owner-context.test.js.map is excluded by !**/dist/**, !**/*.map
  • dist/__tests__/plugin-manifest-parity.test.js is excluded by !**/dist/**
  • dist/__tests__/plugin-manifest-parity.test.js.map is excluded by !**/dist/**, !**/*.map
  • dist/index.d.ts is excluded by !**/dist/**
  • dist/index.d.ts.map is excluded by !**/dist/**, !**/*.map
  • dist/index.js is excluded by !**/dist/**
  • dist/index.js.map is excluded by !**/dist/**, !**/*.map
  • dist/openclaw.plugin.json is excluded by !**/dist/**
📒 Files selected for processing (6)
  • README.md
  • openclaw.plugin.json
  • package.json
  • src/__tests__/owner-context.test.ts
  • src/__tests__/plugin-manifest-parity.test.ts
  • src/index.ts
✅ Files skipped from review due to trivial changes (1)
  • README.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • package.json
  • src/tests/plugin-manifest-parity.test.ts
  • openclaw.plugin.json

Comment thread src/__tests__/owner-context.test.ts Outdated
@100yenadmin 100yenadmin force-pushed the codex/cortex-owner-context-hardening branch from 181e38b to 2ff906c Compare May 17, 2026 19:04
@100yenadmin 100yenadmin merged commit 9056b22 into main May 17, 2026
5 checks passed
@100yenadmin 100yenadmin deleted the codex/cortex-owner-context-hardening branch May 17, 2026 19:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Harden generic Cortex plugin owner context

1 participant