@geoly-ai/social-hub-cli 0.2.24 → 0.2.26

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 (38) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/cmd-manifest.json +12 -2
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +18 -2
  5. package/dist/index.js.map +1 -1
  6. package/dist/permissions-gates-content-classification.d.ts +8 -0
  7. package/dist/permissions-gates-content-classification.d.ts.map +1 -0
  8. package/dist/permissions-gates-content-classification.js +40 -0
  9. package/dist/permissions-gates-content-classification.js.map +1 -0
  10. package/dist/permissions.d.ts.map +1 -1
  11. package/dist/permissions.js +2 -0
  12. package/dist/permissions.js.map +1 -1
  13. package/dist/register-content-classification.d.ts +14 -0
  14. package/dist/register-content-classification.d.ts.map +1 -0
  15. package/dist/register-content-classification.js +205 -0
  16. package/dist/register-content-classification.js.map +1 -0
  17. package/dist/register-content-classification.test.d.ts +2 -0
  18. package/dist/register-content-classification.test.d.ts.map +1 -0
  19. package/dist/register-content-classification.test.js +43 -0
  20. package/dist/register-content-classification.test.js.map +1 -0
  21. package/dist/register-subreddit-post-style.d.ts +8 -0
  22. package/dist/register-subreddit-post-style.d.ts.map +1 -0
  23. package/dist/register-subreddit-post-style.js +161 -0
  24. package/dist/register-subreddit-post-style.js.map +1 -0
  25. package/dist/update-check.d.ts +15 -0
  26. package/dist/update-check.d.ts.map +1 -1
  27. package/dist/update-check.js +106 -3
  28. package/dist/update-check.js.map +1 -1
  29. package/dist/update-check.test.js +71 -2
  30. package/dist/update-check.test.js.map +1 -1
  31. package/package.json +3 -3
  32. package/skills/manifest.json +1 -1
  33. package/skills/social-hub-accounts/SKILL.md +32 -0
  34. package/skills/social-hub-calendar-jobs/SKILL.md +1 -1
  35. package/skills/social-hub-content-classification/SKILL.md +92 -0
  36. package/skills/social-hub-content-review/SKILL.md +31 -4
  37. package/skills/social-hub-ops-runtime/SKILL.md +19 -1
  38. package/skills/social-hub-post-review/SKILL.md +38 -12
@@ -1,4 +1,5 @@
1
- import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
1
+ import { spawn } from "node:child_process";
2
+ import { mkdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
3
  import { homedir } from "node:os";
3
4
  import { join } from "node:path";
4
5
  import { isRunningViaNpx } from "./skills/paths.js";
@@ -9,6 +10,9 @@ const CACHE_TTL_MS = 24 * 60 * 60 * 1000;
9
10
  const FETCH_TIMEOUT_MS = 2_000;
10
11
  const CACHE_DIR = join(homedir(), ".config", "geoly");
11
12
  const CACHE_FILE = join(CACHE_DIR, "social-hub-update-check.json");
13
+ /** 后台自更新的进程锁(TTL 内视为「有一次更新在途」,避免 agent 高频调用触发多次 npm install)。 */
14
+ const AUTO_UPDATE_LOCK_FILE = join(CACHE_DIR, "social-hub-auto-update.lock");
15
+ const AUTO_UPDATE_LOCK_TTL_MS = 15 * 60 * 1000;
12
16
  export function shouldSkipUpdateCheck(argv) {
13
17
  if (process.env["SOCIAL_HUB_NO_UPDATE_CHECK"] === "1")
14
18
  return true;
@@ -126,6 +130,105 @@ export function formatUpdateNoticeLines(current, latest) {
126
130
  function printUpdateNotice(current, latest) {
127
131
  process.stderr.write(formatUpdateNoticeLines(current, latest).join("\n"));
128
132
  }
133
+ // ---------------------------------------------------------------------------
134
+ // 后台自动更新:检测到新版即后台 `npm install -g @latest`;当前调用照常用旧版跑完,
135
+ // **下次调用自然是新版**(不 re-exec、不重启会话)。默认开;对以下场景自动退回「仅提示」:
136
+ // SOCIAL_HUB_NO_AUTO_UPDATE=1、npx 临时运行(全局装不适用)。CI/--no-update-check 等仍由
137
+ // shouldSkipUpdateCheck 在更外层整段跳过。
138
+ // ---------------------------------------------------------------------------
139
+ export function shouldSkipAutoUpdate() {
140
+ if (process.env["SOCIAL_HUB_NO_AUTO_UPDATE"] === "1")
141
+ return true;
142
+ if (isRunningViaNpx())
143
+ return true;
144
+ return false;
145
+ }
146
+ /**
147
+ * 原子拿后台更新锁(writeFile wx;已存在则看 TTL,过期回收重试)。拿到返回 true,
148
+ * 「有一次更新在途且未过期」返回 false。防 agent 一秒内多次调用触发一批 npm install。
149
+ */
150
+ export function acquireAutoUpdateLock(lockFile = AUTO_UPDATE_LOCK_FILE) {
151
+ try {
152
+ mkdirSync(join(lockFile, ".."), { recursive: true });
153
+ }
154
+ catch {
155
+ return false;
156
+ }
157
+ for (let attempt = 0; attempt < 2; attempt++) {
158
+ try {
159
+ writeFileSync(lockFile, JSON.stringify({ at: new Date().toISOString(), pid: process.pid }), { flag: "wx" });
160
+ return true;
161
+ }
162
+ catch {
163
+ try {
164
+ const raw = readFileSync(lockFile, "utf8");
165
+ const at = Date.parse(JSON.parse(raw).at ?? "");
166
+ if (!Number.isNaN(at) && Date.now() - at < AUTO_UPDATE_LOCK_TTL_MS) {
167
+ return false; // 有效锁在途
168
+ }
169
+ rmSync(lockFile, { force: true }); // 陈旧锁 → 回收后重试
170
+ }
171
+ catch {
172
+ return false;
173
+ }
174
+ }
175
+ }
176
+ return false;
177
+ }
178
+ export function releaseAutoUpdateLock(lockFile = AUTO_UPDATE_LOCK_FILE) {
179
+ try {
180
+ rmSync(lockFile, { force: true });
181
+ }
182
+ catch {
183
+ // ignore
184
+ }
185
+ }
186
+ /**
187
+ * 后台(detached、静默、非阻塞)启动 `npm install -g @latest`。当前进程立即返回。
188
+ * 成功启动返回 true;锁在途/启动失败返回 false。锁在成功装完后不主动释放(detached 无法感知
189
+ * 完成),靠 TTL 过期——届时 current 已=latest 不再触发;若装失败,锁到期后下次调用重试。
190
+ */
191
+ export function spawnBackgroundUpdate(latest, lockFile = AUTO_UPDATE_LOCK_FILE) {
192
+ if (!acquireAutoUpdateLock(lockFile))
193
+ return false;
194
+ try {
195
+ const child = spawn("npm", ["install", "-g", `${PACKAGE_NAME}@${latest}`], {
196
+ detached: true,
197
+ stdio: "ignore",
198
+ });
199
+ child.on("error", () => releaseAutoUpdateLock(lockFile));
200
+ child.unref();
201
+ return true;
202
+ }
203
+ catch {
204
+ releaseAutoUpdateLock(lockFile);
205
+ return false;
206
+ }
207
+ }
208
+ /** 后台更新已启动时给人/agent 的一行提示(stderr;不污染 stdout/JSON)。 */
209
+ export function formatAutoUpdateLines(current, latest) {
210
+ return [
211
+ "",
212
+ `[social-hub] Auto-updating ${current} → ${latest} in background (npm i -g).`,
213
+ `[social-hub] This run uses ${current}; the next \`social-hub\` invocation will use ${latest}.`,
214
+ "[social-hub] Agent: do not rely on new flags/skills THIS run — they apply to your next invocation.",
215
+ "",
216
+ ];
217
+ }
218
+ /** 检测到新版后的处置:默认后台自动装;退回场景走「仅提示」。 */
219
+ function handleNewerVersion(current, latest, argv) {
220
+ if (shouldSkipAutoUpdate()) {
221
+ printUpdateNotice(current, latest); // 自动更新被关/npx → 沿用手动提示
222
+ return;
223
+ }
224
+ if (argv.includes("--no-update-check"))
225
+ return; // 理论已在外层跳过,双保险
226
+ const spawned = spawnBackgroundUpdate(latest);
227
+ if (spawned) {
228
+ process.stderr.write(formatAutoUpdateLines(current, latest).join("\n"));
229
+ }
230
+ // spawned=false:有更新在途(锁未过期)或启动失败 → 静默,靠 TTL/下次调用重试,不刷屏。
231
+ }
129
232
  export async function maybeNotifyUpdate(argv = process.argv) {
130
233
  if (shouldSkipUpdateCheck(argv))
131
234
  return;
@@ -135,7 +238,7 @@ export async function maybeNotifyUpdate(argv = process.argv) {
135
238
  const cached = readCache();
136
239
  if (cached && cacheIsFresh(cached)) {
137
240
  if (isNewerVersion(cached.latest, current)) {
138
- printUpdateNotice(current, cached.latest);
241
+ handleNewerVersion(current, cached.latest, argv);
139
242
  }
140
243
  return;
141
244
  }
@@ -144,7 +247,7 @@ export async function maybeNotifyUpdate(argv = process.argv) {
144
247
  return;
145
248
  writeCache(latest);
146
249
  if (isNewerVersion(latest, current)) {
147
- printUpdateNotice(current, latest);
250
+ handleNewerVersion(current, latest, argv);
148
251
  }
149
252
  }
150
253
  //# sourceMappingURL=update-check.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"update-check.js","sourceRoot":"","sources":["../src/update-check.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,8 @@
1
- import { describe, expect, it } from "vitest";
2
- import { buildSelfUpdateSteps, formatUpdateNoticeLines, formatUpgradeCommand, isNewerVersion, shouldSkipUpdateCheck, } from "./update-check.js";
1
+ import { mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
2
+ import { tmpdir } from "node:os";
3
+ import { join } from "node:path";
4
+ import { afterEach, beforeEach, describe, expect, it } from "vitest";
5
+ import { acquireAutoUpdateLock, buildSelfUpdateSteps, formatAutoUpdateLines, formatUpdateNoticeLines, formatUpgradeCommand, isNewerVersion, releaseAutoUpdateLock, shouldSkipAutoUpdate, shouldSkipUpdateCheck, } from "./update-check.js";
3
6
  describe("shouldSkipUpdateCheck", () => {
4
7
  it("skips when env SOCIAL_HUB_NO_UPDATE_CHECK=1", () => {
5
8
  const prev = process.env["SOCIAL_HUB_NO_UPDATE_CHECK"];
@@ -66,6 +69,72 @@ describe("formatUpgradeCommand", () => {
66
69
  expect(formatUpgradeCommand("0.2.0")).toContain("@0.2.0");
67
70
  });
68
71
  });
72
+ describe("shouldSkipAutoUpdate", () => {
73
+ it("skips (falls back to notice) when SOCIAL_HUB_NO_AUTO_UPDATE=1", () => {
74
+ const prev = process.env["SOCIAL_HUB_NO_AUTO_UPDATE"];
75
+ process.env["SOCIAL_HUB_NO_AUTO_UPDATE"] = "1";
76
+ try {
77
+ expect(shouldSkipAutoUpdate()).toBe(true);
78
+ }
79
+ finally {
80
+ if (prev === undefined)
81
+ delete process.env["SOCIAL_HUB_NO_AUTO_UPDATE"];
82
+ else
83
+ process.env["SOCIAL_HUB_NO_AUTO_UPDATE"] = prev;
84
+ }
85
+ });
86
+ it("auto-updates by default", () => {
87
+ const prev = process.env["SOCIAL_HUB_NO_AUTO_UPDATE"];
88
+ delete process.env["SOCIAL_HUB_NO_AUTO_UPDATE"];
89
+ try {
90
+ // 非 npx 常规运行(测试进程)默认允许后台自更新。
91
+ expect(shouldSkipAutoUpdate()).toBe(false);
92
+ }
93
+ finally {
94
+ if (prev !== undefined)
95
+ process.env["SOCIAL_HUB_NO_AUTO_UPDATE"] = prev;
96
+ }
97
+ });
98
+ });
99
+ describe("formatAutoUpdateLines", () => {
100
+ it("says this run uses old, next uses new, and warns the agent", () => {
101
+ const text = formatAutoUpdateLines("0.2.24", "0.2.25").join("\n");
102
+ expect(text).toContain("0.2.24 → 0.2.25");
103
+ expect(text).toContain("next `social-hub` invocation will use 0.2.25");
104
+ expect(text).toMatch(/Agent:/);
105
+ });
106
+ });
107
+ describe("acquireAutoUpdateLock", () => {
108
+ let dir;
109
+ let lockFile;
110
+ beforeEach(() => {
111
+ dir = mkdtempSync(join(tmpdir(), "soh-autoupdate-"));
112
+ lockFile = join(dir, "auto-update.lock");
113
+ });
114
+ afterEach(() => {
115
+ rmSync(dir, { recursive: true, force: true });
116
+ });
117
+ it("grants the lock when none is held", () => {
118
+ expect(acquireAutoUpdateLock(lockFile)).toBe(true);
119
+ });
120
+ it("denies a second acquire while a fresh lock is held", () => {
121
+ expect(acquireAutoUpdateLock(lockFile)).toBe(true);
122
+ expect(acquireAutoUpdateLock(lockFile)).toBe(false);
123
+ });
124
+ it("reclaims a stale lock (older than TTL)", () => {
125
+ const staleAt = new Date(Date.now() - 30 * 60 * 1000).toISOString();
126
+ writeFileSync(lockFile, JSON.stringify({ at: staleAt, pid: 1 }));
127
+ expect(acquireAutoUpdateLock(lockFile)).toBe(true);
128
+ // 回收后应写入新时间戳
129
+ const after = JSON.parse(readFileSync(lockFile, "utf8"));
130
+ expect(Date.parse(after.at)).toBeGreaterThan(Date.parse(staleAt));
131
+ });
132
+ it("releaseAutoUpdateLock frees it for re-acquire", () => {
133
+ expect(acquireAutoUpdateLock(lockFile)).toBe(true);
134
+ releaseAutoUpdateLock(lockFile);
135
+ expect(acquireAutoUpdateLock(lockFile)).toBe(true);
136
+ });
137
+ });
69
138
  describe("isNewerVersion", () => {
70
139
  it("detects patch bump", () => {
71
140
  expect(isNewerVersion("0.0.2", "0.0.1")).toBe(true);
@@ -1 +1 @@
1
- {"version":3,"file":"update-check.test.js","sourceRoot":"","sources":["../src/update-check.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"update-check.test.js","sourceRoot":"","sources":["../src/update-check.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@geoly-ai/social-hub-cli",
3
- "version": "0.2.24",
3
+ "version": "0.2.26",
4
4
  "type": "module",
5
5
  "description": "social-hub CLI for Social Ops Hub",
6
6
  "repository": {
@@ -22,8 +22,8 @@
22
22
  },
23
23
  "dependencies": {
24
24
  "commander": "^12.1.0",
25
- "@geoly-ai/social-hub-authz": "0.0.7",
26
- "@geoly-ai/social-hub-sdk": "0.0.38"
25
+ "@geoly-ai/social-hub-authz": "0.0.8",
26
+ "@geoly-ai/social-hub-sdk": "0.0.41"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@types/node": "^22.10.2",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 1,
3
3
  "package": "social-ops-hub",
4
- "cliVersion": "0.2.24",
4
+ "cliVersion": "0.2.26",
5
5
  "repository": "social-ops-hub",
6
6
  "publish": {
7
7
  "registry": "https://skill.sh",
@@ -274,6 +274,18 @@ social-hub personas system-delete -p <persona-uuid>
274
274
  # 默认风格指南(系统级,无 -t):人设开箱即用的风格,账号无 style marks 时继承之
275
275
  social-hub personas style-guide-get --id <persona-uuid>
276
276
  social-hub personas style-guide-set --id <persona-uuid> -j '{"voiceTraits":["concise"],"toneTags":["friendly"]}'
277
+ # defaultStyleGuide 可嵌套 constitution(声音宪法·行为差异层)六维行为字段:
278
+ social-hub personas style-guide-set --id <persona-uuid> -j '{
279
+ "voiceTraits":["concise"],
280
+ "constitution":{
281
+ "attentionPriority":"先回应对方最具体的那个问题,再补背景",
282
+ "stanceOnUncertainty":"不确定就明说,不硬凑结论",
283
+ "disagreementStyle":"反对时先复述对方观点再给理由",
284
+ "closingBehavior":"结尾常抛一个反问,不总结陈词",
285
+ "detailDepth":"能给具体型号/参数就给,避免泛泛而谈",
286
+ "topicReflex":"遇到价格话题优先谈使用场景"
287
+ }
288
+ }'
277
289
  social-hub personas style-guide-set --id <persona-uuid> --clear
278
290
  # 人设级板块池(系统级,无 -t):账号经 personaId 解析候选板块,与团队无关;pet="common" 挂系统共享通用 pet 池
279
291
  social-hub personas pools-get --id <persona-uuid>
@@ -281,6 +293,26 @@ social-hub personas pools-set --id <persona-uuid> -j '{"starter":["r/iphone","r/
281
293
  social-hub personas pools-set --id <persona-uuid> --clear
282
294
  ```
283
295
 
296
+ ### constitution(声音宪法·行为差异层)
297
+
298
+ `defaultStyleGuide.constitution` 让系统级人设在「怎么行为」而非「怎么措辞」上分化,
299
+ 六维均可选,值必须是**行为规则短句**(描述频率/顺序/条件/取舍的行为,不是文案模板、
300
+ few-shot 示例或成品台词):
301
+
302
+ | 维度 | 写什么(行为规则,非文案) |
303
+ | --------------------- | --------------------------------- |
304
+ | `attentionPriority` | 优先关注/回应什么 |
305
+ | `stanceOnUncertainty` | 面对不确定时的处理方式 |
306
+ | `disagreementStyle` | 表达反对/分歧的方式 |
307
+ | `closingBehavior` | 收尾习惯 |
308
+ | `detailDepth` | 展开到多细 |
309
+ | `topicReflex` | 遇到某类话题的条件反射 |
310
+
311
+ 写入侧走 §5.5 确定性反模板校验:单维 2–160 字符;含 `{{}}`/代码围栏/`<占位>`/URL/
312
+ `template`/`模板`/`few-shot`/列表多段、或像成品文案(opener+句末标点、整句引号包裹、
313
+ 结尾感叹号)会 400;缺行为信号也会 400;六维**全空**(提交了 constitution 但都是空串)
314
+ 400。整个 constitution 缺省则允许(兼容存量)。**未知键 strict 400 拒**(不再静默吞)。
315
+
284
316
  ## 账号版本化人设(account_personas)
285
317
 
286
318
  ```bash
@@ -42,7 +42,7 @@ social-hub ops claim-next -t <team-id> --agent <agent-id>
42
42
  social-hub ops heartbeat|complete|fail|skip ...
43
43
  ```
44
44
 
45
- 遗留 `jobs agent-status` 仅在未接 ops 链路时使用。
45
+ 遗留 `jobs agent-status` 仅用于非发布动作且未接 ops 链路时。**`publish_post` / `publish_comment` 禁止走 `agent-status`**(会 400 拒)——发布必须走 ops `claim`→`complete` 过发布前审核门。
46
46
 
47
47
  ## 与 publishing 的关系
48
48
 
@@ -0,0 +1,92 @@
1
+ ---
2
+ name: social-hub-content-classification
3
+ description: >-
4
+ Social Hub 内容四轴分类(Phase B1a 最小控制面):content-classification get-subject 读某 hot_post
5
+ 的 current proposed 分类,spec list/get/create/activate 管理 classifier spec,presentation 读展示分层。
6
+ 用户要查某热帖被分成什么内容形态(comparison/review/tutorial/showcase/news/deal 等四轴),或
7
+ 建/激活分类器 spec、看 highlight/directional/control 展示配置时用本 skill。
8
+ 不用于板块风格画像/帖子标注(用 social-hub-style-profiles)、板块情报采集(用 social-hub-intelligence)。
9
+ metadata:
10
+ cliVersion: ">=0.2.25"
11
+ ---
12
+
13
+ # social-hub-content-classification
14
+
15
+ > **前置条件:** 先阅读 [`../social-hub-shared/SKILL.md`](../social-hub-shared/SKILL.md),
16
+ > 确认已 `auth login`(Device Code 的 CLI **user token**)。**spec 写操作仅 admin。**
17
+
18
+ Phase B1a 内容分类是把 `subreddit_hot_post_snapshots`(全站热帖快照)按四个正交轴分类的 pilot:
19
+ **content_forms**(多标签:comparison/review/tutorial/showcase/news/deal)、**intent**、**sentiment**、**format**。
20
+ worker(单实例 cron)按 active spec 对缺当前 revision 成功 run 的热帖跑 LLM 分类,结果 immutable 落 run 表。
21
+ 本控制面是**系统级只读 + spec 管理**:不做 accept/reject 治理(那是 Phase 2 / B1b)。
22
+
23
+ ## 关键概念
24
+
25
+ - **spec(classifier_specs)**:分类器 identity(purpose + taxonomy/prompt/input/format/truncation 版本 + modelPolicy),
26
+ immutable、`spec_fingerprint` 去重。同一 `purpose` 至多一个 `active`。改任一版本 = 新 spec。
27
+ - **run**:某 hot_post × subject revision hash × spec 的成功四轴结果,immutable。
28
+ - **current「proposed」**:active spec × 当前 hot_post 算 revision hash × 完整唯一键**精确查询**——
29
+ 1 行=`proposed`,0 行=`missing`(内容或 spec 变了就 missing,下轮 sweep 生成新 run,旧 run 永留审计)。
30
+ **绝不排序猜 latest。** 这是只读、幂等;三次读(active spec→hot_post→run)非原子,spec 切换窗口内相邻两次
31
+ 可能读到 proposed↔missing 抖动,重试即得稳定值。
32
+ - **purpose**:spec identity 的一部分,控制面与 worker 必须用**同一 canonical purpose**(缺省由服务端回退默认常量)
33
+ 才能对齐 active spec;自定义 purpose 时 `--purpose` 要两侧一致。
34
+
35
+ ## 关键约束(先读再操作)
36
+
37
+ - **spec 写(create / activate)仅 admin**,且 user-only:CLI 本地先拒 API Key,API 侧另拒服务/job token
38
+ 并要求真实登录用户(有 userId)+ admin 角色。manager 也**不可**写 spec(区别于 style-profiles 的 manager 可写)。
39
+ - **读(get-subject / spec list / spec get / presentation)**:非 client 内部角色(internal/senior/supervisor/manager/admin)可用,client 恒拒。
40
+ - 无 accept/reject 命令:pilot 不引人工裁决,只暴露 spec 管理 + 只读。
41
+
42
+ ## 读面
43
+
44
+ ```bash
45
+ # 某 hot_post 的 current proposed 分类(proposed|missing;404=无 active spec 或 hot_post 不存在)
46
+ social-hub content-classification get-subject --hot-post-id <uuid> [--purpose <p>]
47
+
48
+ # 该 purpose 当前 active spec(activeSpec:null = 尚未激活;完整历史枚举留 Phase 2)
49
+ social-hub content-classification spec list [--purpose <p>]
50
+
51
+ # 按 id 查任意 spec(含 draft / retired)
52
+ social-hub content-classification spec get --id <spec-uuid>
53
+
54
+ # 展示分层(highlight/directional/control forms;缺则契约默认,source 标注来源)
55
+ social-hub content-classification presentation
56
+ ```
57
+
58
+ ## spec 管理(admin only)
59
+
60
+ ```bash
61
+ # 1) 建 draft spec(同 fingerprint 已存在则幂等返回 created=false)
62
+ social-hub content-classification spec create -j '{
63
+ "purpose": "hot_post_content_classification_v1",
64
+ "taxonomyVersion": "b0-taxonomy-v1",
65
+ "taxonomySchemaVersion": "v1",
66
+ "promptVersion": "cc-prompt-v1",
67
+ "modelPolicy": { "provider": "openai", "model": "gpt-5.6-terra" }
68
+ }' --apply
69
+ # 可选覆盖:inputFingerprintVersion / truncationPolicyVersion / formatDetectorVersion(缺省由服务端补冻结版本)
70
+
71
+ # 2) 激活(退役同 purpose 现 active,若有;已 active 幂等);worker 下轮按新 active spec 重分类
72
+ social-hub content-classification spec activate --id <spec-uuid> --dry-run
73
+ social-hub content-classification spec activate --id <spec-uuid> --apply
74
+ ```
75
+
76
+ 所有写命令遵循 `--dry-run` 预览 / `--apply` 执行约定;create 会展示将写入的 spec identity。
77
+
78
+ ## API
79
+
80
+ - `GET /v1/system/content-classifications/subjects/:hotPostId`(current proposed;`?purpose=`)
81
+ - `GET /v1/system/content-classifications/specs`(该 purpose active spec;`?purpose=`)、`GET .../specs/:id`
82
+ - `POST /v1/system/content-classifications/specs`(建 draft,admin)、`POST .../specs/:id/activate`(激活,admin)
83
+ - `GET /v1/system/content-classifications/presentation`
84
+
85
+ 权限资源:`contentClassification`(读 read/list 非 client;写 create/activate 仅 admin + user-only)。
86
+
87
+ ## 常见排障
88
+
89
+ - `403 ... requires an authenticated admin user`:spec 写用了 API Key / 服务 token,或角色非 admin。改 `social-hub auth login` 的 admin CLI token。
90
+ - `404 no active classifier spec for purpose '<p>'`:该 purpose 还没激活过 spec,先 `spec create` + `spec activate`。
91
+ - `get-subject` 返回 `status:"missing"` 且 `staleHistoryExists:true`:该热帖有旧 revision/spec 的历史 run,但当前内容/spec 下无匹配 run,等 worker 下轮生成。
92
+ - `spec list` 返回 `activeSpec:null`:该 purpose 尚无 active spec。
@@ -53,10 +53,10 @@ enrich,**不要**在请求里传人设内容;`personaId` 传了只做一致
53
53
 
54
54
  ## 两种审核模式
55
55
 
56
- | 模式 | 请求 | 结论边界 |
57
- | --- | --- | --- |
58
- | `ContentOnly` | 省略 `accountId` | 返回 `reviewContext.accountMode=persona_less`;审核情境锚定、突发性、AI 腔、合规和重复度,但账号人设一致性只能 NotAssessed/弱验证 |
59
- | `AccountBound` | 传真实 `accountId` | 额外验证账号 persona/style 与品牌适配;最终发布前使用 |
56
+ | 模式 | 请求 | 结论边界 |
57
+ | -------------- | ------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
58
+ | `ContentOnly` | 省略 `accountId` | 返回 `reviewContext.accountMode=persona_less`;审核情境锚定、突发性、AI 腔、合规和重复度,但账号人设一致性只能 NotAssessed/弱验证 |
59
+ | `AccountBound` | 传真实 `accountId` | 额外验证账号 persona/style 与品牌适配;最终发布前使用 |
60
60
 
61
61
  ContentOnly 的 `completed/pass` 可作为内容通过,但必须记录
62
62
  `AccountBindingStatus: Pending`、`ReadyForDelivery: No`。
@@ -64,6 +64,33 @@ ContentOnly 的 `completed/pass` 可作为内容通过,但必须记录
64
64
  声称完成账号适配。
65
65
  `stage` 仅在值来自有效账号上下文时传;不确定就省略。
66
66
 
67
+ ### brandContext(可选品牌上下文)
68
+
69
+ 请求可带 `brandContext`(可省略),三种入口任选其一:
70
+
71
+ | 键 | 语义 |
72
+ | ------------ | ------------------------------------------------------------------------------------------------------------- |
73
+ | `brandKey` | registry canonical key 或 alias |
74
+ | `campaignId` | legacy 归因入口:Hub 解 campaignId→campaign.brandId→registry brandKey |
75
+ | `brandId` | **系统级 brand `brands.id`(来自 `brands system-list`,不是 `brand_registry.id`)**,与 publishing 新流程对齐 |
76
+
77
+ `brandId` 是新流程入口(与 social-hub-publishing「新流程用系统级 brandId、campaignId 仅
78
+ legacy 归因」一致),**persona-less 与账号路径都支持**。生命周期语义按路径不同:
79
+ persona-less 审核 active 优先、否则回退最新 retired;**账号路径 active-only**(账号品牌上下文是
80
+ persona-bound 的 identity selector,brandId 只解析 active 映射,无 active → 422
81
+ `BRAND_REGISTRY_METADATA_MISSING`)。账号路径的品牌上下文**仅账号已绑 persona 时才解析**,未绑
82
+ persona 则三入口一律静默忽略。多个入口解析到不同 canonical registry → 409 冲突。
83
+
84
+ ```bash
85
+ # persona-less(无 accountId)用系统级 brandId:
86
+ social-hub content review -t <team-id> -j '{
87
+ "draft": "<评论草稿>",
88
+ "commentType": "top_level",
89
+ "thread": { "subreddit": "buildapc", "postTitle": "..." },
90
+ "brandContext": { "brandId": "<brands.id from `brands system-list`>" }
91
+ }'
92
+ ```
93
+
67
94
  Reddit matrix 使用 fail-closed 规则:`degraded` / Hub 不可用不能作为
68
95
  发布通过,也不能用本地自审替代权威 Hub pass。
69
96
 
@@ -52,6 +52,24 @@ social-hub ops fail -t <team-id> --job <jobId> --agent "$AGENT" --reason rule_bl
52
52
  social-hub ops skip -t <team-id> --job <jobId> --agent "$AGENT" --reason manual_intervention_required
53
53
  ```
54
54
 
55
+ ## 执行内容与 fencing 契约(发布类任务 publish_post / publish_comment)
56
+
57
+ `claim` / `claim-next` 成功后,若是发布类任务,Hub 会在响应 + `context job` 里给出**服务端冻结的执行内容**与 **fencing 凭证**:
58
+
59
+ - **`executionContent`(唯一执行真源)**:过审冻结的发布正文——帖子 `title`/`body`,评论 `body` + 线程锚。**发布内容必须逐字段来自 `executionContent`**;**禁止**重新读取草稿(`contentDraftId`)/日历项/workspace,或自行生成/改写正文。缺失、类型错、hash 不符 → **fail,不得降级回草稿**。
60
+ - **`executionId` + `executionGeneration`(fencing pair)**:`executionId` 是高熵 token,**只从 claim/context 响应取,绝不写入日志、命令行 argv、interaction events**。
61
+ - **complete / fail / skip 必须原样回传这对 pair**(从本次 claim 拿到的值)。回传值与当前行不一致 → 被拒(堵「旧 agent 迟到回调完成/终止他人的新一代执行」)。`claim` 后草稿被改(版本漂移)时,冻结快照仍是过审版本;照发 `executionContent`、回传原 pair。
62
+
63
+ ### enforcement 灰度(Hub `EXECUTION_FENCING_ENFORCED`)
64
+
65
+ - **默认 OFF = shadow**:Hub 不强制 pair/executionContent,兼容尚未升级的 agent;claim 仍冻结、complete 仍走既有 detection。
66
+ - **ON = 强制**:按上述契约 fail-closed 校验。
67
+ - **翻 ON 的前提(Hub 与 OpenClaw 必须配套发布)**:OpenClaw/CLI 侧先支持接收 `executionContent`(HTTP body / CLI `--input-json-stdin`)并在 complete/fail/skip **原样回传 pair**;否则 flag ON 后 worker 执行无法合法 complete。发布顺序:部署 Hub(flag 仍 OFF)→ 升级 OpenClaw 回传 pair → 灰度 shadow 无异常 → API+worker **同时**设 `EXECUTION_FENCING_ENFORCED=true` 滚动重启(两侧值须一致)。
68
+
69
+ ### 诚实边界(Hub enforcement vs OpenClaw enforcement)
70
+
71
+ Hub 能保证:client 不能预置/篡改服务端字段、官方 worker executor 只收到冻结内容、complete 校验 hash/generation/pair、未 claim/错 holder/旧 generation 的 complete 被拒。**Hub 挡不住**:拿到 Reddit 会话的 agent 主动忽略 `executionContent`、自行输入别的正文,或用另一 token 重读草稿。真·强制依赖 agent(OpenClaw)遵守本契约——Hub 侧是「冻结 + 校验 + 审计漂移」,不是对平台写动作的物理拦截。
72
+
55
73
  ## `--reason` 枚举(仅允许下列值)
56
74
 
57
75
  `ip_drift`, `env_start_timeout`, `login_expired`, `wrong_account_logged_in`, `reddit_connection_failed`, `rte_failed`, `subreddit_banned`, `bot_bouncer_blocked`, `rule_blocked`, `manual_intervention_required`, `unknown`
@@ -62,7 +80,7 @@ social-hub ops skip -t <team-id> --job <jobId> --agent "$AGENT" --reason manual_
62
80
  `complete`/`fail`/`skip` 均幂等:同终态重试返回成功(`alreadyCompleted`/`alreadyTerminal`),跨终态冲突返回 409。
63
81
  cron 周期任务无论 complete/fail/skip 都会自动生成下一期(按原 runAt 推算),循环链不断。skip 的终态是 `skipped`(可用 `--status skipped` 筛出)。
64
82
 
65
- 遗留路径 `jobs agent-status` 仅在未接 ops 链路时使用(见 `social-hub-calendar-jobs`)。
83
+ 遗留路径 `jobs agent-status` 仅用于非发布动作且未接 ops 链路时。**`publish_post` / `publish_comment` 禁止走 `agent-status`**(会 400 拒)——发布必须走 ops `claim`→`complete`,才能过发布前审核门(review gate + 执行快照冻结)。见 `social-hub-calendar-jobs`。
66
84
 
67
85
  ## 写操作护栏
68
86
 
@@ -41,30 +41,56 @@ social-hub content post-review -t <team-id> -j '{
41
41
 
42
42
  ## 两种审核模式
43
43
 
44
- | 模式 | 请求 | 结论边界 |
45
- | --- | --- | --- |
46
- | `ContentOnly` | 省略 `accountId` | 响应为 `reviewContext.accountMode=persona_less`;可审核标题正文、软广、AI 结构、规则证据和发帖动机,但不能声称账号人设适配已完成 |
47
- | `AccountBound` | 传真实 `accountId` | 在内容审核外验证账号 persona/style 与品牌适配;最终发布前使用 |
44
+ | 模式 | 请求 | 结论边界 |
45
+ | -------------- | ------------------ | -------------------------------------------------------------------------------------------------------------------------------- |
46
+ | `ContentOnly` | 省略 `accountId` | 响应为 `reviewContext.accountMode=persona_less`;可审核标题正文、软广、AI 结构、规则证据和发帖动机,但不能声称账号人设适配已完成 |
47
+ | `AccountBound` | 传真实 `accountId` | 在内容审核外验证账号 persona/style 与品牌适配;最终发布前使用 |
48
48
 
49
49
  ContentOnly 的 `completed/pass` 是内容结论,不是最终发布资格。应标记
50
50
  `AccountBindingStatus: Pending`、`ReadyForDelivery: No`;
51
51
  `accountCandidateFeedback` 只做账号候选建议,不阻断内容审核。
52
52
  `stage` 仅在值来自有效账号上下文时传;不确定就省略。
53
53
 
54
+ ### brandContext(可选品牌上下文)
55
+
56
+ 请求可带 `brandContext`(可省略),三种入口任选其一:
57
+
58
+ | 键 | 语义 |
59
+ | ------------ | ------------------------------------------------------------------------------------------------------------- |
60
+ | `brandKey` | registry canonical key 或 alias |
61
+ | `campaignId` | legacy 归因入口:Hub 解 campaignId→campaign.brandId→registry brandKey |
62
+ | `brandId` | **系统级 brand `brands.id`(来自 `brands system-list`,不是 `brand_registry.id`)**,与 publishing 新流程对齐 |
63
+
64
+ `brandId` 是新流程入口(与 social-hub-publishing「新流程用系统级 brandId、campaignId 仅
65
+ legacy 归因」一致),**persona-less 与账号路径都支持**。生命周期语义按路径不同:persona-less
66
+ active 优先、否则回退最新 retired;**账号路径 active-only**(无 active 映射 → 422
67
+ `BRAND_REGISTRY_METADATA_MISSING`)。账号路径品牌上下文**仅账号已绑 persona 时才解析**,未绑
68
+ persona 则三入口一律静默忽略。多个入口解析到不同 canonical registry → 409 冲突。
69
+
70
+ ```bash
71
+ # persona-less(无 accountId)用系统级 brandId:
72
+ social-hub content post-review -t <team-id> -j '{
73
+ "title": "<帖子标题>",
74
+ "body": "<帖子正文>",
75
+ "subreddit": "buildapc",
76
+ "brandContext": { "brandId": "<brands.id from `brands system-list`>" }
77
+ }'
78
+ ```
79
+
54
80
  Reddit matrix 的发布闸门比本通用 skill 更严格:`degraded` 或 Hub
55
81
  不可用只能诊断,不能替代 Hub pass。
56
82
 
57
83
  ## 七维口径(0-100,服务端计分,模型自报分仅对照)
58
84
 
59
- | 维度 | 判什么 |
60
- | --------------------------- | --------------------------------------------------------------------------------------- |
61
- | `title_body_fit` | 标题承诺 vs 正文兑现(bait-and-switch 低分) |
62
- | `clickbait_or_manipulation` | 标题党/情绪操纵/虚假紧迫(<35 单维红线 block) |
63
- | `promotion_risk` | 软广/导流/品牌推销痕迹(<40 单维红线 block) |
64
- | `subreddit_rule_fit` | 只按提供的版规快照判;**没传版规 → 该维标 insufficient_context 并被剔除权重,不伪造结论** |
65
- | `ai_structural_tone` | 小标题排比/总分总/清单腔等 AI 结构感 |
85
+ | 维度 | 判什么 |
86
+ | --------------------------- | ------------------------------------------------------------------------------------------------- |
87
+ | `title_body_fit` | 标题承诺 vs 正文兑现(bait-and-switch 低分) |
88
+ | `clickbait_or_manipulation` | 标题党/情绪操纵/虚假紧迫(<35 单维红线 block) |
89
+ | `promotion_risk` | 软广/导流/品牌推销痕迹(<40 单维红线 block) |
90
+ | `subreddit_rule_fit` | 只按提供的版规快照判;**没传版规 → 该维标 insufficient_context 并被剔除权重,不伪造结论** |
91
+ | `ai_structural_tone` | 小标题排比/总分总/清单腔等 AI 结构感 |
66
92
  | `persona_consistency` | AccountBound 时判断账号人设;ContentOnly/persona_less 时只能标 NotAssessed/弱验证,不得声称已验证 |
67
- | `natural_post_intent` | 真人为何发这帖(无动机的"分享产品体验"低分) |
93
+ | `natural_post_intent` | 真人为何发这帖(无动机的"分享产品体验"低分) |
68
94
 
69
95
  ## 判定规则
70
96