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 | FixedAssetBindingEntity — metadata-types.ts |
Separate table linking assets to agents with injection_mode, priority, and creator. |
| ACL (Fine-grained access) | AclEntity — metadata-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:
requireActiveTeamMember— verifies the caller belongs to the target team.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:
- Creation — Caller creates an asset via
createAsset, settingowner_user_id,visibility, andstatus. The service validates team membership and ownership. - Version bump — On every
updateAsset, the service increments the version. Bandwidth is saved because the client doesn't need to manage that manually. - Visibility filtering — When assets are listed for an agent, the hub applies the visibility enum to decide which items to return.
- Status gating — Only
approved(or workflow-allowed) assets can be bound to agents.draftandfailedassets are excluded automatically. - Binding — An operator creates a
FixedAssetBindingrow linking the asset to the agent, setting injection mode and priority. - ACL enforcement — For
restrictedvisibility, 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_idwith server-side checks inMetadataService. - Visibility is controlled by the
Visibilityenum and ACL ("allow"/"deny") records forrestrictedassets. - Versioning uses a monotonic counter for optimistic-lock conflict detection.
- Status gates asset availability, with a
statusfield 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →