feat: 人格編號(ASUNA-01)與 Gitea 儲存,依更新頻率分檔案區/Wiki 區
1. 人格編號
- 編號 = 英文名全大寫 + 兩位索引,同名才遞增:ASUNA-01 / YUI-01 / ASUNA-02。
- 編號同時是新人格的本機目錄名與 Gitea 存取庫名稱(`create` 不給
--persona 就用編號當目錄名;既有小寫 slug 仍然合法,不會被鎖在門外)。
- 中文名由 skill 提議羅馬拼音、使用者確認後帶 `--romaji` 進來;
CLI 只吃拉丁字母,避免拼音在程式裡亂猜。
- 新增 `code show|assign|next`;`code assign --rename` 可把既有人格的
目錄名一併改成編號(會轉移鎖與 session 綁定)。
2. Gitea 儲存(scripts/persona-gitea.mjs)
- 每個人格一個私有存取庫,庫名 = 編號。本機仍是工作副本,hook 每輪
讀寫本機檔案,**同步失敗永遠不阻斷對話**。
- 依更新頻率分區:
檔案區(高頻)emotion / short-term / inner / said / inbox /
mindmap threads / journal → 每輪由 Stop hook 背景 push
Wiki 區(低頻)IDENTITY SOUL AGENTS USER / 長期記憶 / INDEX /
心智圖 / 關係圖 → 固化、改身分關係、release 時 push
- Gitea 的 wiki 只有根目錄 .md 會變成頁面(1.27 實測子目錄頁面 404),
所以 Wiki 區攤平成 `Memory-xxx.md`,原始路徑記在 `_paths.json`,
pull 時還原;Home 頁自動列出所有長期記憶連結。
- 新增 `sync status|init|push|pull`;載入時先 pull,兩邊都改過同一個
檔案就停下來不覆蓋本機,交由使用者決定。
- push 遇到 non-fast-forward 會對齊遠端後把工作副本重新疊上去再推。
- 認證走 http.extraHeader(GIT_CONFIG_* 環境變數),token 不寫進
.git/config 也不進 process 參數。
3. 順帶修正
- guard 的 `--persona` 解析原本只吃小寫,大寫編號會漏掉整個跨人格檢查。
- pull 原本會無差別覆蓋本機檔案,本機較新但還沒 push 的內容會被蓋掉;
改成只寫回「遠端真的改過的」與「本機缺少的」。
- `create` 原本吞掉 Gitea 首次推送的結果,失敗是靜默的。
新增 skill:persona-sync(編號、同步、既有人格遷移、衝突處理)。
selftest 116 項全綠(新增 ⑬,含「分區不重不漏」檢查;測試強制 PERSONA_GITEA=off)。
另對真實 Gitea 跑過端對端(建庫→兩區推送→改動→拉回→release),測試用存取庫已刪除。
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -10,7 +10,7 @@ skills 是共通標準,**鎖與隔離的強制執行需要 hook,目前只有
|
||||
|
||||
---
|
||||
|
||||
## 九條硬規則
|
||||
## 十一條硬規則
|
||||
|
||||
| 規則 | 怎麼做到 |
|
||||
| --- | --- |
|
||||
@@ -24,6 +24,8 @@ skills 是共通標準,**鎖與隔離的強制執行需要 hook,目前只有
|
||||
| **7. 短期記憶轉入長期記憶有成文條件** | `R1`–`R6` 六條規則寫在程式裡(`promotionCandidates`),`candidates` 子指令會列出達標的候選與依據,hook 在達標時提醒固化 |
|
||||
| **8. 講話像人:推導藏起來、一到三句、不重複** | 推導寫進**心裡話** `think`(只回報「💭 心想 N 句」,永不回顯內容);說出口的話進 `said.jsonl`,下一輪注入「最近說過的話」提醒別重講;`room post` 直接**擋下**近似重複(字元 bigram+字集合相似度 ≥ 0.72)與超過三句的發言——劇場模式同樣適用 |
|
||||
| **9. 人格可以匯出匯入** | `export` 把身分/情緒/記憶/心智圖/關係圖打包成單一 JSON bundle(可 `--gzip`、附 sha256),`import` 還原或換名複製;**不帶**載入鎖與 guest 租約,`journal/` 要明確 `--with-journal` 才帶走 |
|
||||
| **10. 人格有編號** | 編號 = **英文名全大寫 + 兩位索引**(同名才遞增):`ASUNA-01`、`YUI-01`、`ASUNA-02`。編號同時是新人格的本機目錄名與 Gitea 存取庫名稱;中文名先轉羅馬拼音並跟使用者確認拼法 |
|
||||
| **11. 人格存在 Gitea,依更新頻率分區** | 每個人格一個**私有存取庫**(庫名=編號)。**檔案區**放每輪都在變的活狀態(情緒/短期記憶/心裡話/說過的話/逐字),**Wiki 區**放低頻的身分與長期結構(IDENTITY/SOUL/長期記憶/心智圖/關係圖)當設定百科。本機仍是工作副本,同步失敗不阻斷對話 |
|
||||
|
||||
---
|
||||
|
||||
@@ -43,15 +45,23 @@ flowchart TB
|
||||
subgraph G["Sub Agent(受邀人格,唯讀)"]
|
||||
GA["persona-guest"]
|
||||
end
|
||||
subgraph S["人格倉庫 ~/.claude/personas"]
|
||||
PA["alpha/|IDENTITY SOUL 記憶 情緒 心智圖 關係圖"]
|
||||
PB["beta/|…"]
|
||||
subgraph S["人格倉庫 ~/.claude/personas(工作副本)"]
|
||||
PA["ASUNA-01/|IDENTITY SOUL 記憶 情緒 心智圖 關係圖"]
|
||||
PB["YUI-01/|…"]
|
||||
RM[".rooms/room/transcript.jsonl"]
|
||||
end
|
||||
subgraph GT["Gitea(存取庫名稱 = 人格編號)"]
|
||||
GF["ASUNA-01 檔案區<br/>高頻活狀態"]
|
||||
GW["ASUNA-01 Wiki<br/>低頻設定百科"]
|
||||
end
|
||||
P -->|"只能碰自己"| PA
|
||||
GA -->|"只能碰自己"| PB
|
||||
P <-->|"唯一合法交流管道"| RM
|
||||
GA <--> RM
|
||||
PA -->|"每輪背景 push"| GF
|
||||
PA -->|"固化/改身分/release"| GW
|
||||
GF -.->|"載入時 pull"| PA
|
||||
GW -.-> PA
|
||||
```
|
||||
|
||||
## 人格倉庫(預設 `~/.claude/personas/<slug>/`,可用 `PERSONA_HOME` 覆寫)
|
||||
@@ -68,7 +78,8 @@ flowchart TB
|
||||
│ ├── emotion.json # 十二情緒 levels / baseline / 半衰期
|
||||
│ ├── inner.jsonl # 心裡話(推導過程;只回報「心想 N 句」,不說出口)
|
||||
│ ├── said.jsonl # 說過的話(用來擋短時間內的重複發言)
|
||||
│ └── config.json
|
||||
│ ├── sync.json # Gitea 同步狀態(最後 push / pull)
|
||||
│ └── config.json # 含人格編號 code
|
||||
├── memory/
|
||||
│ ├── short-term.jsonl # 短期記憶(語意分析後;上限 240 筆 / 14 天)
|
||||
│ ├── long-term/*.md # 長期記憶(一則一檔 + frontmatter)
|
||||
@@ -81,6 +92,8 @@ flowchart TB
|
||||
│ ├── graph.json # 人際關係圖(親近度/信任度/連線)
|
||||
│ └── graph.mmd # Mermaid 呈現(自動產生)
|
||||
└── journal/YYYY-MM.jsonl # 原始逐字 + 情緒史(hook 自動寫)
|
||||
|
||||
(另有 `.sync/files/`、`.sync/wiki/`:兩個同步區的 git clone 快取,可安全刪除)
|
||||
```
|
||||
|
||||
## 十二情緒
|
||||
@@ -129,6 +142,40 @@ AI 最容易露餡的三件事:把推理過程講出來、一次講一大段
|
||||
|
||||
視窗預設 120 分鐘、少於 8 個字的短附和(「嗯」「好啊」)不算重複。
|
||||
|
||||
## 人格編號與 Gitea 儲存
|
||||
|
||||
**編號 = 英文名全大寫 + 兩位索引**,同名才遞增,也就是 Gitea 存取庫的名稱:
|
||||
|
||||
```
|
||||
亞絲娜(第一個) → ASUNA-01 結衣 → YUI-01 另一個亞絲娜 → ASUNA-02
|
||||
```
|
||||
|
||||
每個人格一個**私有存取庫**,內容依**更新頻率**分兩區:
|
||||
|
||||
| 區 | 放什麼 | 何時 push |
|
||||
| --- | --- | --- |
|
||||
| **檔案區**(主存取庫) | 高頻活狀態:`emotion.json`、`short-term.jsonl`、`inner.jsonl`、`said.jsonl`、`inbox/`、`mindmap/threads/`、`journal/` | 每輪對話後由 `Stop` hook 背景推送(`PERSONA_SYNC_MIN_SECONDS` 節流) |
|
||||
| **Wiki 區** | 低頻設定:`IDENTITY`/`SOUL`/`AGENTS`/`USER`、長期記憶、`INDEX`、心智圖、關係圖 | 記憶固化、改身分/關係圖、`release` 時 |
|
||||
|
||||
- **本機永遠是工作副本**:hook 每輪讀寫本機檔案,不經網路;Gitea 掛掉照樣能聊天。
|
||||
**同步失敗永遠不阻斷對話。**
|
||||
- 載入人格時會先 `pull`;兩邊都改過同一個檔案就**停下來不覆蓋本機**,由使用者決定保留哪一邊。
|
||||
- Gitea 的 wiki 只有根目錄的 `.md` 會變成頁面(1.27 實測子目錄頁面 404),所以
|
||||
`memory/long-term/xxx.md` 攤平成 `Memory-xxx.md`,原始路徑記在 `_paths.json`;
|
||||
Wiki 首頁自動列出所有長期記憶的連結,變成真的讀得下去的「設定百科」。
|
||||
|
||||
```bash
|
||||
export GITEA_HOST=https://gitea.example.com
|
||||
export GITEA_TOKEN=<個人存取權杖>
|
||||
export PERSONA_GITEA_OWNER=<帳號或組織> # 選填,預設 token 本人
|
||||
export PERSONA_GITEA=off # 需要時整個關掉
|
||||
|
||||
node scripts/persona.mjs code assign --session <id> --romaji Asuna --rename # 既有人格遷移
|
||||
node scripts/persona.mjs sync status|init|push|pull --session <id> [--area files|wiki|all]
|
||||
```
|
||||
|
||||
存取庫**預設私有**——人格裡是使用者的個人記憶,公開必須由使用者明講(`--public`)。
|
||||
|
||||
## 匯出 / 匯入(人格搬家)
|
||||
|
||||
```bash
|
||||
@@ -208,6 +255,12 @@ node scripts/persona.mjs import --session <id> --file ~/backup/lumi.persona.json
|
||||
|
||||
- **Claude Code / Antigravity**:`/jsc-persona:persona-transfer` **Codex**:`$persona-transfer`
|
||||
|
||||
### `persona-sync`
|
||||
|
||||
人格編號與 Gitea 儲存:指派編號(`ASUNA-01`)、開以編號命名的私有存取庫、高頻活狀態同步到檔案區、低頻身分與長期記憶同步到 Wiki 區,並處理既有人格遷移與同步衝突。
|
||||
|
||||
- **Claude Code / Antigravity**:`/jsc-persona:persona-sync` **Codex**:`$persona-sync`
|
||||
|
||||
### `persona-memory`
|
||||
|
||||
記憶固化:依 R1–R6 條件把短期記憶轉入長期(一則一檔)、淘汰雜訊、更新心智圖與思維導圖、消化 guest inbox、重建索引。
|
||||
@@ -243,12 +296,13 @@ node scripts/persona.mjs candidates --session <PERSONA_SESSION> # 看哪些短
|
||||
node scripts/persona.mjs think --session <id> --text "<推導>" # 心裡話(只回報「心想 N 句」)
|
||||
node scripts/persona.mjs said check --session <id> --text "<話>" # 這句是不是又要說一次?
|
||||
node scripts/persona.mjs room script --session <id> --room <room> # 乾淨對話稿(劇場模式用)
|
||||
node scripts/persona.mjs export --session <id> --out lumi.json # 人格搬家
|
||||
node scripts/selftest.mjs # 102 項驗證:鎖、隔離、情緒、固化條件、說話節制、劇場模式、匯出匯入、hooks
|
||||
node scripts/persona.mjs export --session <id> --out lumi.json # 離線搬家(單檔)
|
||||
node scripts/persona.mjs sync status --session <id> # Gitea 同步狀態
|
||||
node scripts/selftest.mjs # 116 項驗證:鎖、隔離、情緒、固化、說話節制、劇場模式、匯出匯入、編號與 Gitea 分區、hooks
|
||||
```
|
||||
|
||||
檔案結構:`scripts/persona-lib.mjs`(核心:鎖/隔離/情緒/記憶)、`scripts/persona.mjs`(CLI)、
|
||||
`hooks/*.mjs`(六個 hook)、`scripts/selftest.mjs`(自我測試)。
|
||||
`scripts/persona-gitea.mjs`(編號與 Gitea 同步)、`hooks/*.mjs`(六個 hook)、`scripts/selftest.mjs`(自我測試)。
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user