Current behavior
Ownership semantics differ between the MCP tools and the HTTP API:
- MCP tools enforce an owner check (fetch entity, compare caller-supplied
user_id against metadata.owner_id) for publish, unpublish, and delete:
altk_evolve/frontend/mcp/mcp_server.py:668-670 (publish_entity)
altk_evolve/frontend/mcp/mcp_server.py:711-713 (unpublish_entity)
altk_evolve/frontend/mcp/mcp_server.py:749-752 (delete_entity)
- The HTTP API delete endpoint has no ownership check at all —
altk_evolve/frontend/api/routes.py:185-197 (delete_namespace_entity calls delete_entity_by_id directly at line 191)
- The check that does exist is advisory in nature: the caller supplies its own
user_id, and each tool re-implements the get-then-compare logic inline
Why it matters
Consistency across surfaces: the React UI talks to the HTTP API, so the same entity can be owner-protected through one frontend and freely deletable through another. Principle of least surprise says all frontends should apply the same policy, and duplicated inline checks tend to drift as new tools/endpoints are added.
Suggested direction
- Extract a single ownership-policy helper (e.g.
check_owner(entity, caller_id)) in a shared module, and have MCP tools and API routes both call it
- Apply it to the HTTP API mutation endpoints (delete, and any future publish/update routes)
- Longer term, this is a natural fit for a hook/policy layer where ownership is one pluggable rule rather than per-frontend inline logic
Current behavior
Ownership semantics differ between the MCP tools and the HTTP API:
user_idagainstmetadata.owner_id) for publish, unpublish, and delete:altk_evolve/frontend/mcp/mcp_server.py:668-670(publish_entity)altk_evolve/frontend/mcp/mcp_server.py:711-713(unpublish_entity)altk_evolve/frontend/mcp/mcp_server.py:749-752(delete_entity)altk_evolve/frontend/api/routes.py:185-197(delete_namespace_entitycallsdelete_entity_by_iddirectly at line 191)user_id, and each tool re-implements the get-then-compare logic inlineWhy it matters
Consistency across surfaces: the React UI talks to the HTTP API, so the same entity can be owner-protected through one frontend and freely deletable through another. Principle of least surprise says all frontends should apply the same policy, and duplicated inline checks tend to drift as new tools/endpoints are added.
Suggested direction
check_owner(entity, caller_id)) in a shared module, and have MCP tools and API routes both call it