M1:镜生域后端闭环——灵胚/照心试演/启镜原子闸门/执镜关系/命台租约/魂籍签名导出/死亡冷静期(迁移 001,测试 7 用例)
This commit is contained in:
1 parent
c090893e63
commit
1cd0069d65
24 files changed
+1508
-9
No files matched your search
@@ -16,6 +16,7 @@ from app.models.governance import (
|
||||
)
|
||||
from app.models.idempotency import IdempotencyKey
|
||||
from app.models.imports import CharacterImportJob, ImportItem
|
||||
from app.models.jingsheng import Custodianship, EmbryoDraft, IdentityRecord, RuntimeSeat
|
||||
from app.models.lorebook import Lorebook, LorebookEntry
|
||||
from app.models.mcp_servers import McpServer
|
||||
from app.models.memory import Memory, MemoryLink
|
||||
|
||||
@@ -41,3 +41,13 @@ class Character(Base):
|
||||
)
|
||||
activated_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
archived_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
# ── rewrite/1.0 镜生域增量列(data-model.md §1):来源、道体锚点、死亡与冷静期 ──
|
||||
source: Mapped[str] = mapped_column(
|
||||
String(40), nullable=False, default="original", server_default="original", index=True
|
||||
)
|
||||
identity_baseline_json: Mapped[str] = mapped_column(
|
||||
Text, nullable=False, default="{}", server_default="{}"
|
||||
)
|
||||
death_requested_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
calm_period_until: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
died_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
@@ -0,0 +1,84 @@
|
||||
"""镜生域模型:灵胚、执镜关系、命台、魂籍(data-model.md §1)。
|
||||
|
||||
- 灵胚只有预备身份,启镜(activate)才产生正式人物与执镜关系;
|
||||
- 命台人物粒度唯一(UNIQUE(character_id)),租约到期可被接管,epoch 递增;
|
||||
- 魂籍版本不可变(UNIQUE(character_id, version)),签名绑定人物与版本。
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from sqlalchemy import DateTime, ForeignKey, Integer, String, Text, UniqueConstraint
|
||||
from sqlalchemy.orm import Mapped, mapped_column
|
||||
|
||||
from app.core.ids import new_custodianship_id, new_embryo_id, new_identity_record_id, new_seat_id
|
||||
from app.core.time import utc_now
|
||||
from app.db.base import Base
|
||||
|
||||
|
||||
class EmbryoDraft(Base):
|
||||
"""灵胚:启镜前的可审阅草稿。放弃灵胚是删除草稿,不是人物死亡。"""
|
||||
|
||||
__tablename__ = "embryo_drafts"
|
||||
|
||||
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_embryo_id)
|
||||
owner_scope: Mapped[str] = mapped_column(String(80), nullable=False, index=True)
|
||||
# drafting / previewing / confirming / activated / abandoned
|
||||
status: Mapped[str] = mapped_column(String(40), nullable=False, default="drafting", index=True)
|
||||
# original / adopted / imported / serendipity
|
||||
source: Mapped[str] = mapped_column(String(40), nullable=False, default="original")
|
||||
name: Mapped[str] = mapped_column(String(120), nullable=False)
|
||||
description: Mapped[str | None] = mapped_column(Text)
|
||||
identity_baseline_json: Mapped[str] = mapped_column(Text, nullable=False, default="{}")
|
||||
# 照心试演引用:[{run_id, prompt, performed_at}],内容在事件日志,不入正式经历
|
||||
rehearsals_json: Mapped[str] = mapped_column(Text, nullable=False, default="[]")
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), default=utc_now, onupdate=utc_now
|
||||
)
|
||||
|
||||
|
||||
class Custodianship(Base):
|
||||
"""执镜关系:治理责任(1.0 一对一),与缘契(covenants)严格分离。"""
|
||||
|
||||
__tablename__ = "custodianships"
|
||||
|
||||
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_custodianship_id)
|
||||
character_id: Mapped[str] = mapped_column(
|
||||
String(80), ForeignKey("characters.id"), nullable=False, unique=True, index=True
|
||||
)
|
||||
custodian_scope: Mapped[str] = mapped_column(String(80), nullable=False, index=True)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
||||
|
||||
|
||||
class RuntimeSeat(Base):
|
||||
"""命台:人物唯一权威运行位置;holder 持有租约,过期可接管,epoch 每次获取递增。"""
|
||||
|
||||
__tablename__ = "runtime_seats"
|
||||
|
||||
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_seat_id)
|
||||
character_id: Mapped[str] = mapped_column(
|
||||
String(80), ForeignKey("characters.id"), nullable=False, unique=True, index=True
|
||||
)
|
||||
epoch: Mapped[int] = mapped_column(Integer, nullable=False, default=1)
|
||||
holder: Mapped[str | None] = mapped_column(String(120))
|
||||
lease_expires_at: Mapped[datetime | None] = mapped_column(DateTime(timezone=True))
|
||||
updated_at: Mapped[datetime] = mapped_column(
|
||||
DateTime(timezone=True), default=utc_now, onupdate=utc_now
|
||||
)
|
||||
|
||||
|
||||
class IdentityRecord(Base):
|
||||
"""魂籍:可验证、版本化的身份与状态包。版本不可变;复制不能凭相同 ID 冒充原人物。"""
|
||||
|
||||
__tablename__ = "identity_records"
|
||||
__table_args__ = (UniqueConstraint("character_id", "version", name="uq_identity_char_version"),)
|
||||
|
||||
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_identity_record_id)
|
||||
character_id: Mapped[str] = mapped_column(
|
||||
String(80), ForeignKey("characters.id"), nullable=False, index=True
|
||||
)
|
||||
version: Mapped[int] = mapped_column(Integer, nullable=False)
|
||||
payload_json: Mapped[str] = mapped_column(Text, nullable=False)
|
||||
digest: Mapped[str] = mapped_column(String(64), nullable=False)
|
||||
signature: Mapped[str] = mapped_column(String(128), nullable=False)
|
||||
created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=utc_now)
|
||||
@@ -14,11 +14,18 @@ class Run(Base):
|
||||
__tablename__ = "runs"
|
||||
|
||||
id: Mapped[str] = mapped_column(String(80), primary_key=True, default=new_run_id)
|
||||
character_id: Mapped[str] = mapped_column(String(80), ForeignKey("characters.id"), index=True)
|
||||
# rewrite/1.0:照心试演(kind=rehearsal)无正式人物,character_id 允许为空
|
||||
character_id: Mapped[str | None] = mapped_column(
|
||||
String(80), ForeignKey("characters.id"), index=True, nullable=True
|
||||
)
|
||||
session_id: Mapped[str | None] = mapped_column(
|
||||
String(80), ForeignKey("chat_sessions.id"), index=True
|
||||
)
|
||||
status: Mapped[str] = mapped_column(String(40), nullable=False, default="queued", index=True)
|
||||
# run.kind:foreground / background_task / awakening / rehearsal(契约词典 §8.2)
|
||||
kind: Mapped[str] = mapped_column(
|
||||
String(40), nullable=False, default="foreground", server_default="foreground"
|
||||
)
|
||||
goal: Mapped[str | None] = mapped_column(String(300))
|
||||
origin: Mapped[str] = mapped_column(String(40), nullable=False, default="chat")
|
||||
model_hint: Mapped[str | None] = mapped_column(String(120))
|
||||
|
||||
Reference in new issue
Block a user