wake-bridge 0.9.0-preview.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (115) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +222 -0
  3. package/dist/src/adapters/botlingknows.d.ts +42 -0
  4. package/dist/src/adapters/botlingknows.js +141 -0
  5. package/dist/src/adapters/botlingknows.js.map +1 -0
  6. package/dist/src/adapters/group-chat.d.ts +43 -0
  7. package/dist/src/adapters/group-chat.js +120 -0
  8. package/dist/src/adapters/group-chat.js.map +1 -0
  9. package/dist/src/cli.d.ts +2 -0
  10. package/dist/src/cli.js +637 -0
  11. package/dist/src/cli.js.map +1 -0
  12. package/dist/src/connector-catalog.d.ts +17 -0
  13. package/dist/src/connector-catalog.js +43 -0
  14. package/dist/src/connector-catalog.js.map +1 -0
  15. package/dist/src/connectors/botlingknows-mcp.d.ts +15 -0
  16. package/dist/src/connectors/botlingknows-mcp.js +130 -0
  17. package/dist/src/connectors/botlingknows-mcp.js.map +1 -0
  18. package/dist/src/connectors/group-chat-http.d.ts +17 -0
  19. package/dist/src/connectors/group-chat-http.js +226 -0
  20. package/dist/src/connectors/group-chat-http.js.map +1 -0
  21. package/dist/src/connectors/mcp-http-client.d.ts +11 -0
  22. package/dist/src/connectors/mcp-http-client.js +108 -0
  23. package/dist/src/connectors/mcp-http-client.js.map +1 -0
  24. package/dist/src/core.d.ts +170 -0
  25. package/dist/src/core.js +1720 -0
  26. package/dist/src/core.js.map +1 -0
  27. package/dist/src/daemon.d.ts +31 -0
  28. package/dist/src/daemon.js +605 -0
  29. package/dist/src/daemon.js.map +1 -0
  30. package/dist/src/db.d.ts +31 -0
  31. package/dist/src/db.js +513 -0
  32. package/dist/src/db.js.map +1 -0
  33. package/dist/src/event-sdk.d.ts +43 -0
  34. package/dist/src/event-sdk.js +152 -0
  35. package/dist/src/event-sdk.js.map +1 -0
  36. package/dist/src/host-adapter-registry.d.ts +21 -0
  37. package/dist/src/host-adapter-registry.js +59 -0
  38. package/dist/src/host-adapter-registry.js.map +1 -0
  39. package/dist/src/index.d.ts +5 -0
  40. package/dist/src/index.js +6 -0
  41. package/dist/src/index.js.map +1 -0
  42. package/dist/src/instance-config.d.ts +46 -0
  43. package/dist/src/instance-config.js +176 -0
  44. package/dist/src/instance-config.js.map +1 -0
  45. package/dist/src/mcp.d.ts +51 -0
  46. package/dist/src/mcp.js +728 -0
  47. package/dist/src/mcp.js.map +1 -0
  48. package/dist/src/operator-control.d.ts +82 -0
  49. package/dist/src/operator-control.js +220 -0
  50. package/dist/src/operator-control.js.map +1 -0
  51. package/dist/src/out-of-process-host.d.ts +37 -0
  52. package/dist/src/out-of-process-host.js +196 -0
  53. package/dist/src/out-of-process-host.js.map +1 -0
  54. package/dist/src/policy-control.d.ts +3 -0
  55. package/dist/src/policy-control.js +120 -0
  56. package/dist/src/policy-control.js.map +1 -0
  57. package/dist/src/release-lifecycle.d.ts +98 -0
  58. package/dist/src/release-lifecycle.js +378 -0
  59. package/dist/src/release-lifecycle.js.map +1 -0
  60. package/dist/src/sdk-error.d.ts +6 -0
  61. package/dist/src/sdk-error.js +12 -0
  62. package/dist/src/sdk-error.js.map +1 -0
  63. package/dist/src/source-adapter.d.ts +32 -0
  64. package/dist/src/source-adapter.js +164 -0
  65. package/dist/src/source-adapter.js.map +1 -0
  66. package/dist/src/source-connector.d.ts +50 -0
  67. package/dist/src/source-connector.js +358 -0
  68. package/dist/src/source-connector.js.map +1 -0
  69. package/dist/src/source-control-client.d.ts +38 -0
  70. package/dist/src/source-control-client.js +61 -0
  71. package/dist/src/source-control-client.js.map +1 -0
  72. package/dist/src/source-ingress.d.ts +16 -0
  73. package/dist/src/source-ingress.js +47 -0
  74. package/dist/src/source-ingress.js.map +1 -0
  75. package/dist/src/source-sdk.d.ts +6 -0
  76. package/dist/src/source-sdk.js +53 -0
  77. package/dist/src/source-sdk.js.map +1 -0
  78. package/dist/src/transport-sdk.d.ts +102 -0
  79. package/dist/src/transport-sdk.js +222 -0
  80. package/dist/src/transport-sdk.js.map +1 -0
  81. package/dist/src/transport.d.ts +23 -0
  82. package/dist/src/transport.js +71 -0
  83. package/dist/src/transport.js.map +1 -0
  84. package/dist/src/types.d.ts +522 -0
  85. package/dist/src/types.js +2 -0
  86. package/dist/src/types.js.map +1 -0
  87. package/dist/src/util.d.ts +26 -0
  88. package/dist/src/util.js +136 -0
  89. package/dist/src/util.js.map +1 -0
  90. package/dist/src/version.d.ts +1 -0
  91. package/dist/src/version.js +2 -0
  92. package/dist/src/version.js.map +1 -0
  93. package/docs/adapters/botlingknows.md +40 -0
  94. package/docs/adapters/gmail-planned.md +16 -0
  95. package/docs/adapters/group-chat.md +126 -0
  96. package/docs/operations/connector-catalog.md +40 -0
  97. package/docs/operations/operator-control.md +83 -0
  98. package/docs/operations/out-of-process-host-adapter.md +150 -0
  99. package/docs/operations/policies.md +106 -0
  100. package/docs/operations/public-sdk.md +87 -0
  101. package/docs/operations/release-lifecycle.md +154 -0
  102. package/docs/operations/source-connectors.md +163 -0
  103. package/docs/operations/source-ingress.md +108 -0
  104. package/docs/operations/templates/botlingknows-connector.env.example +5 -0
  105. package/docs/operations/templates/sources.json.example +15 -0
  106. package/docs/quickstart.md +143 -0
  107. package/docs/releases/0.9.0-preview.8.md +44 -0
  108. package/docs/verification.md +19 -0
  109. package/examples/policies/botlingknows-conservative.json +44 -0
  110. package/examples/reference-host-adapter/README.md +41 -0
  111. package/examples/reference-host-adapter/adapter.mjs +173 -0
  112. package/examples/reference-host-adapter/host-adapters.json.example +26 -0
  113. package/package.json +94 -0
  114. package/schemas/event-v1.schema.json +26 -0
  115. package/schemas/policy-v1.schema.json +66 -0
@@ -0,0 +1,106 @@
1
+ # Personal policy 文件与控制面
2
+
3
+ 状态:current local implementation(WB-MVP-002)。本页只描述 public policy v1;Core 中的迁移类型不扩大支持矩阵。
4
+
5
+ ## 1. 写一个完整 policy 文件
6
+
7
+ policy 文件是一个 owner-authored snapshot,每个 id 在同一文件中只能出现一次,并必须有显式 default:
8
+
9
+ ```json
10
+ {
11
+ "schema_version": 1,
12
+ "policies": [
13
+ {
14
+ "id": "ci-failures",
15
+ "version": 1,
16
+ "order": 100,
17
+ "match": {"source": "ci", "metadata.status": "failed"},
18
+ "delivery": {
19
+ "mode": "immediate",
20
+ "quiet_hours_policy": "bypass",
21
+ "foreground_presence_policy": "defer"
22
+ },
23
+ "batch": {"coalesce_by": "metadata.project", "max_events": 20, "window_ms": 5000},
24
+ "target": {"attention_channel": "engineering"},
25
+ "reason_code": "ci_failed"
26
+ },
27
+ {
28
+ "id": "default",
29
+ "version": 2,
30
+ "enabled": true,
31
+ "order": -1000000,
32
+ "match": {},
33
+ "delivery": {"mode": "suppress"}
34
+ }
35
+ ]
36
+ }
37
+ ```
38
+
39
+ 内置 bootstrap rule 已占用 `default@1`,所以第一次安装 owner default 用 version 2。之后改变任何内容都必须同时升 version。
40
+ 同版本内容完全相同可安全重跑;同版本内容不同或安装低于现有最高版本会返回 conflict。
41
+
42
+ 当前 delivery mode 只有 `immediate`、`scheduled` 与 `suppress`。scheduled 使用本实例 timezone:
43
+
44
+ ```json
45
+ {"mode":"scheduled","scheduled_local_time":"08:30"}
46
+ ```
47
+
48
+ `debounce`、`digest`、`max_delay_ms`、`prefer_transport`、`busy_behavior` 当前会被拒绝。`resume_spread_ms` 与
49
+ `default_action` 也不接受为 quiet-hours config。不要根据历史 DB row 推断它们已经受支持。
50
+
51
+ ## 2. 安装与查看
52
+
53
+ ```sh
54
+ node dist/src/cli.js policy install \
55
+ --config /absolute/path/to/agent-space/wakebridge.config.json \
56
+ --file /absolute/path/to/policies.json
57
+
58
+ node dist/src/cli.js policy list \
59
+ --config /absolute/path/to/agent-space/wakebridge.config.json
60
+ ```
61
+
62
+ list 同时返回 append-only `policies` 历史、每个 id 的 `active` 最高版本和 `status`。`new_event_matching` 可能是
63
+ `eligible | disabled | historical | legacy_unsupported`;最后一种表示升级前残留 row 只供历史解释,不会匹配新事件。
64
+ 要停用一个规则,安装更高且
65
+ `"enabled": false` 的版本;系统不会回退到旧 enabled 版本。文件中没有出现的已有 id 不会被删除或自动停用。
66
+
67
+ ## 3. Test 与 preview
68
+
69
+ 下面的命令只读取当前安装规则:
70
+
71
+ ```sh
72
+ EVENT='{"type":"job.completed","dedupe_key":"dry-run-1","resource":{"uri":"ci://build/1842"},"metadata":{"status":"failed","project":"demo"}}'
73
+
74
+ node dist/src/cli.js policy test \
75
+ --config /absolute/path/to/agent-space/wakebridge.config.json \
76
+ --source ci --event "$EVENT"
77
+
78
+ node dist/src/cli.js policy preview \
79
+ --config /absolute/path/to/agent-space/wakebridge.config.json \
80
+ --source ci --event "$EVENT"
81
+ ```
82
+
83
+ 加 `--file /path/to/candidate.json` 可在安装前评估 candidate。test 返回 matched rule;preview 还返回当前求值时间、是否
84
+ suppress、Claim eligibility/expiry/channel、quiet/presence gate 与 batch key。两者都不登记 Event,不创建 Claim/Batch。
85
+
86
+ ## 4. Owner API
87
+
88
+ 所有 endpoint 都要求 owner token,不能把它交给 source producer:
89
+
90
+ ```sh
91
+ curl --fail-with-body http://127.0.0.1:4311/v1/policies \
92
+ -H "Authorization: Bearer ${WAKEBRIDGE_ADMIN_TOKEN}"
93
+
94
+ curl --fail-with-body -X POST http://127.0.0.1:4311/v1/policies/install \
95
+ -H "Authorization: Bearer ${WAKEBRIDGE_ADMIN_TOKEN}" \
96
+ -H "Content-Type: application/json" \
97
+ --data-binary @/absolute/path/to/policies.json
98
+
99
+ curl --fail-with-body -X POST http://127.0.0.1:4311/v1/policies/preview \
100
+ -H "Authorization: Bearer ${WAKEBRIDGE_ADMIN_TOKEN}" \
101
+ -H "Content-Type: application/json" \
102
+ -d '{"source":"ci","event":{"type":"job.completed","dedupe_key":"dry-run-api","resource":{"uri":"ci://build/1842"}}}'
103
+ ```
104
+
105
+ 若要 preview 未安装文件,把完整对象放在 request 的 `policy_file` 字段。source-scoped ingress、host bootstrap 与 endpoint
106
+ lease credential 对这些 API 一律 unauthorized。
@@ -0,0 +1,87 @@
1
+ # Public SDK boundary
2
+
3
+ 状态:introduced in `wake-bridge@0.9.0-preview.2`; current package `0.9.0-preview.8`。
4
+
5
+ Wake Bridge 只把 event、source 与 transport 三条版本化 contract 作为第三方 package surface。Core、DB、daemon、owner
6
+ control 与 release lifecycle 是 package 内部实现,不是可导入 subpath;历史具体产品 Host Adapter 实验也不进入当前 tarball。`exports` map 会拒绝
7
+ `wake-bridge/core`、`wake-bridge/db`、`wake-bridge/daemon` 等路径。
8
+
9
+ `wake-bridge/transport` 在 preview.4 增加 `LOCAL_HOST_PROTOCOL_VERSION=1`、`HostSessionClient` 与 delivery validator,使仓库外
10
+ bridge service 可以通过固定 loopback wire contract 接入 stock daemon。Public client 只有 host-session lifecycle、foreground
11
+ presence 与 activity capability,
12
+ 不暴露 Core、DB 或 owner control;内置 local HTTP transport 仍是 package private implementation。
13
+
14
+ ## Entrypoints
15
+
16
+ ```ts
17
+ import {
18
+ EVENT_CONTRACT_VERSION,
19
+ SourcePushClient,
20
+ validateWakeEventInput,
21
+ } from "wake-bridge/event";
22
+
23
+ import {
24
+ SOURCE_ADAPTER_CONTRACT_VERSION,
25
+ validateSourceManifest,
26
+ type PullSourceAdapter,
27
+ } from "wake-bridge/source";
28
+
29
+ import {
30
+ HOST_ADAPTER_CONTRACT_VERSION,
31
+ LOCAL_HOST_PROTOCOL_VERSION,
32
+ HostSessionClient,
33
+ validateLocalHostDeliveryRequest,
34
+ validateHostAdapterManifest,
35
+ type HostAdapter,
36
+ } from "wake-bridge/transport";
37
+ ```
38
+
39
+ root `wake-bridge` 只聚合以上 contract 与 `RELEASE_VERSION`,不再导出 `WakeBridge`、DB、daemon、operator lifecycle 或
40
+ 内置 adapters。JSON event schema 通过 `wake-bridge/schema/event-v1` 提供;policy schema 继续通过
41
+ `wake-bridge/schema/policy-v1` 提供。
42
+
43
+ ## Version negotiation
44
+
45
+ - event payload 必须使用 `schema_version: 1`;省略时 SDK/daemon 规范化为 v1,其他版本 fail closed;
46
+ - source manifest 必须同时声明 `contract_version: 1` 与 adapter 自己的 `version`,二者不能混用;
47
+ - host manifest 必须声明 `contract_version: 1` 与 `adapter_version`;
48
+ - 当前 preview 只支持 exact v1,不做猜测、向下转换或“尽力兼容”。未来扩展必须增加 supported-version set 与明确迁移。
49
+
50
+ ## Capability isolation
51
+
52
+ Source adapter 只能返回 event page;generic push client 只能向配置时固定的 loopback `source` 路径提交 v1 event。Host adapter
53
+ 只收到 dispatch context 与 `{instance_id, daemon_origin}` lifecycle context,不会获得 Core、SQLite handle、owner token 或
54
+ owner-control client。Transport route 可以包含该 adapter 完成投递所需的窄 route credential,但不能据此调用 owner/source API。
55
+
56
+ `HostSessionClient.renewPresence()` 只接受当前 lease 与 host 自己观察到的真实用户 active edge;Core 校验 endpoint/generation 并
57
+ 生成短 TTL lease。它与 `observeActivity()` 分离,避免把 agent/model activity 或 Wake echo 冒充用户仍在前台。
58
+
59
+ 实际 tarball test 会在仓库外安装 package、用 TypeScript 编译 fake source + fake host、运行 validators,并逐一确认 private
60
+ subpaths 返回 `ERR_PACKAGE_PATH_NOT_EXPORTED`。这是一条受支持 API boundary,不是对同机恶意代码的 OS sandbox;安装目录仍应
61
+ 由 operator 权限保护。
62
+
63
+ ## Generic push
64
+
65
+ ```ts
66
+ const client = new SourcePushClient({
67
+ base_url: "http://127.0.0.1:4311",
68
+ source: "ci",
69
+ token: process.env.WAKEBRIDGE_SOURCE_CI_TOKEN!,
70
+ });
71
+
72
+ await client.emit({
73
+ schema_version: EVENT_CONTRACT_VERSION,
74
+ type: "job.completed",
75
+ dedupe_key: "build:1842",
76
+ resource: { uri: "ci://build/1842" },
77
+ });
78
+ ```
79
+
80
+ client 不接受公网 daemon origin,不把 `source` 写入 body,并验证返回 receipt 的 source 与 event contract。Credential 的创建、
81
+ 轮换与 daemon 配置见 [source ingress](source-ingress.md);SDK 不提供 owner API。
82
+
83
+ ## Reference source
84
+
85
+ `wake-bridge/source/group-chat` 提供只依赖公开 feed contract 的 `GroupChatSourceAdapter` 与 mapper。仓内 conformance fixture 已覆盖
86
+ mention/reply mapping、opaque cursor、schema fencing 与 duplicate-page rejection。真实独立 Group Chat feed canary 仍是外部验收项;
87
+ 在取得实际 feed endpoint、principal credential 与 provider version 之前,不得把 fixture 结果写成 production support。
@@ -0,0 +1,154 @@
1
+ # Release install, upgrade, backup, and rollback
2
+
3
+ 状态:engineering preview current runbook(2026-09-07)。Wake Bridge 发布包只支持 Host Adapter Contract;
4
+ 完成本页不等于任何具体 agent 产品获得兼容性或时延保证。
5
+
6
+ ## 支持矩阵
7
+
8
+ | 项目 | 当前承诺 |
9
+ | --- | --- |
10
+ | package | `wake-bridge`,npm dist-tag `preview` |
11
+ | license | Apache-2.0 |
12
+ | OS | macOS / `darwin`;Linux profile 与验证明确延后 |
13
+ | CPU | arm64、x64 |
14
+ | Node.js | 20 或更高 |
15
+ | SQLite CLI | 3.33.0 或更高,且必须支持 `-json` |
16
+ | topology | 每个 Agent Space 一个本地 instance / SQLite DB |
17
+ | schema | current 8;显式升级支持 6、7 → 8 |
18
+ | host integration | out-of-process Host Adapter Contract v1;不内置具体 agent 产品支持 |
19
+
20
+ 当前 npm manifest 会在非 macOS 平台拒绝安装,避免把尚未做 systemd、OS matrix 和真实 canary 的 Linux 暗示为已支持。
21
+ SQLite 是外部 runtime prerequisite,不由 npm 安装;3.33.0 是 CLI 加入 JSON output mode 的版本。
22
+
23
+ ## 从 tarball 干净安装
24
+
25
+ 发布前先生成并审计 tarball:
26
+
27
+ ```bash
28
+ npm pack --json
29
+ npm install --global ./wake-bridge-0.9.0-preview.8.tgz
30
+ wakebridge release-preflight
31
+ ```
32
+
33
+ 正式发布到 preview channel 后,等价安装命令是:
34
+
35
+ ```bash
36
+ npm install --global wake-bridge@preview
37
+ ```
38
+
39
+ 初始化一个私有 Agent Space:
40
+
41
+ ```bash
42
+ wakebridge init \
43
+ --data-dir "$HOME/Library/Application Support/WakeBridge/default" \
44
+ --instance-id default \
45
+ --owner-id your-agent \
46
+ --timezone Asia/Shanghai
47
+
48
+ wakebridge release-preflight \
49
+ --config "$HOME/Library/Application Support/WakeBridge/default/wakebridge.config.json"
50
+ ```
51
+
52
+ `init` 生成 mode-600 config、owner credential 与 SQLite DB,不在 stdout 打印 token。它不会覆盖已有 config/DB。
53
+
54
+ ## macOS LaunchAgent
55
+
56
+ 安装真实 profile,但不替 operator 静默启动进程:
57
+
58
+ ```bash
59
+ wakebridge service install \
60
+ --config "$HOME/Library/Application Support/WakeBridge/default/wakebridge.config.json" \
61
+ --port 4311
62
+ ```
63
+
64
+ 返回值包含精确 `plist_path`、`load_command` 和 `unload_command`。plist 只保存 Node、已安装 CLI、config path、loopback
65
+ host/port 与日志位置,不复制 owner token。核对后执行返回的 `launchctl bootstrap ...`,再检查:
66
+
67
+ 同机多个 Agent Space 必须为每个 instance 选择不同 loopback port;profile 不会猜测或自动抢占已有端口。
68
+
69
+ ```bash
70
+ curl --fail -H "Authorization: Bearer $WAKEBRIDGE_ADMIN_TOKEN" http://127.0.0.1:4311/health
71
+ wakebridge doctor --config "$HOME/Library/Application Support/WakeBridge/default/wakebridge.config.json"
72
+ ```
73
+
74
+ 同一 instance 不允许覆盖已有 plist。升级 package 后 plist 的全局安装路径保持不变;若 npm 安装布局改变,先 bootout、
75
+ `service uninstall`,再由新 bin 重装 profile。
76
+
77
+ ## 一致性备份
78
+
79
+ daemon 可运行时执行 online SQLite snapshot:
80
+
81
+ ```bash
82
+ wakebridge backup \
83
+ --config /absolute/path/wakebridge.config.json \
84
+ --output /absolute/path/backups/pre-upgrade-0.9.0-preview.8
85
+ ```
86
+
87
+ 输出目录必须事先不存在。命令使用 SQLite `VACUUM INTO` 生成一致性 DB,随后执行 `quick_check`,写入 mode-600
88
+ `manifest.json` 与 SHA-256。备份只包含 durable DB 和无 secret manifest,不复制带 owner token 的 config;config 应由 operator
89
+ 另行放进加密 secret backup。不要用文件复制代替 online snapshot,也不要只复制 `-wal` 或 `-shm`。
90
+
91
+ ## 显式 upgrade
92
+
93
+ 普通 `daemon`、`inspect`、MCP 或其他 Core 打开路径看到旧 schema 时会 fail closed,并要求显式 upgrade;它们不会先改 DB
94
+ 再补备份。
95
+
96
+ ```bash
97
+ # 先停止/bootout daemon,避免 migration 期间仍有业务写入。
98
+ wakebridge upgrade \
99
+ --config /absolute/path/wakebridge.config.json \
100
+ --backup-output /absolute/path/backups/pre-schema-8 \
101
+ --confirm-offline
102
+ ```
103
+
104
+ upgrade 顺序固定:`offline assertion → WAL checkpoint → quick_check → verified backup → migrate → schema 8 + quick_check`。任何 migration/验证失败都会用刚创建的
105
+ backup 自动恢复原 DB。schema 8 再执行为 no-op;schema 6、7 是本 preview 的升级基线;更旧或更新的 schema 都拒绝。
106
+
107
+ ## 数据 rollback / restore
108
+
109
+ restore 是 offline、instance-fenced 的破坏性操作:
110
+
111
+ ```bash
112
+ # 1. 执行 service install 曾返回的 unload_command,并确认 daemon 已停止。
113
+ # 2. 恢复备份;confirm 值必须与 config 中 instance_id 完全一致。
114
+ wakebridge restore \
115
+ --config /absolute/path/wakebridge.config.json \
116
+ --backup /absolute/path/backups/pre-schema-8 \
117
+ --rollback-output /absolute/path/backups/pre-restore-current \
118
+ --confirm-instance-id default \
119
+ --confirm-offline
120
+ ```
121
+
122
+ restore 先为当前 DB 再做一份 verified rollback snapshot,校验目标 manifest、checksum、schema 与 integrity,然后原子替换 DB;
123
+ 失败时自动把刚才的 current snapshot 放回。恢复旧 schema 后不要再用新 daemon 打开 DB:先安装与该 schema 配套的旧 tarball,
124
+ 或重新执行新版本显式 upgrade。
125
+
126
+ 代码 rollback 与数据 rollback 是两个独立动作:
127
+
128
+ 1. bootout 新 daemon;
129
+ 2. 保存 inspect/日志证据;
130
+ 3. 必要时用 `restore` 恢复 pre-upgrade DB;
131
+ 4. `npm install --global /absolute/path/old-release.tgz`;
132
+ 5. 用旧版本的 `release-preflight/doctor` 验证后再 bootstrap LaunchAgent。
133
+
134
+ ## Uninstall
135
+
136
+ 先执行 install 返回的 `unload_command`,再删除 profile:
137
+
138
+ ```bash
139
+ wakebridge service uninstall --config /absolute/path/wakebridge.config.json
140
+ npm uninstall --global wake-bridge
141
+ ```
142
+
143
+ `service uninstall` 只删除该 instance 的 plist,明确保留 config、DB、backups 和 logs。数据删除不属于 uninstall;如确需删除,
144
+ 由 operator 在完成 verified backup 后另行处理明确目录。
145
+
146
+ ## Artifact 内容
147
+
148
+ tarball 包含运行 CLI 所需的 compiled `dist/src`、event/policy schema、LICENSE、README,以及当前 install/policy/source/SDK/operator/local-host runbook。
149
+ tests、具体产品 Host Adapter 实验实现与文档、历史私有运行环境 artifacts、私有现场记录、源码和开发依赖不进入发布包。`exports` 只公开 root contract aggregation、
150
+ `event`、`source`、`transport`、Group Chat reference source 与 schemas;Core/DB/daemon/operator/local-HTTP modules 只供 package 自己的 CLI 使用。
151
+ 边界和仓库外 fixture 见 [public SDK](public-sdk.md);运行态与 dead-letter recovery 见
152
+ [operator control](operator-control.md)。
153
+ [Out-of-process host integration](out-of-process-host-adapter.md) 使用同一个 public transport subpath,但具体 runtime adapter 不因进入
154
+ artifact 而获得 supported tier。
@@ -0,0 +1,163 @@
1
+ # Source Connector 安装与本地协议
2
+
3
+ 状态:current Source Connector contract。通用 runner 已通过隔离 fixture;是否可启用仍由 connector catalog、
4
+ identity verify、from-now bootstrap 与该来源的真实 UAT 分别决定。本文不证明任何 Host Adapter 的兼容性。
5
+
6
+ ## 谁保管什么
7
+
8
+ ```text
9
+ provider credential → Source Connector process
10
+ connector-local bearer → Wake Bridge daemon environment
11
+ event facts + resource refs + identity-fenced opaque cursor → Wake Bridge SQLite
12
+ ```
13
+
14
+ 外部 provider 不需要为 Wake Bridge 改 server、增加 scope 或签发专用 credential。Connector 是 owner 安装的适配进程,可以复用 provider 已有 OAuth、API key、MCP 登录、webhook 或本地 session。Wake Bridge 不获得这些上游 secret。
15
+
16
+ 隔离不会把 broad credential 变成 read-only。Connector 被攻破时仍可能继承上游权限;能用 provider 原生最小 scope 时应优先使用。Manifest 只是如实声明和验收依据,不是进程沙箱。
17
+
18
+ ## Connector protocol
19
+
20
+ Connector 监听一个独占 loopback origin,并用独立 bearer 验证每个请求:
21
+
22
+ ```http
23
+ GET /v1/manifest
24
+ Authorization: Bearer <connector-local-token>
25
+ ```
26
+
27
+ ```json
28
+ {
29
+ "id": "example-notifications",
30
+ "version": "1.0.0",
31
+ "subject_ref": "example:principal:owner-confirmed-id",
32
+ "binding_fingerprint": "sha256:<64-lowercase-hex>",
33
+ "read_side_effects": "none",
34
+ "credential_custody": "connector",
35
+ "upstream_credential_breadth": "broad",
36
+ "upstream_credential_scopes": ["provider.account"],
37
+ "connector_capabilities": ["notifications.read"]
38
+ }
39
+ ```
40
+
41
+ ```http
42
+ POST /v1/poll
43
+ Authorization: Bearer <connector-local-token>
44
+ Content-Type: application/json
45
+
46
+ {"cursor": null, "limit": 100}
47
+ ```
48
+
49
+ 可选的首次安装接口:
50
+
51
+ ```http
52
+ POST /v1/bootstrap
53
+ Authorization: Bearer <connector-local-token>
54
+ Content-Type: application/json
55
+
56
+ {"mode": "from-now"}
57
+ ```
58
+
59
+ 它只返回当前水位 cursor,不返回或创建 event。Wake Bridge 只在 source 尚无 checkpoint 时接受一次 `from-now` bootstrap。Agent 必须把刚刚 verify 到的 `subject_ref` 与 `binding_fingerprint` 原样回传,Bridge 不替 agent 猜身份。
60
+
61
+ ```json
62
+ {
63
+ "events": [
64
+ {
65
+ "type": "mention",
66
+ "occurred_at": "2026-08-29T05:00:00.000Z",
67
+ "dedupe_key": "notification:123",
68
+ "resource": {"uri": "example://notification/123", "cursor": 123},
69
+ "metadata": {"notification_id": 123}
70
+ }
71
+ ],
72
+ "next_cursor": {"high_watermark": 123},
73
+ "has_more": false
74
+ }
75
+ ```
76
+
77
+ Event 不得携带 provider credential、完整邮件/消息正文或任意模型指令。`resource.uri` 指回权威来源,agent 醒来后使用自己的授权工具读取。
78
+
79
+ ## Wake Bridge 配置
80
+
81
+ 配置文件不保存 token 值,只保存 token 环境变量名:
82
+
83
+ ```json
84
+ {
85
+ "version": 1,
86
+ "sources": [
87
+ {
88
+ "id": "example-notifications",
89
+ "base_url": "http://127.0.0.1:4391",
90
+ "token_env": "WAKEBRIDGE_SOURCE_EXAMPLE_TOKEN",
91
+ "enabled": true,
92
+ "poll_interval_ms": 60000,
93
+ "max_backoff_ms": 900000,
94
+ "limit": 100,
95
+ "max_pages_per_cycle": 4
96
+ }
97
+ ]
98
+ }
99
+ ```
100
+
101
+ Daemon 用 `WAKEBRIDGE_SOURCE_CONNECTORS_FILE=/absolute/path/sources.json` 读取它。`base_url` 必须是无 path/query/credential 的 loopback HTTP origin。Connector token 只放在 daemon 的 mode-600 env 文件或等价 secret store,不放命令行、配置 JSON、数据库或日志。
102
+
103
+ 安装者只负责提供已安装 connector 槽位和本地运行能力。上游 MCP URL、OAuth 或 API key 由 owning agent 使用 connector/provider 自己的配置机制填写和保管;Wake Bridge 不扫描宿主、shell 或浏览器配置,也不复制、修改这些值。
104
+
105
+ ## 验证与运行
106
+
107
+ ```bash
108
+ wakebridge source-validate --connectors /absolute/path/sources.json
109
+ wakebridge source-bootstrap example-notifications \
110
+ --mode from-now \
111
+ --connectors /absolute/path/sources.json \
112
+ --expected-subject-ref example:principal:owner-confirmed-id \
113
+ --expected-binding-fingerprint sha256:<64-lowercase-hex>
114
+ wakebridge source-once example-notifications \
115
+ --connectors /absolute/path/sources.json \
116
+ --db /private/tmp/wakebridge-source-probe.sqlite
117
+ wakebridge daemon \
118
+ --config /absolute/path/to/agent-space/wakebridge.config.json \
119
+ --connectors /absolute/path/sources.json
120
+ ```
121
+
122
+ `source-once` 会真实调用 connector,并把标准化 event/checkpoint 写入指定 DB;它不是“只打印、不落库”的假 dry-run。首次验收应显式使用隔离 DB。状态不是 `healthy` 时命令以非零退出。
123
+
124
+ Agent 日常使用 MCP 自助完成:
125
+
126
+ 1. `attention_source_status` 查看已安装槽位;
127
+ 2. 启动自己配置好的 connector 后,调用 `attention_source_verify`;
128
+ 3. 首次接入用 `attention_source_bootstrap`,已有错误/旧身份 checkpoint 用 `attention_source_rebind`;两者都必须回传 verify 结果中的准确身份;
129
+ 4. 调用 `attention_source_enable` 开始轮询;需要停用时调用 `attention_source_disable`。enable/disable 会持久化并跨 daemon 重启保留。
130
+
131
+ Source control MCP 只接受 source id、非敏感身份确认、checkpoint revision 与 rebind reason,不接受任何 provider URL 或 credential。Opaque cursor 也不会经 status/verify 暴露给 agent。
132
+
133
+ 对应的 authenticated loopback 管理 API:
134
+
135
+ ```text
136
+ GET /v1/sources
137
+ POST /v1/sources/:source_id/poll
138
+ POST /v1/sources/:source_id/verify
139
+ POST /v1/sources/:source_id/bootstrap
140
+ POST /v1/sources/:source_id/rebind
141
+ POST /v1/sources/:source_id/enable
142
+ POST /v1/sources/:source_id/disable
143
+ ```
144
+
145
+ 两者都走现有 admin token。Health 只公开 source、状态、时间、错误分类、连续失败数、下一次轮询、checkpoint revision 与上一轮计数,不回显 endpoint、token、manifest scopes 或 event body。
146
+
147
+ ## 失败语义
148
+
149
+ - connector 暂时不可达、HTTP 5xx/429:`backoff`,指数退避到配置上限;
150
+ - 缺 connector token、401/403、manifest/checkpoint identity 不符、读取有副作用、schema/cursor/event 错误:`needs_attention`,停止自动轮询;
151
+ - 每次 poll 都核对 live `subject_ref` + `binding_fingerprint`;身份变化时禁止沿用旧 cursor,只能在 disabled 状态显式 rebind,并把旧 checkpoint 归档;
152
+ - page 全部 event durable 后才 CAS 推进 checkpoint;
153
+ - commit 前崩溃会重放同页,`(source, dedupe_key)` 吸收重复;
154
+ - `has_more` 每轮最多读取 `max_pages_per_cycle` 页,避免一个高流量 source 饿死其他来源。
155
+
156
+ ## 首次生产接入 gate
157
+
158
+ 1. 在隔离环境对真实 connector 做 manifest、auth、read-side-effect 与 cursor conformance。
159
+ 2. 由 owner 明确选择 `from-now` 或受控 backfill;`from-now` 用显式 bootstrap 写入空 checkpoint,不手改 SQLite。
160
+ 3. 用隔离 DB 先验证 bootstrap + `source-once`,确认旧通知不生成 event、event 不含正文/secret 且 resource 可回读;不要先指向 production DB。Production bootstrap 时 source 配置必须保持 `enabled=false`,完成后再受控启用,避免 poll 与空 checkpoint 竞争。
161
+ 4. 备份 Wake Bridge DB、release、LaunchAgent/env;安装 connector 自己的 rollback。
162
+ 5. 先启单一 source,以一条专用无敏感通知做 canary。
163
+ 6. 验收 event → claim → wake → ack/consume receipts;不自动回复、不改 provider read state。
@@ -0,0 +1,108 @@
1
+ # Source-scoped event ingress
2
+
3
+ 状态:current local implementation。该入口适合 loopback producer、webhook sidecar 或同机 job runner;它只授予固定 source 的
4
+ event ingest authority,不授予 owner control。
5
+
6
+ ## 1. 初始化一个 Agent Space
7
+
8
+ ```sh
9
+ node dist/src/cli.js init \
10
+ --data-dir /absolute/path/to/agent-space \
11
+ --instance-id agent-a \
12
+ --owner-id agent-a-owner \
13
+ --timezone Asia/Shanghai
14
+ ```
15
+
16
+ 命令创建私有 config 与 DB,不在 stdout 打印 owner token。先检查本地 readiness:
17
+
18
+ ```sh
19
+ node dist/src/cli.js doctor \
20
+ --config /absolute/path/to/agent-space/wakebridge.config.json
21
+ ```
22
+
23
+ 不要把 `wakebridge.config.json` 提交到 git、复制给 source producer 或传给任何 agent host。
24
+
25
+ ## 2. 配置窄 source credential
26
+
27
+ token 只放环境变量:
28
+
29
+ ```sh
30
+ export WAKEBRIDGE_SOURCE_CI_TOKEN="<至少 32 字符的随机 token>"
31
+ ```
32
+
33
+ reference file 只保存 env 名与固定 source:
34
+
35
+ ```json
36
+ {
37
+ "version": 1,
38
+ "credentials": [
39
+ {
40
+ "id": "ci-primary",
41
+ "source": "ci",
42
+ "token_env": "WAKEBRIDGE_SOURCE_CI_TOKEN"
43
+ }
44
+ ]
45
+ }
46
+ ```
47
+
48
+ 启动 daemon:
49
+
50
+ ```sh
51
+ node dist/src/cli.js daemon \
52
+ --config /absolute/path/to/agent-space/wakebridge.config.json \
53
+ --source-credentials /absolute/path/to/source-credentials.json \
54
+ --host 127.0.0.1 \
55
+ --port 4311
56
+ ```
57
+
58
+ ## 3. Producer 登记 event
59
+
60
+ ```sh
61
+ curl --fail-with-body \
62
+ -X POST http://127.0.0.1:4311/v1/ingress/ci/events \
63
+ -H "Authorization: Bearer ${WAKEBRIDGE_SOURCE_CI_TOKEN}" \
64
+ -H "Content-Type: application/json" \
65
+ -d '{
66
+ "schema_version": 1,
67
+ "type": "job.completed",
68
+ "dedupe_key": "build:1842",
69
+ "attention_channel_hint": "default",
70
+ "resource": {"uri": "ci://build/1842"},
71
+ "metadata": {"result": "success"}
72
+ }'
73
+ ```
74
+
75
+ 请求 body 不接受 `source`。Bridge 从已经验证的 token 与 URL path 注入 `source=ci`。同一个 token 不能访问
76
+ `/v1/ingress/other/events`,也不能访问 `/v1/inspect`、`/v1/tick` 或其他 owner API。
77
+
78
+ `POST /v1/events` 仍存在,但它是 owner-admin surface,用于本实例 owner 的手动与管理式操作;不要把 owner token 发给普通
79
+ producer。
80
+
81
+ ## 4. 轮换与撤销
82
+
83
+ source token 不进 DB。安全轮换流程:
84
+
85
+ 1. 为同一个 source 增加第二个 credential id 与新的 token env;
86
+ 2. 重启 daemon;
87
+ 3. producer 切换到新 token;
88
+ 4. 从 reference file/env 删除旧 token并再次重启。
89
+
90
+ owner config-backed token 使用:
91
+
92
+ ```sh
93
+ node dist/src/cli.js owner-token-rotate \
94
+ --config /absolute/path/to/agent-space/wakebridge.config.json
95
+ ```
96
+
97
+ 轮换后重启 daemon。命令不会打印新 token;若设置了 `WAKEBRIDGE_ADMIN_TOKEN`,必须先 unset。config-backed profile 不允许
98
+ CLI/env 改写固定的 instance、owner、DB、timezone 或 admin token,避免同一 credential 被带到另一个 Agent Space。
99
+
100
+ ## Development escape hatch
101
+
102
+ 只有不带任何真实数据的本地 fixture 才可使用:
103
+
104
+ ```sh
105
+ node dist/src/cli.js daemon --unsafe-no-auth --host 127.0.0.1
106
+ ```
107
+
108
+ 它不能绑定 `0.0.0.0` 或其他非 loopback 地址,也不能让 host session 或 scoped source endpoint 绕过各自 credential。
@@ -0,0 +1,5 @@
1
+ # Copy to a mode-600 file outside git. Never put either value in argv.
2
+ BOTLINGKNOWS_MCP_URL=<existing-full-streamable-http-mcp-url>
3
+ # Non-secret label chosen and confirmed by this connector's owner.
4
+ BOTLINGKNOWS_SUBJECT_REF=botlingknows:principal:<owner-confirmed-id>
5
+ WAKEBRIDGE_CONNECTOR_TOKEN=<separate-local-connector-token>
@@ -0,0 +1,15 @@
1
+ {
2
+ "version": 1,
3
+ "sources": [
4
+ {
5
+ "id": "botlingknows",
6
+ "base_url": "http://127.0.0.1:4391",
7
+ "token_env": "WAKEBRIDGE_SOURCE_BOTLING_TOKEN",
8
+ "enabled": false,
9
+ "poll_interval_ms": 60000,
10
+ "max_backoff_ms": 900000,
11
+ "limit": 50,
12
+ "max_pages_per_cycle": 4
13
+ }
14
+ ]
15
+ }