docs: rewrite README + add CONTRIBUTING guide

- README: update Rule signature to onion middleware, add architecture diagram,
  document watchers/survival/storage, link all RFCs
- CONTRIBUTING: code structure, architecture, dev workflow, testing conventions,
  Cursor Agent usage guide, design principles
This commit is contained in:
2026-04-14 13:52:20 +00:00
parent 8b96e48e99
commit 0b32eef3c7
2 changed files with 317 additions and 30 deletions
+118 -30
View File
@@ -1,62 +1,150 @@
# Pulse
```
Rule = (prev, curr) → (effects, tickMs) → (effects', tickMs')
```
这是 Pulse 的原子——一个上下文相关的修饰函数。上半段感知世界(快照 diff),下半段修饰行为(追加/删除/替换 effects,调整采样频率)。
整个 Pulse 就是一组 Rule 的 fold:
Agent 的自主神经系统。
```
pulse = fold rules dummy
dummy = (prev, curr) → ([], defaultTickMs)
Rule = (prev, curr, inner) => Promise<[Effect[], tickMs]>
```
Runtime 十行。所有智能在 Rule 里
有状态响应式循环:持续感知 → 认知判断 → 自主行动。确定性任务自己做,不确定才上报 Agent
## 什么是 Pulse
## 架构
Agent 的自主神经系统——有状态的响应式循环,持续感知多数据源,自主执行确定性任务,只在不确定时才上报 Agent 决策。
```
Autonomic 层(vitals.db) Tick 层(events.db)
Watchers → 写 vitals → 唤醒判定 rebuildSnapshot → Rule Chain → Executors
└── wakeTick() ──────────────→ 提前唤醒 tick
```
### 性质
**双层驱动**:Watchers 每 5s 采集写 vitals,关键事件提前唤醒 tick。Tick 层重建 snapshot,跑 Rule Chain 产生 effects,Executors 执行。
- **Moore 机** — 不逐事件响应,只看两次采样间的状态 diff。Effects 由新状态决定
- **路径依赖** — 采样有损,副作用不满足结合律。采样频率 = 现实世界的分辨率
- **不强制纯函数** — 大部分 Rule 是确定性的(零 token),不确定时可以 async
- **Agent 管理** — Rule repo 是 TypeScript 项目,tsc 守门。staging 用 git worktree
**洋葱 Rule 模型**:每个 Rule 接收 `inner`(剩余 rule chain),可以放行、bypass(跳过内层)、修饰结果、变换 snapshot。保命 rules 硬编码在最外层,agent 的业务 rules 在内层。
### Agent 与 Pulse 的关系
## 三层不可变性
Agent 是意识层,Pulse 是自主神经系统。Agent 定义 Rule,Pulse 执行 Rule,遇到例外回报 Agent,Agent 调整 Rule。
| 层级 | 比喻 | 谁能改 |
|---|---|---|
| **植物神经** — watchers、保命 rules、executors | 心跳、痛觉 | 只能 npm 升级 |
| **浅层自主神经** — 业务 rules | 呼吸节奏 | Agent staging → promote |
| **意识层** — OC Agent session | 思考、决策 | kill/restart 不影响 Pulse |
人不能通过大脑控制让心脏停跳。Agent 不能修改自己的保命逻辑。
## 包结构
| 包 | 内容 |
|---|---|
| `@uncaged/pulse` | 核心引擎`runPulse()` + `Rule` 类型,纯泛型零依赖 |
| `@uncaged/upulse` | CLI:daemon 管理 + test/staging/promote |
| `@uncaged/pulse-rules` | 共享 Rule 函数库 |
| 包 | 说明 | npm |
|---|---|---|
| `@uncaged/pulse` | 核心引擎 + 保命层 + watchers | [![npm](https://img.shields.io/npm/v/@uncaged/pulse)](https://www.npmjs.com/package/@uncaged/pulse) |
| `@uncaged/upulse` | CLI:daemon 管理staging/promote/rollback | [![npm](https://img.shields.io/npm/v/@uncaged/upulse)](https://www.npmjs.com/package/@uncaged/upulse) |
## 快速开始
```bash
# 安装
bun add @uncaged/pulse
bun add -g @uncaged/upulse
# 初始化 engine 目录
upulse init
# 开发模式(热重载)
upulse dev
# 部署到生产
upulse deploy
# 启动 daemon
upulse daemon start
```
## 核心概念
### Rule(洋葱中间件)
```typescript
type Rule<S, E> = (
prev: S, // 上一次 snapshot
curr: S, // 当前 snapshot
inner: (prev: S, curr: S) => Promise<[E[], number]> // 内层 rule chain
) => Promise<[E[], number]> // [effects, tickMs]
```
Rule 可以:
- **放行**:`return inner(prev, curr)`
- **Bypass**:`return [myEffects, 5000]`(不调 inner,跳过内层)
- **修饰**:先 `await inner(prev, curr)` 再追加/过滤 effects
- **变换 snapshot**:`return inner(prev, modifiedCurr)`
### Watcher(Autonomic 层)
```typescript
interface WatcherDef {
name: string
key: string // vitals 表的 key
collect: () => Promise<unknown> | unknown // 采集数据
shouldWake: (window: VitalWithData[]) => boolean // 唤醒判定
intervalMs?: number // 采集间隔,默认 5000
}
```
Watcher 持续采集写 vitals,唤醒判定看最近 1 分钟窗口(~12 条),关键事件 `wakeTick()` 提前唤醒 tick。
### 存储
| 库 | 内容 | 策略 |
|---|---|---|
| `events.db` | promote/rollback/effect/error/collect | 永不压缩 |
| `vitals.db` | 系统资源/进程/网络/LLM 健康 | 可 gc |
| `objects/` | CAS(内容寻址,不可变) | 自动去重 |
### 保命层(P0 Survival)
5 个内置 Watcher + 7 个保命 Rule,零 LLM 零网络依赖:
**Watchers:**
- `system-resource` — CPU/内存/磁盘/swap
- `process-alive` — 关键进程存活
- `network` — DNS + HTTP 出站
- `error-log` — 日志关键词匹配
- `llm-health` — 双层探针(轻量 5s + 深度 60s)
**Rules(洋葱顺序,最外层先执行):**
1. `panicRollback` — 保命动作连续失败 → 紧急回滚
2. `autoRollback` — promote 后大量 error → 自动回滚
3. `processWatchdog` — 进程挂了 → restart
4. `resourceGuard` — 内存/磁盘超限 → archive sessions + 清理
5. `llmWatchdog` — LLM 不通 → restart LiteLLM
6. `networkWatchdog` — 网络断了 → 通知
7. `errorEscalate` — 错误日志 → 通知 + 加速巡检
## Engine 目录
每个 Agent 维护自己的 engine repo:
每个 Agent 维护自己的 Rule repo:
```
~/.upulse/
config.json
engine/ ← main branch(生产)
types.tsSnapshot + Effect 类型
pulse.db / vitals.db / objects/
engine/ main branch(生产)
types.ts
rules/
collectors/
effectors/
pulse.config.ts
staging/ ← git worktree(安全实验)
staging/ ← git worktree(安全实验)
```
`upulse promote` = git merge + tsc 守门 + daemon reload
`upulse rollback` = git revert + 自动恢复
## 设计文档
[RFC #44: Pulse — Agent 的自主神经系统](https://github.com/oc-xiaoju/ograph/issues/44)
- [RFC #1: Pulse — Agent 的自主神经系统](https://github.com/oc-xiaoju/pulse/issues/1)
- [RFC #2: upulse CLI](https://github.com/oc-xiaoju/pulse/issues/2)
- [RFC #4: 核心洞察 — 感知·认知·行动](https://github.com/oc-xiaoju/pulse/issues/4)
- [RFC #5: 一切皆事件 — 存储模型](https://github.com/oc-xiaoju/pulse/issues/5)
- [RFC #22: 多实例管理](https://github.com/oc-xiaoju/pulse/issues/22)
- [RFC #23: Autonomic Layer + Rule Middleware Refactor](https://github.com/oc-xiaoju/pulse/issues/23)
- [Design #27: P0 保命层完整设计](https://github.com/oc-xiaoju/pulse/issues/27)
## License