ccs-align

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

CCS Align — Worker Watch seat (Phases 0–2 shipped; Phase 3 = verify / sign-off)

CCS Align — Worker Watch seat(Phase 0–2 已交付;Phase 3 = 验证 / 签核)

CCS Align is a standing seat, not a bird's-eye planner. Its one job, once an hour: talk to the local claude-mem worker, pull recent needle observations through the existing three-layer disclosure ladder, and land them in a seat-owned middle cache using grab → append → replace.
This skill implements the Phase 0 breathing slice, Phase 1 exclude marks, and Phase 2 rules alignment from the plan of record,
plans/2026-09-09-ccs-align.md
. Phases 0–2 are shipped and merged (#3934, #3935, #3936); Phase 3 is verify / sign-off (this loop) — no new product surface. It is not a context compiler, not Focus/mouth, and not Grok Memory Phase 2. When you speak to the human, address them as Alex.
CCS Align 是一个 常驻 seat,而不是鸟瞰式规划器。它唯一的任务是每小时运行一次:与 本地 claude-mem worker 通信,通过现有的三层披露阶梯拉取最近的 needle observations,并使用 grab → append → replace 将其写入 seat 自主管理的 middle cache。
本 skill 实现记录在案的计划
plans/2026-09-09-ccs-align.md
中的 Phase 0 呼吸切片、Phase 1 exclude marks 和 Phase 2 规则对齐。Phase 0–2 已交付并合并(#3934、#3935、#3936);Phase 3 是 验证 / 签核(即此循环)——不会新增任何产品界面。它 不是 context compiler,不是 Focus/mouth,也 不是 Grok Memory Phase 2。与人类交流时,应称呼其为 Alex。

What is implemented (Phases 0–2 shipped)

已实现内容(Phase 0–2 已交付)

  • Phase 0 — Breathing slice (#3934): health check →
    search
    →
    timeline
    →
    get_observations
    → append records to
    ~/.claude-mem/ccs-align/<viewerId>/middle.jsonl
    (atomic, deduped).
  • Phase 1 — Exclude marks (#3935): mark observations (and linked tool-use ids) as excluded from the compiled middle cache. "Purge" means the compiled
    middle.jsonl
    no longer contains the record — the diary / SQLite stay authoritative. Unmarking + rebuild restores the observation.
    DELETE /api/observation/:id
    is forbidden.
  • Phase 2 — Rules alignment (#3936): walk house → project → seat layers, detect conflicts (
    SHADOW_HOUSE
    ,
    DENY_ALLOW
    ,
    DRIFT
    ,
    CLOCK_HEADER
    ), emit an append-only
    rules-report.md
    . Optionally dry-run/apply
    SHADOW_HOUSE
    leaf patches when
    CLAUDE_MEM_CCS_ALIGN_PATCH_SHADOWS=true
    . Runs every 6th hour of the hourly Worker Watch cycle (D4). This is a checklist, not a parser — no
    .cas
    compiler.
  • Phase 3 — Verify / sign-off (this loop): re-run the regression tests and anti-pattern greps, prove the boundary (a scripted cycle dedupes, an exclude drops from the middle cache but not the diary, the rules report is produced or a MISS is recorded), and keep the skill + plan honest about what this seat is not. Phase 3 adds no new runtime behavior.
  • Does not: delete history, write
    profile.md
    , write LFG/Orifice
    [awareness]
    logs (that seam belongs to #3931), add a sixth
    processAgentResponse
    consumer, restart the worker, run a per-turn drip update, enforce Focus/mouth/standing rules, or copy house text into seats.
  • Phase 0 — 呼吸切片(#3934):health check →
    search
    →
    timeline
    →
    get_observations
    → 将记录原子化、去重后追加到
    ~/.claude-mem/ccs-align/<viewerId>/middle.jsonl
    。
  • Phase 1 — Exclude marks(#3935):将 observations(以及关联的 tool-use ids)标记为从已编译的 middle cache 中排除。「清除」意味着已编译的
    middle.jsonl
    不再包含该记录——diary / SQLite 仍是权威来源。取消标记并重建会恢复该 observation。禁止使用
    DELETE /api/observation/:id
    。
  • Phase 2 — 规则对齐(#3936):遍历 house → project → seat 层,检测冲突(
    SHADOW_HOUSE
    、
    DENY_ALLOW
    、
    DRIFT
    、
    CLOCK_HEADER
    ),生成仅追加的
    rules-report.md
    。当
    CLAUDE_MEM_CCS_ALIGN_PATCH_SHADOWS=true
    时,可选地试运行或应用
    SHADOW_HOUSE
    leaf 补丁。在每小时 Worker Watch 周期中,每第 6 个小时运行一次(D4)。这是一个 检查清单,而不是 parser——不存在
    .cas
    compiler。
  • Phase 3 — 验证 / 签核(此循环):重新运行回归测试和反模式 grep,验证边界(脚本化周期能够去重;exclude 后记录会从 middle cache 中消失但仍保留在 diary 中;能够生成 rules report 或记录 MISS),并让 skill + plan 如实说明此 seat 不是什么。Phase 3 不新增任何运行时行为。
  • **不执行:**删除历史、写入
    profile.md
    、写入 LFG/Orifice
    [awareness]
    日志(该接入点归 #3931 所有)、添加第六个
    processAgentResponse
    consumer、重启 worker、运行逐轮 drip update、执行 Focus/mouth/standing rules,或将 house 文本复制到 seats。

What this is NOT (honest boundary)

这不是什么(诚实的边界)

CCS Align is deliberately small. It does not ship, and this loop does not add, any of the following — these are future work or a different agent, called out so no one reads more into the seat than is there:
  • No context compiler. There is no
    .cas
    parser, no
    compileAwareness()
    , no JIT compile, no computed-styles UI. The CCS Notion page types (
    Bucket
    ,
    canRead
    ) are teaching copy quoted as comments — never a runtime parser.
  • No brainbeat product. The "regenerate awareness once per finished unit of work" door is not built. Align pulls on an hourly cadence; it is not a per-turn drip and it is not a brainbeat.
  • No attention trough / curse-salience. No salience decay, no trough scoring. Explicitly out of every phase.
  • No Focus / mouth enforcement. Standing rules (always / never / danger) are never enforced or decayed here. Align may list a conflict; egress filtering belongs to a different agent.
  • No second writer on LFG/Orifice
    [awareness]
    logs.
    #3931 owns
    agents/**/memory/log/YYYY-MM.md
    . Align writes only its seat-owned middle cache.
  • No history rewrite. Exclude marks filter the compiled cache; the diary / SQLite stay authoritative and rebuildable. No
    DELETE /api/observation
    , no A-MEM row rewrite.
CCS Align 刻意保持小巧。它不会交付、此循环也不会新增以下任何内容——这些属于未来工作或由其他 agent 负责,特此说明以免对 seat 的能力产生过度解读:
  • 没有 context compiler。 不存在
    .cas
    parser、
    compileAwareness()
    、JIT compile 或 computed-styles UI。CCS Notion 页面类型(
    Bucket
    、
    canRead
    )是作为注释引用的教学文案——绝不是运行时 parser。
  • 没有 brainbeat 产品。「每个完成的工作单元后重新生成 awareness」这一入口尚未构建。Align 按小时节奏主动 拉取;它不是逐轮 drip,也不是 brainbeat。
  • 没有 attention trough / curse-salience。 不存在 salience decay 或 trough scoring。明确不在任何阶段范围内。
  • 不执行 Focus / mouth 强制。 此处绝不会执行或衰减 standing rules(always / never / danger)。Align 可以 列出 冲突;egress filtering 属于另一个 agent。
  • 不会成为 LFG/Orifice
    [awareness]
    日志的第二个写入方。
    #3931 负责
    agents/**/memory/log/YYYY-MM.md
    。Align 只写入其 seat 自主管理的 middle cache。
  • 不会重写历史。 Exclude marks 过滤的是 已编译的 cache;diary / SQLite 仍是权威且可重建的来源。不使用
    DELETE /api/observation
    ,也不重写 A-MEM 行。

Ops MISS — worker plugin version lag

Ops MISS — worker plugin 版本滞后

As of this sign-off, the repo (package, plugin, marketplace) is at 13.24.5 (this Phase 3 PATCH), but the running worker plugin on the house box may still be 13.24.1. That is an operational MISS to record, not fix here: this seat does not restart or upgrade the worker (a hard forbid). If the live box still shows 13.24.1, note it when rolling status up to the Prioritizer so the worker gets restarted onto the current plugin out-of-band. If the running worker already matches the package version, this MISS is closed.
截至本次签核,仓库(package、plugin、marketplace)的版本为 13.24.5(本次 Phase 3 PATCH),但 house box 上运行的 worker plugin 可能仍为 13.24.1。这是一项 需要记录但不在此处修复的 Ops MISS:此 seat 不会重启或升级 worker(这是硬性禁止项)。如果实时 box 仍显示 13.24.1,请在向 Prioritizer 汇总状态时注明,以便通过带外方式将 worker 重启到当前 plugin。如果运行中的 worker 已与 package 版本一致,则此 MISS 已关闭。

Prerequisites

前置条件

The claude-mem worker must be running locally. This seat talks to the local worker (per-UID port ~
37700
), never the cloud CMEM MCP — cloud
observation:<base64>
ids are a different API and must not be mixed in.
Resolve the worker port once and reuse
$WORKER_PORT
in every curl below. This snippet is copied from the
timeline-report
skill and honors
CLAUDE_MEM_WORKER_PORT
→
~/.claude-mem/settings.json
→ the per-UID default
37700 + (uid % 100)
:
bash
WORKER_PORT="${CLAUDE_MEM_WORKER_PORT:-$(node -e "const fs=require('fs'),p=require('path'),os=require('os');const uid=(typeof process.getuid==='function'?process.getuid():77);const fallback=String(37700+(uid%100));try{const s=JSON.parse(fs.readFileSync(p.join(os.homedir(),'.claude-mem','settings.json'),'utf-8'));process.stdout.write(String(s.CLAUDE_MEM_WORKER_PORT||fallback));}catch{process.stdout.write(fallback);}" 2>/dev/null)}"
Do not hardcode port
37777
— ports are per-UID.
claude-mem worker 必须在本机运行。此 seat 与 本地 worker 通信(每个 UID 的端口约为
37700
),绝不与 cloud CMEM MCP 通信——cloud
observation:<base64>
ids 属于另一套 API,不得混用。
解析 worker 端口一次,并在下面的每个 curl 命令中复用
$WORKER_PORT
。
此代码片段复制自
timeline-report
skill,并遵循
CLAUDE_MEM_WORKER_PORT
→
~/.claude-mem/settings.json
→ 每个 UID 的默认值
37700 + (uid % 100)
:
bash
WORKER_PORT="${CLAUDE_MEM_WORKER_PORT:-$(node -e "const fs=require('fs'),p=require('path'),os=require('os');const uid=(typeof process.getuid==='function'?process.getuid():77);const fallback=String(37700+(uid%100));try{const s=JSON.parse(fs.readFileSync(p.join(os.homedir(),'.claude-mem','settings.json'),'utf-8'));process.stdout.write(String(s.CLAUDE_MEM_WORKER_PORT||fallback));}catch{process.stdout.write(fallback);}" 2>/dev/null)}"
不要将端口硬编码为
37777
——端口取决于 UID。

Settings

设置

Defaults live in
SettingsDefaultsManager.ts
; override in
~/.claude-mem/settings.json
:
KeyDefaultMeaning
CLAUDE_MEM_CCS_ALIGN_ENABLED
true
Master switch for the seat.
CLAUDE_MEM_CCS_ALIGN_VIEWER_IDS
ccs-align
Comma-separated viewer ids the seat maintains a cache for.
CLAUDE_MEM_CCS_ALIGN_TRIGGER_TYPES
decision,bugfix,security_alert,sensitive
Needle observation types to pull (copied from #3931's list, D6).
CLAUDE_MEM_CCS_ALIGN_PATCH_SHADOWS
false
Phase 2 rules-shadow patch gate. When
true
, the rules walker removes
SHADOW_HOUSE
duplicate lines from leaf files (atomic temp+rename). Default off — report-only.
Pilot viewer id is
ccs-align
. The seat may read LFG observations (agent id
521e962d-2ec3-4488-bfbc-54d5209ce118
) as a project filter, but must not write LFG/Orifice monthly logs or any
profile.md
.
默认值位于
SettingsDefaultsManager.ts
;可在
~/.claude-mem/settings.json
中覆盖:
键默认值含义
CLAUDE_MEM_CCS_ALIGN_ENABLED
true
此 seat 的总开关。
CLAUDE_MEM_CCS_ALIGN_VIEWER_IDS
ccs-align
此 seat 为其维护缓存的 viewer ids,以逗号分隔。
CLAUDE_MEM_CCS_ALIGN_TRIGGER_TYPES
decision,bugfix,security_alert,sensitive
要拉取的 needle observation 类型(复制自 #3931 的列表,D6)。
CLAUDE_MEM_CCS_ALIGN_PATCH_SHADOWS
false
Phase 2 rules-shadow 补丁开关。为
true
时,rules walker 会从 leaf 文件中移除
SHADOW_HOUSE
重复行(使用原子 temp+rename)。默认 关闭——仅生成报告。
试点 viewer id 为
ccs-align
。此 seat 可以读取 LFG observations(agent id
521e962d-2ec3-4488-bfbc-54d5209ce118
)作为 project filter,但 不得写入 LFG/Orifice 月度日志或任何
profile.md
。

Hourly cycle (Appendix A runbook)

每小时周期(Appendix A runbook)

Run this every hour on a weekday house board. One purpose. No watercooler. No "while I was here I also…".
every hour (weekday house board):
  1. Resolve WORKER_PORT (snippet above)
  2. GET /api/health || GET /health   → abort with a one-line miss if down
  3. search(obs_type=needles, limit=20) since cursor.lastObservationId
  4. timeline(anchor=newest)          → collect neighbor ids
  5. get_observations(ids=…)
  5b. (Phase 1, mark-time only) If excluding: get_tool_uses for tool ids → record on mark
  6. grab middle.jsonl → append new → filter exclude-marks → replace atomic
  7. if original-cache path set and not writable: append-only to middle.jsonl (already done)
  8. update cursor.json
  9. every 6th hour: rules walk → append rules-report.md   (Phase 2 — see below)
 10. Speak to Alex only on red (worker down, write refused, unexpected profile.md touch)
在每个工作日 house board 上每小时运行一次。只为一个目的。不闲聊。也不做「既然来了,顺便……」的事。
every hour (weekday house board):
  1. Resolve WORKER_PORT (snippet above)
  2. GET /api/health || GET /health   → abort with a one-line miss if down
  3. search(obs_type=needles, limit=20) since cursor.lastObservationId
  4. timeline(anchor=newest)          → collect neighbor ids
  5. get_observations(ids=…)
  5b. (Phase 1, mark-time only) If excluding: get_tool_uses for tool ids → record on mark
  6. grab middle.jsonl → append new → filter exclude-marks → replace atomic
  7. if original-cache path set and not writable: append-only to middle.jsonl (already done)
  8. update cursor.json
  9. every 6th hour: rules walk → append rules-report.md   (Phase 2 — see below)
 10. Speak to Alex only on red (worker down, write refused, unexpected profile.md touch)

Step 1 — Resolve the port

Step 1 — 解析端口

Use the
$WORKER_PORT
snippet above.
使用上面的
$WORKER_PORT
代码片段。

Step 2 — Prove worker health (prefer
/api/health
)

Step 2 — 证明 worker 健康(优先使用
/api/health
)

Prefer
GET /api/health
; also accept the viewer alias
GET /health
. The public worker docs still show
GET /health
and a
port
field — both are stale. Health does not return a port; use
GET /api/stats
(
worker.port
) if you need it.
bash
curl -sS "http://127.0.0.1:${WORKER_PORT}/api/health" || curl -sS "http://127.0.0.1:${WORKER_PORT}/health"
优先使用
GET /api/health
;也可接受 viewer 别名
GET /health
。公共 worker 文档仍显示
GET /health
和一个
port
字段——两者均已过时。Health 不会返回端口;如果需要端口,请使用
GET /api/stats
(
worker.port
)。
bash
curl -sS "http://127.0.0.1:${WORKER_PORT}/api/health" || curl -sS "http://127.0.0.1:${WORKER_PORT}/health"

expect a JSON body with "status":"ok". If the worker is down, abort with a

expect a JSON body with "status":"ok". If the worker is down, abort with a

one-line miss — do NOT start it, do NOT retry aggressively.

one-line miss — do NOT start it, do NOT retry aggressively.


If health cannot be proven (e.g. no live worker in a cloud VM), record a **MISS** and stop. Do not fabricate a cache cycle.

如果无法证明 worker 健康(例如 cloud VM 上没有运行中的 worker),请记录 **MISS** 并停止。不要伪造 cache 周期。

Step 3 — Pull through the three-layer ladder (in order)

Step 3 — 按顺序通过三层阶梯拉取

The disclosure order is
search
→
timeline
→
get_observations
. Never jump straight to
get_observations
, and do not call
get_tool_uses
in Phase 0 (that is Phase 1).
  1. search
    with the needle
    obs_type
    list (
    CLAUDE_MEM_CCS_ALIGN_TRIGGER_TYPES
    ),
    limit
    ≤ 20, optionally scoped by
    project
    . Use the cursor's
    lastObservationId
    to avoid re-pulling the whole diary.
    bash
    curl -sS "http://127.0.0.1:${WORKER_PORT}/api/search?query=*&type=decision&limit=20&format=json"
  2. timeline
    anchored on the newest hit. The worker's code default depth is 10 (
    SearchManager.ts
    ) — the MCP text that says "3" is stale, so omit the depths (worker applies 10) or pass
    10
    explicitly.
    bash
    curl -sS "http://127.0.0.1:${WORKER_PORT}/api/timeline?anchor=<newestObservationId>"
  3. get_observations
    for the ids you will actually cache.
    bash
    curl -sS -X POST "http://127.0.0.1:${WORKER_PORT}/api/observations/batch" \
      -H 'content-type: application/json' \
      -d '{"ids":[12345,12346]}'
The MCP twins are
search
→
timeline
→
get_observations
. Worker
get_observations
ids are numbers; do not pass cloud
observation:<base64>
ids into
/api/observations/batch
.
披露顺序为
search
→
timeline
→
get_observations
。绝不能直接跳到
get_observations
,Phase 0 中也 不得调用
get_tool_uses
(它属于 Phase 1)。
  1. 使用 needle
    obs_type
    列表(
    CLAUDE_MEM_CCS_ALIGN_TRIGGER_TYPES
    )、
    limit
    ≤ 20 调用
    search
    ,并可按
    project
    限定范围。使用 cursor 的
    lastObservationId
    ,避免重新拉取整个 diary。
    bash
    curl -sS "http://127.0.0.1:${WORKER_PORT}/api/search?query=*&type=decision&limit=20&format=json"
  2. 以最新命中项为锚点调用
    timeline
    。worker 的 代码默认深度为 10(
    SearchManager.ts
    )——MCP 文本中所说的「3」已经过时,因此应省略 depth(worker 会应用 10),或明确传入
    10
    。
    bash
    curl -sS "http://127.0.0.1:${WORKER_PORT}/api/timeline?anchor=<newestObservationId>"
  3. 对实际要缓存的 ids 调用
    get_observations
    。
    bash
    curl -sS -X POST "http://127.0.0.1:${WORKER_PORT}/api/observations/batch" \
      -H 'content-type: application/json' \
      -d '{"ids":[12345,12346]}'
对应的 MCP 工具是
search
→
timeline
→
get_observations
。worker 的
get_observations
ids 是 数字;不要将 cloud
observation:<base64>
ids 传入
/api/observations/batch
。

Step 4 — Grab → append → filter exclude-marks → replace (atomic middle cache)

Step 4 — Grab → append → filter exclude-marks → replace(原子 middle cache)

Land the observations with the seat helper
src/services/integrations/CcsAlignMiddleCache.ts
(
landObservationsInMiddleCache
). It copies the #3931 atomic primitive (
appendAwarenessLineAtomic
+
awarenessLineBody
) with exactly three changes: the tag is
[ccs-align]
, the path root is
~/.claude-mem/ccs-align/<viewerId>/
, and the file is
middle.jsonl
.
Phase 1 adds an exclude-marks filter inside the atomic pipeline:
grab:    read middle.jsonl if it exists, else empty
filter:  load exclude-marks.json; drop any record whose id is marked
append:  for each new observation id not already present AND not marked, append one record
replace: write temp + rename (copy appendAwarenessLineAtomic; never appendFileSync)
fallback: if an OPTIONAL original-cache path is set and not writable, skip grab/replace
          on that path and append timeline items to middle.jsonl only
There is no compiled laminate file in-repo, so the fallback resolves to "append to the seat file" — never invent a laminate.
Each line of
middle.jsonl
is one record. The shape is locked for Phase 0 (do not add fields):
json
{
  "v": 1,
  "id": 12345,
  "type": "decision",
  "title": "…",
  "created_at": "2026-09-09T00:00:00.000Z",
  "project": "claude-mem",
  "agent_id": null,
  "source": "worker",
  "line": "- 2026-09-09 [ccs-align] decision — «…»"
}
line
is
formatCcsAlignLine
: the awareness line format with the tag swapped, written by the same shared formatter, so the recalled text is sanitized (no tag framing or invisible characters) and fenced in
«…»
, truncated inside the fence to 500 chars. Dedupe is by observation
id
and by body (the line from
[ccs-align]
onward, date excluded), so the same fact on a new day is still skipped and the file does not grow on a repeat cycle.
A minimal invocation (bun/node):
ts
import { landObservationsInMiddleCache } from '../../src/services/integrations/CcsAlignMiddleCache.js';

landObservationsInMiddleCache({
  viewerId: 'ccs-align',
  observations: rowsFromGetObservations, // [{ id, type, title, subtitle, facts, created_at, project, agent_id }]
});
It never throws into the caller — a broken write path is logged and swallowed.
使用 seat helper
src/services/integrations/CcsAlignMiddleCache.ts
中的
landObservationsInMiddleCache
写入 observations。它复制 #3931 的原子原语(
appendAwarenessLineAtomic
+
awarenessLineBody
),仅做三处更改:tag 改为
[ccs-align]
,路径根目录改为
~/.claude-mem/ccs-align/<viewerId>/
,文件改为
middle.jsonl
。
Phase 1 在原子流水线内增加 exclude-marks 过滤器:
grab:    read middle.jsonl if it exists, else empty
filter:  load exclude-marks.json; drop any record whose id is marked
append:  for each new observation id not already present AND not marked, append one record
replace: write temp + rename (copy appendAwarenessLineAtomic; never appendFileSync)
fallback: if an OPTIONAL original-cache path is set and not writable, skip grab/replace
          on that path and append timeline items to middle.jsonl only
仓库中 没有 已编译的 laminate 文件,因此 fallback 会解析为「追加到 seat 文件」——绝不能虚构 laminate。
middle.jsonl
的每一行都是一条记录。Phase 0 的结构是 锁定的(不要添加字段):
json
{
  "v": 1,
  "id": 12345,
  "type": "decision",
  "title": "…",
  "created_at": "2026-09-09T00:00:00.000Z",
  "project": "claude-mem",
  "agent_id": null,
  "source": "worker",
  "line": "- 2026-09-09 [ccs-align] decision — «…»"
}
line
由
formatCcsAlignLine
生成:沿用 awareness line 格式,但替换 tag,并由同一个共享 formatter 写入,从而清理召回文本(不含 tag 框架或不可见字符),再将其置于
«…»
中,并在围栏内截断到 500 个字符。去重依据是 observation
id
以及正文(从
[ccs-align
开始、不含日期的行内容),因此同一天重复运行周期时,同一事实仍会被跳过,文件不会增长。
最小调用方式(bun/node):
ts
import { landObservationsInMiddleCache } from '../../src/services/integrations/CcsAlignMiddleCache.js';

landObservationsInMiddleCache({
  viewerId: 'ccs-align',
  observations: rowsFromGetObservations, // [{ id, type, title, subtitle, facts, created_at, project, agent_id }]
});
它 绝不会向调用方抛出异常——损坏的写入路径会被记录并吞掉。

Step 5 — Update the cursor

Step 5 — 更新 cursor

Write
~/.claude-mem/ccs-align/<viewerId>/cursor.json
so the next hour does not re-pull the whole diary:
json
{ "lastRunAt": "…", "lastObservationId": 12345, "healthPath": "/api/health", "workerPort": 37700 }
Use
writeCursor
from the helper (atomic temp + rename).
写入
~/.claude-mem/ccs-align/<viewerId>/cursor.json
,以免下一小时重新拉取整个 diary:
json
{ "lastRunAt": "…", "lastObservationId": 12345, "healthPath": "/api/health", "workerPort": 37700 }
使用 helper 中的
writeCursor
(原子 temp + rename)。

Step 6 — Speak only on red

Step 6 — 仅在红色告警时发言

Roll status up to the Prioritizer. Only speak to Alex on red: worker down, a write was refused, or an unexpected
profile.md
touch. Otherwise stay quiet.
将状态 向上汇总 给 Prioritizer。仅在红色告警时向 Alex 发言:worker 宕机、写入被拒绝,或意外触及
profile.md
。其他情况保持安静。

Phase 1 — Exclude marks

Phase 1 — Exclude marks

"Purge" means the compiled
middle.jsonl
no longer contains the observation or its tool I/O for that viewer. The diary stays. This is Secure Isolated Awareness + context-stripper — not delete.
「清除」意味着对于该 viewer,已编译的
middle.jsonl
不再包含该 observation 或其 tool I/O。diary 仍然保留。这是 Secure Isolated Awareness + context-stripper——不是删除。

Exclude-marks file

Exclude-marks 文件

Each viewer has
~/.claude-mem/ccs-align/<viewerId>/exclude-marks.json
:
json
{
  "v": 1,
  "marks": [
    {
      "observationId": 12345,
      "toolUseIds": ["toolu_01abc", 678],
      "reason": "sibling-wall|manual|stripper|secure-isolation",
      "markedAt": "2026-09-09T00:00:00.000Z",
      "markedBy": "ccs-align"
    }
  ]
}
Marks are managed by
addExcludeMark
/
removeExcludeMark
in
CcsAlignMiddleCache.ts
, or by manual JSON edit.
每个 viewer 都有
~/.claude-mem/ccs-align/<viewerId>/exclude-marks.json
:
json
{
  "v": 1,
  "marks": [
    {
      "observationId": 12345,
      "toolUseIds": ["toolu_01abc", 678],
      "reason": "sibling-wall|manual|stripper|secure-isolation",
      "markedAt": "2026-09-09T00:00:00.000Z",
      "markedBy": "ccs-align"
    }
  ]
}
可通过
CcsAlignMiddleCache.ts
中的
addExcludeMark
/
removeExcludeMark
管理 marks,也可手动编辑 JSON。

How marks get created (v1)

Marks 的创建方式(v1)

  1. Manual JSON edit — open
    exclude-marks.json
    and add a mark entry.
  2. Skill flag —
    exclude <observationId> --reason …
    (manual, sibling-wall, stripper, secure-isolation).
  3. No auto-promotion from chat text (poison surface — see Memory dig findings).
  1. 手动编辑 JSON——打开
    exclude-marks.json
    并添加一个 mark 条目。
  2. Skill flag——
    exclude <observationId> --reason …
    (manual、sibling-wall、stripper、secure-isolation)。
  3. 不会从聊天文本自动提升为标记(这是污染面——参见 Memory dig findings)。

Purge tools (compiled only)

清除工具(仅针对已编译内容)

When recording tool-use ids on a mark:
  1. After
    get_observations
    , if you need tool ids, call
    get_tool_uses
    /
    POST /api/tool-uses/batch
    (layer 4).
  2. Record those ids on the mark's
    toolUseIds
    array.
  3. Never persist raw
    tool_input
    /
    tool_response
    into
    middle.jsonl
    — layer 4 stays out of the laminate.
  4. Do not call
    DELETE /api/observation/:id
    — that tombstones the diary and breaks rebuild-from-history.
Warning:
get_tool_uses
is layer 4 of the progressive disclosure ladder. It returns raw tool I/O and should only be called at mark-time to capture tool-use ids for an exclude mark. Never call it during the normal hourly cycle. Never persist its
tool_input
/
tool_response
payloads into any cache file.
在标记时记录 tool-use ids:
  1. 在
    get_observations
    之后,如需 tool ids,请调用
    get_tool_uses
    /
    POST /api/tool-uses/batch
    (第 4 层)。
  2. 将这些 ids 记录到 mark 的
    toolUseIds
    数组中。
  3. 绝不将原始
    tool_input
    /
    tool_response
    持久化到
    middle.jsonl
    ——第 4 层不得进入 laminate。
  4. 不要调用
    DELETE /api/observation/:id
    ——它会将 diary 标记为 tombstone,并破坏从历史重建的能力。
警告:
get_tool_uses
是渐进式披露阶梯的 第 4 层。它会返回原始 tool I/O,只应在标记时调用,以捕获 exclude mark 所需的 tool-use ids。正常每小时周期中绝不调用它。也绝不能将其
tool_input
/
tool_response
payload 持久化到任何 cache 文件。

Unmark + rebuild

取消标记并重建

To restore a previously excluded observation:
  1. Remove the mark from
    exclude-marks.json
    (
    removeExcludeMark
    or manual edit).
  2. Re-pull the diary through the three-layer ladder (
    search
    →
    timeline
    →
    get_observations
    ).
  3. Call
    rebuildMiddleCache
    to clear and re-land the compiled file from the authoritative diary.
The observation reappears in
middle.jsonl
on the next cycle because the diary was never touched.
要恢复先前排除的 observation:
  1. 从
    exclude-marks.json
    中移除该标记(使用
    removeExcludeMark
    或手动编辑)。
  2. 通过三层阶梯重新拉取 diary(
    search
    →
    timeline
    →
    get_observations
    )。
  3. 调用
    rebuildMiddleCache
    ,从权威 diary 清除并重新写入已编译文件。
由于 diary 从未被修改,该 observation 会在下一个周期重新出现在
middle.jsonl
中。

Viewer isolation

Viewer 隔离

Each viewer's middle cache is independent:
  • ~/.claude-mem/ccs-align/viewer-a/middle.jsonl
  • ~/.claude-mem/ccs-align/viewer-b/middle.jsonl
Observations landed for viewer A never appear in viewer B's compiled file. Exclude marks for viewer A do not affect viewer B. This implements the Secure Isolated Awareness property: inject a unique eval token into viewer A's cache → run viewer B → assert A's token never appears in B's compiled file.
每个 viewer 的 middle cache 都是独立的:
  • ~/.claude-mem/ccs-align/viewer-a/middle.jsonl
  • ~/.claude-mem/ccs-align/viewer-b/middle.jsonl
为 viewer A 写入的 observations 永远不会出现在 viewer B 的已编译文件中。Viewer A 的 exclude marks 也不会影响 viewer B。这实现了 Secure Isolated Awareness 属性:向 viewer A 的 cache 注入一个唯一 eval token → 运行 viewer B → 断言 A 的 token 永远不会出现在 B 的已编译文件中。

Programmatic usage

程序化用法

ts
import {
  addExcludeMark,
  removeExcludeMark,
  rebuildMiddleCache,
  ccsAlignExcludeMarksPath,
  readExcludeMarks,
} from '../../src/services/integrations/CcsAlignMiddleCache.js';

const marksPath = ccsAlignExcludeMarksPath(dataRoot, 'ccs-align');

// Mark an observation as excluded (with optional tool-use ids)
addExcludeMark(marksPath, 12345, ['toolu_01abc'], 'manual');

// Unmark and rebuild
removeExcludeMark(marksPath, 12345);
rebuildMiddleCache({
  viewerId: 'ccs-align',
  observations: allObservationsFromDiary,
  dataRoot,
});
ts
import {
  addExcludeMark,
  removeExcludeMark,
  rebuildMiddleCache,
  ccsAlignExcludeMarksPath,
  readExcludeMarks,
} from '../../src/services/integrations/CcsAlignMiddleCache.js';

const marksPath = ccsAlignExcludeMarksPath(dataRoot, 'ccs-align');

// Mark an observation as excluded (with optional tool-use ids)
addExcludeMark(marksPath, 12345, ['toolu_01abc'], 'manual');

// Unmark and rebuild
removeExcludeMark(marksPath, 12345);
rebuildMiddleCache({
  viewerId: 'ccs-align',
  observations: allObservationsFromDiary,
  dataRoot,
});

Hard forbids (every phase)

硬性禁止项(适用于所有阶段)

  • ❌
    DELETE /api/observation/:id
    — tombstone ≠ exclude mark; breaks rebuild-from-history.
  • ❌ Writing LFG/Orifice
    [awareness]
    logs, or into any
    agents/**/memory/log/
    path.
  • ❌ Writing
    profile.md
    , user-memory, or project memory.
  • ❌ A top-of-prompt clock (timestamps belong on facts, not a cache header).
  • ❌
    POST /api/context/semantic
    (per-turn drip the awareness design forbids).
  • ❌ A sixth
    processAgentResponse
    consumer — CCS Align pulls; #3931 owns that seam.
  • ❌ Restarting the worker, or
    POST /api/settings
    .
  • ❌ Addressing the human as "Az". Always Alex.
  • ❌ Claiming a context compiler / brainbeat shipped. Those are future work.
  • ❌ "Fixing" deny/allow by flipping rules — report only.
  • ❌ Copying house text into seats — that is the bug this phase detects.
  • ❌ Building a
    .cas
    compiler so the report looks smarter.
  • ❌ Patching standing / Focus / always / never / danger files.
  • ❌ Attention trough / curse-salience experiments (Phase-N backlog only).
  • ❌
    DELETE /api/observation/:id
    ——tombstone ≠ exclude mark;它会破坏从历史重建的能力。
  • ❌ 写入 LFG/Orifice
    [awareness]
    日志,或写入任何
    agents/**/memory/log/
    路径。
  • ❌ 写入
    profile.md
    、user-memory 或 project memory。
  • ❌ 在 prompt 顶部添加 clock(时间戳应属于事实,而不是 cache header)。
  • ❌
    POST /api/context/semantic
    (awareness 设计禁止逐轮 drip)。
  • ❌ 添加第六个
    processAgentResponse
    consumer——CCS Align 采用 拉取 模式;该接入点归 #3931 所有。
  • ❌ 重启 worker,或调用
    POST /api/settings
    。
  • ❌ 将人类称为「Az」。始终称呼 Alex。
  • ❌ 宣称 context compiler / brainbeat 已交付。那些属于未来工作。
  • ❌ 通过翻转规则来「修复」deny/allow——仅生成报告。
  • ❌ 将 house 文本复制到 seats——这正是本阶段要检测的 bug。
  • ❌ 构建
    .cas
    compiler 来让报告看起来更智能。
  • ❌ 修改 standing / Focus / always / never / danger 文件。
  • ❌ 进行 attention trough / curse-salience 实验(仅属于 Phase-N backlog)。

Phase 2 — Rules alignment (house → project → seat)

Phase 2 — 规则对齐(house → project → seat)

Every 6th hour of the hourly Worker Watch cycle (D4), the seat walks house → project → seat layers to detect and report rules conflicts. This is a checklist, not a parser. No
.cas
compiler.
在每小时 Worker Watch 周期中,每第 6 个小时(D4),此 seat 会遍历 house → project → seat 层,以检测并报告规则冲突。这是一个 检查清单,而不是 parser。不存在
.cas
compiler。

Cascade rules (from Notion CCS)

层叠规则(来自 Notion CCS)

  • Write once at HOUSE; seats inherit
  • A leaf copy shadows the cascade (bug, not feature)
  • Deny beats allow
  • Siblings deny heavy buckets (
    obs
    ,
    note
    ,
    person
    ) by default
  • Fail closed: if no rule exists, deny
  • 在 HOUSE 写入一次;seats 继承
  • leaf 副本会 遮蔽 层叠规则(这是 bug,不是功能)
  • Deny 优先于 Allow
  • 默认情况下,siblings 拒绝重度 buckets(
    obs
    、
    note
    、
    person
    )
  • Fail closed:如果不存在规则,则拒绝

Layer walk

层遍历

LayerWhere to look (house box)Bucket
House
user-memory/
shared profile; Notion CCS
:root
profile
,
standing
,
owns
Project
.cmem-projects/<project>/
, repo
CLAUDE.md
project overrides
Seat
agents/<uuid>/profile.md
,
agents/<uuid>/memory/
leaf — must not duplicate house
On a box with no agent-data tree, the report records
MISS: house-box paths
and exits cleanly.
层查找位置(house box)Bucket
House
user-memory/
共享 profile;Notion CCS
:root
profile
、
standing
、
owns
Project
.cmem-projects/<project>/
、仓库
CLAUDE.md
项目覆盖规则
Seat
agents/<uuid>/profile.md
、
agents/<uuid>/memory/
leaf——不得复制 house 内容
在缺少 agent-data tree 的 box 上,报告会记录
MISS: house-box paths
并干净退出。

Conflict classes (v1)

冲突类别(v1)

CodePatternAgency
SHADOW_HOUSE
Leaf file contains a line that also exists at house (or starts with
House rule
)
Dry-run remove-from-leaf; apply only if
CLAUDE_MEM_CCS_ALIGN_PATCH_SHADOWS=true
DENY_ALLOW
Same bucket allow at one layer, deny at anotherReport only
DRIFT
House text changed; leaf still has old wording (partial prefix match)Report only
CLOCK_HEADER
Top-of-prompt clock / "current time is" in a profileReport only (house rule: no clock in the prefix)
代码模式处理方式
SHADOW_HOUSE
Leaf 文件包含 house 中也存在的行,或以
House rule
开头
试运行并从 leaf 移除;仅当
CLAUDE_MEM_CCS_ALIGN_PATCH_SHADOWS=true
时应用
DENY_ALLOW
同一 bucket 在一个层为 allow,在另一个层为 deny仅报告
DRIFT
House 文本已更改,但 leaf 仍保留旧措辞(部分前缀匹配)仅报告
CLOCK_HEADER
Profile 中存在 prompt 顶部 clock /「current time is」仅报告(house 规则:prefix 中不得有时钟)

Rules report

Rules report

Output:
~/.claude-mem/ccs-align/<viewerId>/rules-report.md
— dated, append-only sections. Each run appends a new section with a timestamp, a table of conflicts, any MISS entries, and a patches-applied count. Status rolls up to Prioritizer (never peer spam).
输出:
~/.claude-mem/ccs-align/<viewerId>/rules-report.md
——包含日期且仅追加的章节。每次运行都会追加一个新章节,其中包括时间戳、冲突表、所有 MISS 条目和已应用补丁数。状态会 向上汇总 给 Prioritizer(绝不向同级 agent 发送 spam)。

Limited patch (D8 default off)

有限补丁(D8 默认关闭)

When
CLAUDE_MEM_CCS_ALIGN_PATCH_SHADOWS=true
:
  1. Only
    SHADOW_HOUSE
    conflicts are patched — never
    DENY_ALLOW
    ,
    DRIFT
    , or
    CLOCK_HEADER
    .
  2. The would-be diff is written into the report before any patch is applied.
  3. The leaf file is copied, duplicate lines are stripped, and the file is replaced atomically (temp + rename, same primitive as
    CcsAlignMiddleCache
    ).
  4. Never patches
    standing
    / Focus /
    always.md
    /
    never.md
    /
    danger.md
    /
    profile.md
    .
  5. House files are never modified.
当
CLAUDE_MEM_CCS_ALIGN_PATCH_SHADOWS=true
时:
  1. 仅修补
    SHADOW_HOUSE
    冲突——绝不修补
    DENY_ALLOW
    、
    DRIFT
    或
    CLOCK_HEADER
    。
  2. 拟应用的 diff 会在应用任何补丁 之前 写入报告。
  3. 复制 leaf 文件、移除重复行,然后使用原子方式替换文件(temp + rename,与
    CcsAlignMiddleCache
    使用相同的原语)。
  4. 绝不修补
    standing
    / Focus /
    always.md
    /
    never.md
    /
    danger.md
    /
    profile.md
    。
  5. House 文件绝不会被修改。

Programmatic usage

程序化用法

ts
import {
  walkRules,
  discoverLayerPaths,
  type RulesWalkerConfig,
} from '../../src/services/integrations/CcsAlignRulesWalker.js';

// Discover paths on the current box
const paths = discoverLayerPaths({ project: 'claude-mem' });

const config: RulesWalkerConfig = {
  dataRoot: '~/.claude-mem',
  viewerId: 'ccs-align',
  patchShadows: false,  // report-only by default
  housePaths: paths.housePaths,
  projectPaths: paths.projectPaths,
  seatPaths: paths.seatPaths,
};

const result = walkRules(config);
// result.conflicts — array of detected conflicts
// result.misses — paths that were not found
// result.reportPath — path to the appended rules-report.md
// result.patchesApplied — number of SHADOW_HOUSE lines removed (0 if patchShadows=false)
ts
import {
  walkRules,
  discoverLayerPaths,
  type RulesWalkerConfig,
} from '../../src/services/integrations/CcsAlignRulesWalker.js';

// Discover paths on the current box
const paths = discoverLayerPaths({ project: 'claude-mem' });

const config: RulesWalkerConfig = {
  dataRoot: '~/.claude-mem',
  viewerId: 'ccs-align',
  patchShadows: false,  // report-only by default
  housePaths: paths.housePaths,
  projectPaths: paths.projectPaths,
  seatPaths: paths.seatPaths,
};

const result = walkRules(config);
// result.conflicts — array of detected conflicts
// result.misses — paths that were not found
// result.reportPath — path to the appended rules-report.md
// result.patchesApplied — number of SHADOW_HOUSE lines removed (0 if patchShadows=false)

Phase 3 — Verify / sign-off (plan §3)

Phase 3 — 验证 / 签核(计划 §3)

Phase 3 closes the plan loop. It proves the seat is hourly-runnable, documented, and honest about what it is not — it does not add runtime behavior.
Prove the boundary, not the code (§3.1):
  • One scripted cycle: health →
    search
    →
    timeline
    →
    get_observations
    →
    middle.jsonl
    .
  • A second cycle produces no duplicate lines (dedupe holds).
  • Exclude one id → gone from the middle cache, still returned by the worker (
    GET /api/observation/N
    ).
  • A rules report is produced (or an explicit
    MISS
    on a box with no agent-data tree).
  • User-facing strings say Alex, never "Az"; no "context compiler shipped / brainbeat is live / we compiled awareness" claims (only future / not-this-plan wording).
Prove nothing regressed (§3.2): run the tests in the Verification section below, including the #3931 pusher and transcript tests. #3931 behavior must stay: LFG/Orifice still get
[awareness]
lines from the worker pusher, not from Align.
Anti-pattern grep (§3.3): no
DELETE /api/observation
, no
notifyGrokBotAwareness
, no
processAgentResponse
reuse in the seat helpers (forbid/comment mentions are fine — the seat must not use them).
Sign-off (§3.4): this skill can be run by a Worker Watch seat with no extra product context; the shipped defaults still match the D-rows; the Prioritizer can roll this up as "CCS Align Phase 0 green / Phase 1 marks / Phase 2 report."
See
plans/2026-09-09-ccs-align.md
§3 for the full contract.
Phase 3 闭合计划循环。它证明此 seat 可以按小时运行、文档齐全,并且如实说明自身边界——不会新增运行时行为。
验证边界,而不是代码(§3.1):
  • 一个脚本化周期:health →
    search
    →
    timeline
    →
    get_observations
    →
    middle.jsonl
    。
  • 第二个周期不会产生重复行(去重有效)。
  • 排除一个 id → 从 middle cache 中消失,但仍由 worker 返回(
    GET /api/observation/N
    )。
  • 生成 rules report(或在缺少 agent-data tree 的 box 上记录明确的
    MISS
    )。
  • 面向用户的字符串应使用 Alex,绝不能使用「Az」;不得出现「context compiler 已交付 / brainbeat 已上线 / 我们编译了 awareness」之类的声明(只能使用未来工作 / 不属于本计划的措辞)。
**证明没有回归(§3.2):**运行下方 Verification 部分中的测试,包括 #3931 pusher 和 transcript 测试。必须保持 #3931 的行为:LFG/Orifice 仍从 worker pusher 获得
[awareness]
行,而不是从 Align 获得。
**反模式 grep(§3.3):**不得出现
DELETE /api/observation
、
notifyGrokBotAwareness
,seat helpers 中也不得复用
processAgentResponse
(禁止项或注释中的提及没有关系——seat 绝不能 使用 它们)。
**签核(§3.4):**此 skill 可以由 Worker Watch seat 在没有额外产品上下文的情况下运行;已交付的默认配置仍符合 D 行;Prioritizer 可以向上汇总为「CCS Align Phase 0 green / Phase 1 marks / Phase 2 report」。
有关完整契约,请参阅
plans/2026-09-09-ccs-align.md
§3。

Later phases (documented, not implemented)

后续阶段(仅记录,尚未实现)

  • Full brainbeat / context compiler /
    .cas
    runtime
    — future work, paper scaffold, out of this plan.
  • Attention trough / curse-salience, Focus/mouth egress enforcement — different agents / backlog; hard forbids here.
See
plans/2026-09-09-ccs-align.md
"Explicit non-goals" for the full list.
  • 完整 brainbeat / context compiler /
    .cas
    runtime
    ——未来工作、paper scaffold,不在本计划范围内。
  • Attention trough / curse-salience、Focus/mouth egress enforcement——属于其他 agent / backlog;这里对此有硬性禁止。
完整列表请参阅
plans/2026-09-09-ccs-align.md
的「Explicit non-goals」。

Verification (Phase 0 + Phase 1 + Phase 2)

Verification(Phase 0 + Phase 1 + Phase 2)

bash
bun test tests/integrations/ccs-align-middle-cache.test.ts
bash
bun test tests/integrations/ccs-align-middle-cache.test.ts

Phase 0: format/truncate, needle match, append, dedupe, path safety, never-throw, cursor round-trip

Phase 0: format/truncate, needle match, append, dedupe, path safety, never-throw, cursor round-trip

Phase 1: mark drop, diary present, tool ids not in middle.jsonl, viewer isolation,

Phase 1: mark drop, diary present, tool ids not in middle.jsonl, viewer isolation,

unmark+rebuild, exclude-marks round-trip, buildExcludeSet, secure-isolation,

unmark+rebuild, exclude-marks round-trip, buildExcludeSet, secure-isolation,

corrupt marks fail-closed, marked ids skipped on ingest

corrupt marks fail-closed, marked ids skipped on ingest

bun test tests/integrations/ccs-align-rules-walker.test.ts
bun test tests/integrations/ccs-align-rules-walker.test.ts

Phase 2: SHADOW_HOUSE detection (exact dup + "House rule" prefix), default report-only

Phase 2: SHADOW_HOUSE detection (exact dup + "House rule" prefix), default report-only

(leaf unchanged), patchShadows=true (leaf loses duplicates, house unchanged),

(leaf unchanged), patchShadows=true (leaf loses duplicates, house unchanged),

never patches standing/always/never, MISS on absent paths, CLOCK_HEADER detection,

never patches standing/always/never, MISS on absent paths, CLOCK_HEADER detection,

DENY_ALLOW detection, DRIFT detection, append-only report, atomic patch,

DENY_ALLOW detection, DRIFT detection, append-only report, atomic patch,

full walkRules integration, edge cases

full walkRules integration, edge cases

#3931 must not regress — LFG/Orifice still get [awareness] lines from the worker pusher, not Align

#3931 must not regress — LFG/Orifice still get [awareness] lines from the worker pusher, not Align

bun test tests/integrations/grok-bot-awareness-pusher.test.ts

Verification greps (plan §2.3):

```bash
bun test tests/integrations/grok-bot-awareness-pusher.test.ts

验证 grep(计划 §2.3):

```bash

Report path documented

Report path documented

rg -n "rules-report" plugin/skills/ccs-align/SKILL.md
rg -n "rules-report" plugin/skills/ccs-align/SKILL.md

expect ≥1

expect ≥1

Patch gated

Patch gated

rg -n "CCS_ALIGN_PATCH_SHADOWS" plugin/skills/ccs-align/SKILL.md
rg -n "CCS_ALIGN_PATCH_SHADOWS" plugin/skills/ccs-align/SKILL.md

expect ≥1

expect ≥1


Live-box checks (house, not CI — a cloud VM may have no live worker; record a MISS if so):

- `curl -sS "http://127.0.0.1:$WORKER_PORT/api/health"` returns `status: ok`
- After one cycle, `~/.claude-mem/ccs-align/ccs-align/middle.jsonl` exists
- A second cycle with the same observations does **not** grow the file (dedupe)
- Mark observation N → next cycle drops N from `middle.jsonl`
- SQLite / `GET /api/observation/N` still returns the row (diary is authoritative)
- Linked tool-use ids on the mark never appear in `middle.jsonl`
- Viewer B's cache does not contain viewer A's unique eval token
- Unmark (remove from JSON) + cycle restores N on the next pull
- `profile.md` under any `agents/` path is byte-identical to before
- LFG/Orifice `memory/log/YYYY-MM.md` unchanged by Align

实机检查(在 house 上执行而非 CI——cloud VM 可能没有运行中的 worker;如无则记录 MISS):

- `curl -sS "http://127.0.0.1:$WORKER_PORT/api/health"` 返回 `status: ok`
- 运行一个周期后,`~/.claude-mem/ccs-align/ccs-align/middle.jsonl` 存在
- 使用相同 observations 运行第二个周期时,文件 **不会**增长(去重有效)
- 标记 observation N → 下一个周期会从 `middle.jsonl` 中移除 N
- SQLite / `GET /api/observation/N` 仍会返回该行(diary 是权威来源)
- 标记中关联的 tool-use ids 永远不会出现在 `middle.jsonl` 中
- Viewer B 的 cache 不包含 Viewer A 的唯一 eval token
- 取消标记(从 JSON 中移除)+ 运行周期后,下一次拉取会恢复 N
- 任意 `agents/` 路径下的 `profile.md` 与之前逐字节一致
- LFG/Orifice `memory/log/YYYY-MM.md` 未被 Align 修改