How Memory Assets Are Managed for Ownership, Visibility, Versioning, and Status in TencentDB-Agent-Memory

TLDR: In the TencentDB-Agent-Memory repository, Memory Assets (Chat Memory, Skills, Wiki, CodeGraph) are managed through AssetEntity records that combine an owner_user_id for ownership, an AssetVisibility enum for read access, an AssetStatus enum for lifecycle state, and a monotonically increasing version field for optimistic-lock updates — all enforced server-side via the metadata-service.ts and client-facing through metadata-client.ts.

The TencentDB-Agent-Memory repository provides a comprehensive metadata layer for managing team-shared AI memory assets. Understanding how these assets are controlled is essential for anyone building agents, skills, or knowledge systems on this platform. This article breaks down the exact mechanism — ownership, visibility, versioning, and status — as implemented in the source code, so you can work with the API confidently.

The core data model lives in sdk/memory-core/typescript/src/v3/metadata-types.ts, while the enforcement logic is split between the SDK client (metadata-client.ts) and the server service (memory-core/src/metadata/service/metadata-service.ts).

The Core Model: AssetEntity and Its Metadata

Every Memory Asset is stored as an AssetEntity record. This single structure holds all the metadata needed to drive ownership, visibility, versioning, and status.

Aspect Where It's Defined What It Means
Owner owner_user_id field — metadata-types.ts The user who created the asset. The owner automatically has full management rights (read/write/delete).
Visibility AssetVisibility enum — metadata-types.ts Controls who can read the asset. Options: private, team, restricted, agent, task.
Status AssetStatus enum — metadata-types.ts Tracks lifecycle: draft, candidate, approved, deprecated, archived, failed. Gating mechanism for agent binding.
Version version field — metadata-types.ts Monotonically increasing integer incremented on update. Enables optimistic-lock checks.
Binding to Agents FixedAssetBindingEntitymetadata-types.ts Separate table linking assets to agents with injection_mode, priority, and creator.
ACL (Fine-grained access) AclEntitymetadata-types.ts For restricted visibility, grants or denies specific permissions to users, roles, or agents.

Visibility: Who Can Read the Asset

The AssetVisibility enum controls the read scope. According to the repository's source code:

  • private — Only the owner can read the asset.
  • team — All members of the owning team can read.
  • restricted — Access is granted via ACL rows.
  • agent — Only specific agents bound to the asset can access it.
  • cr — Assets attached to a specific task.

Status: What Lifecycle Stage the Asset Is In

The AssetStatus enum drives the workflow. From the source definition:

  • draft — Initial state; not yet ready for use.
  • candidate — Submitted for review.
  • approved — Verified and available for agent binding.
  • deprecated — Superseded by a newer version.
  • archived — Retired from active use.
  • failed — Creation or update process failed.

The UI and the hub consult this field to decide whether an asset can be attached to an agent.

How Ownership Enforcement Works

Server-side enforcement is strictly handled in MemoryCore/src/metadata/service/metadata-service.ts. When you call createAssetForCaller or updateAssetForCaller (lines L1869-L1883), the service performs two critical checks before touching the store:

  1. requireActiveTeamMember — verifies the caller belongs to the target team.
  2. assertCallerIsResourceOwner — verifies the caller is the asset's owner for mutations.

This guarantees that no non-owner can modify or delete an asset, even if they pass the correct payload.

Versioning and Optimistic-Lock Updates

The version field is a monotonically increasing integer. Every update through updateAsset increments it. This enables optimistic-lock checking — callers must supply the latest expected version to avoid stale writes.

Example: Update a Skill with Version Check

const client = new MemoryClient({ baseUrl: 'http://localhost:8125' });

await client.updateAsset({
  asset_id: 'skill-123',
  version: 2, // latest version expected
  description: 'Updated Checklist',
  status: 'approved',
});

When a provided version does not match the server's current value, the API returns a SKILL_VERSION_STALE error (as defined in the SDK error handling in errors.ts).

Visibility Filtering at Runtime

When an agent requests accessible assets through listAccessibleAssets (see metadata-client.ts, the hub applies the visibility filter:

  • private → only owner sees it.
  • team → all team members see it.
  • restricted → an ACL lookup happens.
  • agent → only bound agents see it.

This filtering logic is implemented in `permission-checker.ts under the MemoryCore service directory.

Granting a Restricted ACL Entry

For restricted assets, you can grant specific permissions via grantAcl:

await client.grantAcl({
  asset_id: 'skill-123',
  subject_type: 'user',
  subject_id: 'user-99',
  permission: 'read',
  effect: 'allow',
  granted_by: 'user-42',
});

This call is defined in metadata-client.ts.

Binding Assets to Agents

The FixedAssetBindingEntity stores which assets an agent uses, along with configuration:

Field Purpose
agent_id The agent that owns the binding.
asset_id The asset linked to the agent.
injection_mode How the asset gets injected (direct, summary, tool, reference).
priority Controls injection order (lower number = higher priority).
created_by The user who created the binding.

Example: Set Fixed Assets for an Agent

await client.setAgentFixedAssets('agent-07', [
  {
    asset_id: 'skill-123',
    asset_type: 'skill',
    injection_mode: 'direct',
    priority: 10,
    created_by: 'user-42',
  },
]);

The Full Lifecycle in Practice

Combining everything, here's how a Memory Asset moves from creation to reuse:

  1. Creation — Caller creates an asset via createAsset, setting owner_user_id, visibility, and status. The service validates team membership and ownership.
  2. Version bump — On every updateAsset, the service increments the version. Bandwidth is saved because the client doesn't need to manage that manually.
  3. Visibility filtering — When assets are listed for an agent, the hub applies the visibility enum to decide which items to return.
  4. Status gating — Only approved (or workflow-allowed) assets can be bound to agents. draft and failed assets are excluded automatically.
  5. Binding — An operator creates a FixedAssetBinding row linking the asset to the agent, setting injection mode and priority.
  6. ACL enforcement — For restricted visibility, each request checks the ACL records to decide allow/deny.

Key Files for Reference

File Relocation What It Contains
metadata-types.ts sdk/memory-core/typescript/src/v3/metadata-types.ts Core types for assets, visibility, status, version, ACL, and bindings.
metadata-client.ts sdk/memory-core/typescript/src/v3/metadata-client.ts SDK client methods (createAsset, updateAsset, listAccessibleAssets, grantAcl).
metadata-service.ts MemoryCore/src/metadata/service/metadata-service.ts Server-side ownership, visibility, and ACL enforcement logic.
permission-checker.ts MemoryCore/src/metadata/service/permission-checker.ts Evaluates ACL records against incoming requests.
skill-versioning.ts MemoryCore/src/core/skill/skill-versioning.ts Version-aware create/update for Skill assets.

Summary

  • Ownership is enforced via owner_user_id with server-side checks in MetadataService.
  • Visibility is controlled by the Visibility enum and ACL ("allow"/"deny") records for restricted assets.
  • Versioning uses a monotonic counter for optimistic-lock conflict detection.
  • Status gates asset availability, with a status field driving UI badges and agent-binding eligibility.
  • Agent binding is a separate table, allowing direct, summary, tool, or reference injection modes.

Frequently Asked Questions

What are the possible visibility values for a Memory Asset?

The five values are private (owner-only), team (all team members), restricted (ACL-based), agent (bound agents only), and task (assets tied to a denominator task). These are defined in the AssetVisibility enum in metadata-types.ts.

How does versioning prevent data conflicts in TencentDB-Agent-Memory?

The version field increments on every update. When you pass a version in an update, the service verifies it matches the current stored value. If not, an error is returned, preventing stale writes and enabling optimistic-lock concurrency control.

Can a non-owner update or delete a Memory asset?

No. The metadata-service.ts enforces that only the owner can mutate an asset via assertCallerIsResourceOwner. However, an owner can grant others write access through ACL rows if the visibility is restricted.

When does an asset become available for binding to an agent?

Only assets with status approved are eligible for binding. Assets in draft, failed, or archived statuses are hidden from the "bind" UI and rejected by the hub's status gating logic.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →