docs(comments): 注释中文化 · internal/runtime/memory(31 文件,纯替换)
CI / Backend (build / vet / test / cross-compile) (push) Has been cancelled
CI / Frontend (tsc + vite build) (push) Has been cancelled

- 只翻注释/文档字符串:820 增 / 820 删 严格 1:1;剥掉整行注释与行尾注释尾巴后,
  逐文件与 HEAD 比对「代码部分差异 = 0」;裁决/design 编号计数逐项与 HEAD 一致
- 保留可执行 SQL 样例、SQLite 报错原文、pgvector/HNSW/ANN/BLOB 等技术词原文
- 复核:go build 绿 + memory/projectindex/vector 三包测试绿;gofmt 仅剩 2 个既有未格式化文件(改动前即如此,未顺手修)
This commit is contained in:
AskaEth committed 2026-10-04 13:32:54 +08:00
1 parent eb1828ee7a
commit 61cf80d5ee
31 files changed
+820 -820

No files matched your search

+47 -47
View File
@@ -8,26 +8,26 @@ import (
"strings"
)
// Scope access control sentinels. These surface when a persona attempts a write
// it is not permitted to make under the design §3 rules.
// 作用域访问控制哨兵错误。当角色试图执行 design §3 规则
// 不允许的写入时返回。
var (
// ErrReadOnly is returned when a persona tries to write or delete a
// persona-scope memory item it does not own. Under design §3 other personas
// are read-only for 角色日常记忆.
// ErrReadOnly 在角色试图写入或删除
// 不属于它的角色作用域记忆条目时返回。按 design §3,其他角色
// 对角色日常记忆只读。
ErrReadOnly = errors.New("memory: read-only: persona does not own this item")
// ErrMissingProjectID is returned when a project-scoped query has a blank id.
// ErrMissingProjectID 在项目作用域查询的 id 为空时返回。
ErrMissingProjectID = errors.New("memory: project_id is required")
)
// canWrite reports whether actorID may write item under the design §3 scope rules:
// canWrite 报告 actorID 按 design §3 作用域规则是否可以写入 item:
//
// - ScopeUser: any persona may write (user habits are globally shared).
// - ScopePersona: only the owning persona may write (other personas read-only).
// - ScopeProject: any persona may write (project memory is 人人可写).
// - ScopeUser:任何角色都可写(用户习惯全局共享)。
// - ScopePersona:只有归属角色可写(其他角色只读)。
// - ScopeProject:任何角色都可写(项目记忆人人可写)。
//
// The caller must have already validated item.Scope; an invalid scope is not
// writable by anyone.
// 调用方必须已校验 item.Scope;非法作用域对任何人
// 都不可写。
func canWrite(actorID string, it MemoryItem) bool {
switch it.Scope {
case ScopeUser, ScopeProject:
@@ -39,11 +39,11 @@ func canWrite(actorID string, it MemoryItem) bool {
}
}
// AddScoped persists item under actorID's authority, enforcing the design §3
// write rules by persona_id + scope. A blank actorID returns ErrMissingPersona.
// When item.PersonaID is blank it is filled with actorID, so a persona always
// records its own provenance; a persona-scope item owned by a different persona
// returns ErrReadOnly. User- and project-scope items are writable by any persona.
// AddScoped 以 actorID 的权限持久化 item,按 persona_id + scope 施加
// design §3 写规则。actorID 为空返回 ErrMissingPersona。
// item.PersonaID 为空时用 actorID 填充它,因此角色总是
// 记录自身的来源;归属其他角色的角色作用域条目
// 返回 ErrReadOnly。用户与项目作用域的条目任何角色都可写。
func (s *Store) AddScoped(ctx context.Context, actorID string, item MemoryItem) (MemoryItem, error) {
if strings.TrimSpace(actorID) == "" {
return MemoryItem{}, ErrMissingPersona
@@ -60,19 +60,19 @@ func (s *Store) AddScoped(ctx context.Context, actorID string, item MemoryItem)
return s.Add(ctx, item)
}
// ListScope returns every item of scope visible to personaID, newest first,
// applying the design §3 read rules (rowid breaks created_at ties so items
// written within the same clock tick keep a stable newest-first order):
// ListScope 返回 personaID 可见的该作用域全部条目,最新的在前,
// 施加 design §3 读规则(rowid 打破 created_at 并列,使
// 同一时钟刻内写入的条目保持稳定的最新优先顺序):
//
// - ScopeUser: every user-scope item (globally shared across personas).
// - ScopePersona: every persona-scope item. Other personas are read-only but
// still readable, so a persona can read another persona's 角色日常记忆 here.
// - ScopeProject: every project-scope item (人人可读).
// - ScopeUser:全部用户作用域条目(跨角色全局共享)。
// - ScopePersona:全部角色作用域条目。其他角色只读但
// 仍可读,因此角色在这里可以读到另一个角色的角色日常记忆。
// - ScopeProject:全部项目作用域条目(人人可读)。
//
// personaID names the reading persona and is required so callers always declare
// the identity boundary even for a shared scope. The higher policy layer still
// decides whether a restricted context (group chat / stranger, design §5) may
// receive these; this method only enforces the base read rule.
// personaID 指明读取方角色,且必填,以便调用方即使在共享
// 作用域上也始终声明身份边界。是否允许受限上下文(群聊 / 陌生人,design §5)
// 接收这些内容仍由更高层策略决定;本方法只施加
// 基础读规则。
func (s *Store) ListScope(ctx context.Context, scope Scope, personaID string) ([]MemoryItem, error) {
if strings.TrimSpace(personaID) == "" {
return nil, ErrMissingPersona
@@ -90,13 +90,13 @@ func (s *Store) ListScope(ctx context.Context, scope Scope, personaID string) ([
return scanItems(rows, "scope item")
}
// ListProject returns every memory item linked to projectID, newest first, with
// rowid breaking created_at ties so same-tick writes keep a stable order. A
// project-scoped memory carries a ProjectID that links to the projectindex
// hierarchy (design §3); this is the deep-search entry point — callers combine
// it with the projectindex store to walk 项目索引 → 项目描述 → 章节内容. Project
// memory is readable by all personas, so no persona filter is applied. A blank
// projectID returns ErrMissingProjectID.
// ListProject 返回链接到 projectID 的全部记忆条目,最新的在前,
// rowid 打破 created_at 并列,使同一刻的写入保持稳定顺序。项目
// 作用域记忆携带一个 ProjectID,链到 projectindex
// 层级(design §3);这是深检索入口 —— 调用方把它与
// projectindex 存储结合,沿 项目索引 → 项目描述 → 章节内容 遍历。项目
// 记忆所有角色可读,因此不施加角色过滤。projectID 为空
// 返回 ErrMissingProjectID。
func (s *Store) ListProject(ctx context.Context, projectID string) ([]MemoryItem, error) {
if strings.TrimSpace(projectID) == "" {
return nil, ErrMissingProjectID
@@ -111,11 +111,11 @@ func (s *Store) ListProject(ctx context.Context, projectID string) ([]MemoryItem
return scanItems(rows, "project item")
}
// DeleteScoped removes the item with the given id, but only if actorID may write
// it under the design §3 rules. This enforces the persona read-only boundary on
// deletion: a persona may delete its own persona-scope items and any user- or
// project-scope item, but not another persona's 角色日常记忆. A blank id returns
// ErrNotFound; writing a foreign persona-scope item returns ErrReadOnly.
// DeleteScoped 删除给定 id 的条目,但仅当按 design §3 规则 actorID
// 可以写它。这在删除上施加角色只读边界:
// 角色可以删自己的角色作用域条目,以及任何用户或
// 项目作用域条目,但不能删另一个角色的角色日常记忆。id 为空返回
// ErrNotFound;改动他人的角色作用域条目返回 ErrReadOnly。
func (s *Store) DeleteScoped(ctx context.Context, actorID, id string) error {
if strings.TrimSpace(actorID) == "" {
return ErrMissingPersona
@@ -130,19 +130,19 @@ func (s *Store) DeleteScoped(ctx context.Context, actorID, id string) error {
return s.Delete(ctx, id)
}
// ensureProjectIDColumn rolls the memory_items table forward when it was created
// before the M4 project index (design §3) existed: it adds the project_id column
// if it is missing, and ignores the duplicate-column result when present. It is
// SQLite-specific (the memory store is SQLite-backed) and idempotent, so NewStore
// may be called on a fresh schema or a pre-existing one.
// ensureProjectIDColumn 在 memory_items 表创建于 M4 项目索引
// (design §3)存在之前时把它前滚:缺失时补加 project_id 列,
// 已存在时忽略重复列错误。它是
// SQLite 特有的(记忆存储基于 SQLite)且幂等,因此 NewStore
// 可在全新 schema 或既有 schema 上调用。
func ensureProjectIDColumn(ctx context.Context, db *sql.DB) error {
_, err := db.ExecContext(ctx, `ALTER TABLE memory_items
ADD COLUMN project_id TEXT NOT NULL DEFAULT ''`)
if err == nil {
return nil
}
// SQLite reports "duplicate column name: project_id" when the column already
// exists (e.g. created by the CREATE TABLE in NewStore, or by a previous run).
// 当该列已存在(例如由 NewStore 中的 CREATE TABLE 创建,
// 或由上一次运行创建)时,SQLite 报 "duplicate column name: project_id"。
if strings.Contains(err.Error(), "duplicate column name") {
return nil
}