@geoly-ai/social-hub-cli 0.3.18 → 0.3.20
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.
- package/CHANGELOG.md +29 -0
- package/dist/cmd-manifest.json +4 -2
- package/dist/content-review.test.js +1 -1
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +98 -8
- package/dist/index.js.map +1 -1
- package/dist/register-calendar-directives.d.ts +64 -0
- package/dist/register-calendar-directives.d.ts.map +1 -0
- package/dist/register-calendar-directives.js +135 -0
- package/dist/register-calendar-directives.js.map +1 -0
- package/dist/register-calendar-directives.test.d.ts +2 -0
- package/dist/register-calendar-directives.test.d.ts.map +1 -0
- package/dist/register-calendar-directives.test.js +127 -0
- package/dist/register-calendar-directives.test.js.map +1 -0
- package/dist/scrape-output.test.d.ts +2 -0
- package/dist/scrape-output.test.d.ts.map +1 -0
- package/dist/scrape-output.test.js +58 -0
- package/dist/scrape-output.test.js.map +1 -0
- package/package.json +2 -2
- package/skills/README.md +23 -22
- package/skills/manifest.json +6 -1
- package/skills/reddit-content-rewrite/SKILL.md +29 -0
- package/skills/reddit-content-writing/SKILL.md +54 -5
- package/skills/reddit-content-writing/references/phase4-execution-table.md +24 -3
- package/skills/reddit-content-writing/references/phase4-writing.md +123 -3
- package/skills/reddit-content-writing/references/post-writing-templates.md +14 -6
- package/skills/reddit-delivery-check/SKILL.md +39 -6
- package/skills/reddit-delivery-check/references/phase5-delivery.md +7 -1
- package/skills/reddit-matrix.lock.json +10 -10
- package/skills/reddit-phase-brief/SKILL.md +62 -11
- package/skills/reddit-phase-brief/references/brand-SKU-PGC-rules.md +223 -36
- package/skills/reddit-phase-brief/references/phase4-brief-workflow.md +405 -19
- package/skills/reddit-phase-planning/SKILL.md +13 -0
- package/skills/reddit-phase-planning/references/phase4-execution-table.md +16 -2
- package/skills/reddit-phase-planning/references/phase4-planning.md +74 -15
- package/skills/reddit-phase-planning/references/scheduling-decision-procedure.md +386 -0
- package/skills/reddit-phase-research/SKILL.md +7 -1
- package/skills/reddit-phase-research/references/phase01-research.md +93 -29
- package/skills/reddit-strategy-orchestrator/SKILL.md +120 -18
- package/skills/reddit-strategy-shared/SKILL.md +4 -2
- package/skills/reddit-strategy-shared/references/content-diversity-contract.md +26 -5
- package/skills/reddit-strategy-shared/references/content-review-gate.md +48 -1
- package/skills/reddit-strategy-shared/references/context-contract.md +45 -11
- package/skills/reddit-strategy-shared/references/evidence-policy.md +139 -0
- package/skills/reddit-strategy-shared/references/handoff-schemas.md +88 -3
- package/skills/reddit-strategy-shared/references/native-copy-profile.md +207 -0
- package/skills/reddit-strategy-shared/references/path-conventions.md +26 -4
- package/skills/reddit-strategy-shared/references/persona-card-contract.md +210 -0
- package/skills/reddit-strategy-shared/references/prerequisites/README.md +57 -0
- package/skills/reddit-strategy-shared/references/prerequisites/{reddit-master-canvas-agent-prompt-template.md → archive/reddit-master-canvas-agent-prompt-template.md} +7 -0
- package/skills/reddit-strategy-shared/references/prerequisites/{reddit-sop-v2-universal.md → archive/reddit-sop-v2-universal.md} +7 -0
- package/skills/reddit-strategy-shared/references/prerequisites/{reddit-strategy-prerequisites-read.md → archive/reddit-strategy-prerequisites-read.md} +7 -0
- package/skills/reddit-strategy-shared/references/prerequisites/{reddit-strategy-reuse-playbook.md → archive/reddit-strategy-reuse-playbook.md} +7 -0
- package/skills/reddit-strategy-shared/references/subreddit-research-profile.md +514 -0
- package/skills/reddit-strategy-shared/references/version-manifest.md +89 -2
- package/skills/reddit-subreddit-compliance/SKILL.md +28 -1
- package/skills/reddit-voc-volume/matrix-contract.md +16 -1
- package/skills/social-hub-calendar-directives/SKILL.md +548 -0
- package/skills/social-hub-calendar-jobs/SKILL.md +10 -0
- package/skills/social-hub-cli/SKILL.md +2 -0
- package/skills/social-hub-notifications/SKILL.md +7 -0
- package/skills/social-hub-publishing/SKILL.md +5 -0
|
@@ -12,7 +12,8 @@ Full-flow strategy work must collect or confirm:
|
|
|
12
12
|
- Deliverable type and volume
|
|
13
13
|
- Delivery target: Feishu folder/doc link, local Markdown only, or both
|
|
14
14
|
- Whether strict A/B testing is required
|
|
15
|
-
- If A/B is required: single test variable, A/B group symmetry, and whether external comments are excluded from the main A/B sample
|
|
15
|
+
- If A/B is required: single test variable, A/B group symmetry, and whether external comments are excluded from the main A/B sample (**default: excluded** — external comments are supplementary observation only; readout rule in `reddit-phase-planning/references/phase4-planning.md` Phase 4.0.5)
|
|
16
|
+
- Contract pricing unit: whether the contract is priced in 「量」(a unit that bundles posts and self-comments, e.g. 1 post + 3 self-comments = 1 unit — posts and comments are not the same cost unit and are never simply summed) or in direct post/comment counts; plus the total allowance and the confirmation source (Phase 4.0.0.0 blocks the quantity plan until this is confirmed; never assume an example ratio)
|
|
16
17
|
- Whether competitor mentions are allowed
|
|
17
18
|
- Review mode when content is generated: ContentOnly if the final publishing account is not selected; AccountBound only after the real account and approved brand context are known
|
|
18
19
|
- Brief approval mode: client review first, internal confirmation only, or unknown
|
|
@@ -24,19 +25,40 @@ Full-flow strategy work must collect or confirm:
|
|
|
24
25
|
|
|
25
26
|
## Startup Prerequisites
|
|
26
27
|
|
|
27
|
-
For full-flow projects, read the shared contracts
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
28
|
+
For full-flow projects, read the shared contracts (`routing.md`, `evidence-policy.md`,
|
|
29
|
+
`context-contract.md`, `handoff-schemas.md`, `safety-rules.md`) — **and nothing else** before Phase 0.
|
|
30
|
+
|
|
31
|
+
**Phase-scoped contracts (read on entering the phase that consumes them, not at startup):**
|
|
32
|
+
|
|
33
|
+
| Contract | Read before | Owner / consumers |
|
|
34
|
+
|---|---|---|
|
|
35
|
+
| `references/content-type-routing-contract.md` | Phase 4 Brief structure routing | brief / writing / rewrite / delivery |
|
|
36
|
+
| `references/content-diversity-contract.md` | Phase 4 Brief baseline + fingerprint | brief / writing / rewrite / delivery |
|
|
37
|
+
| `references/subreddit-research-profile.md` (SRP) | Phase 0.5 step 0.5.5, and any compliance / brief / planning step that consumes subreddit-level conclusions | research produces; compliance / planning / brief consume |
|
|
38
|
+
| `reddit-phase-planning/references/scheduling-decision-procedure.md` (D1–D7) | Phase 4.0.0.4 board quantity planning | planning owns; brief reads `memory/phase4-排期决策台账.md`, not the procedure |
|
|
39
|
+
|
|
40
|
+
Keeping these out of the startup read is deliberate: the startup budget is the five
|
|
41
|
+
shared contracts above. Loading a phase contract early is not a gate failure, but
|
|
42
|
+
skipping it when its phase starts is.
|
|
43
|
+
|
|
44
|
+
> **⛔ 那四份 prerequisite 文件已归档,agent 不得读取。**
|
|
45
|
+
> `reddit-strategy-prerequisites-read.md` / `reddit-strategy-reuse-playbook.md` /
|
|
46
|
+
> `reddit-sop-v2-universal.md` / `reddit-master-canvas-agent-prompt-template.md` 已移入
|
|
47
|
+
> `references/prerequisites/archive/`(`AgentReadPolicy: DoNotRead`)。
|
|
48
|
+
>
|
|
49
|
+
> **为什么**:这四份共 1,994 行,占全流程强制阅读量的 80%,而它们自己声明
|
|
50
|
+
> `LegacyStatus: Superseded`、"Do not execute any gate, schema, or structure rule found in them"
|
|
51
|
+
> —— 同时其中的规则又与 active 文件里的硬规则**逐条重复**。一份"声明不作数、内容却一致"的
|
|
52
|
+
> 文本进入上下文,模型无从区分哪句该执行,只会稀释真正的门禁。
|
|
53
|
+
>
|
|
54
|
+
> 需要人工查阅历史背景时见 `references/prerequisites/README.md`(该 README 可读、非必读,
|
|
55
|
+
> 只做转发与真空登记)。**active 文档不得再要求 agent 读取 archive 内容,引用即 gate failure。**
|
|
35
56
|
|
|
36
57
|
**v2.12.25 legacy scope (binding).** `reddit-strategy-reuse-playbook.md` and
|
|
37
58
|
`reddit-sop-v2-universal.md` are marked `LegacyStatus: Superseded` /
|
|
38
|
-
`UseAsWritingGate: No` / `UseAsPlanningGate: No
|
|
39
|
-
|
|
59
|
+
`UseAsWritingGate: No` / `UseAsPlanningGate: No`, and they are now under
|
|
60
|
+
`prerequisites/archive/` with `AgentReadPolicy: DoNotRead` — **agents do not read
|
|
61
|
+
them at all** (human historical reference only). Never take from them: post structure, opening-sentence form, title formulas,
|
|
40
62
|
per-paragraph format checklists, or the execution-table schema. Their
|
|
41
63
|
four-paragraph body structure, title-formula section, format-prohibition
|
|
42
64
|
checklist, and 14-field table were **deleted** in v2.12.25. The replacements are:
|
|
@@ -61,6 +83,7 @@ Use `memory/` as the working truth store:
|
|
|
61
83
|
- `phase2-缺口分析.md`
|
|
62
84
|
- `phase3-master-canvas摘要.md`
|
|
63
85
|
- `phase4-board-quantity-plan.md`
|
|
86
|
+
- `phase4-排期决策台账.md`
|
|
64
87
|
- `phase4-sku-基准表.md`
|
|
65
88
|
- `phase4-执行表.md`
|
|
66
89
|
- `phase4-external-post-audit.md`
|
|
@@ -88,6 +111,17 @@ Use `memory/` as the working truth store:
|
|
|
88
111
|
- Phase 2 must write `phase2-缺口分析.md`.
|
|
89
112
|
- Phase 3 must write `phase3-master-canvas摘要.md` and confirm all 21 Master Canvas boards.
|
|
90
113
|
- Phase 4.0.0 must write `phase4-board-quantity-plan.md` and `phase4-sku-基准表.md`.
|
|
114
|
+
- Phase 4.0.0.4 must run the D1–D7 scheduling decision procedure
|
|
115
|
+
(`reddit-phase-planning/references/scheduling-decision-procedure.md`) and write
|
|
116
|
+
`phase4-排期决策台账.md`: one row per planned post keyed by execution-table `Key`, all 9 fields
|
|
117
|
+
present, including `ProposedFlair` (the execution table has no flair column). Owner:
|
|
118
|
+
`reddit-phase-planning`. `reddit-phase-brief` reads it to verify and lock `AssignedFlair`;
|
|
119
|
+
a missing ledger or `ProposedFlair` is a `BlockingGap` back to planning, not a licence for the
|
|
120
|
+
Brief to pick its own flair.
|
|
121
|
+
- Phase 0.5 step 0.5.5 must produce one `SubredditResearchProfile`
|
|
122
|
+
(`references/subreddit-research-profile.md`) per passing subreddit alongside
|
|
123
|
+
`phase0.5-board-analysis.md`; boards with no SRP are declared `SRPMode: Fallback` downstream,
|
|
124
|
+
which is **not** the same as `confidence: Insufficient`.
|
|
91
125
|
- Phase 4.0 must write `phase4-执行表.md`; if external comment URLs exist, EPA results must be recorded in `phase4-external-post-audit.md` or as an `外部核验` control column.
|
|
92
126
|
- Phase 4.0.6 must write `phase4-SKU品牌词映射.md` and `phase4-撰写批次map.md`.
|
|
93
127
|
- Phase 4 Brief must write `phase4-内容排期表.md` and `phase4-撰写brief.md`; writing cannot start until the required Brief approval phrase is present.
|
|
@@ -70,3 +70,142 @@ Use this file to resolve conflicts between Reddit strategy sources. If older pla
|
|
|
70
70
|
- The next phase may start only when the response shows `readyForNextSkill=true` and `blockingIssues=[]`. Missing fields / blocking issues must be resolved. If the user explicitly accepts a partial handoff, the waiver MUST be written back to Hub (re-run `handoff-create` with the waiver recorded in the payload, e.g. `weeklyReportWaiver` or an explicit `partialAcceptedBy` field) so the new handoff itself becomes ready — local bypass without a Hub-persisted waiver is NOT allowed.
|
|
71
71
|
- Standalone single-skill runs are encouraged but not required to persist handoffs.
|
|
72
72
|
- Local `memory/*.md` files remain the working copy for one release cycle (dual-write); each memory file SHOULD record the associated Hub `runId`(s) and handoff id for traceability. Do not delete local memory in this release.
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
# 证据门(Gates)
|
|
77
|
+
|
|
78
|
+
本节把上面的来源分层与冲突消解落成**可检查的门禁**。门禁编号是稳定标识,下游 skill 引用时用编号
|
|
79
|
+
(如 `G3`),不要复述规则正文——复述会分叉。
|
|
80
|
+
|
|
81
|
+
## G3 · URL 存活状态三字段
|
|
82
|
+
|
|
83
|
+
**规则.** 任何产出中出现的 Reddit URL,只要它**被当作证据**(支撑某个结论、被列为对标帖、被引用为
|
|
84
|
+
样本或先例),就必须**可追溯到一次真实采集记录**,并带齐存活状态三字段
|
|
85
|
+
(**观测时刻 + 核验时刻 + 当前状态**):
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
ObservedAt: # 三字段之一(必填):这条 URL 被真实采集到的时刻
|
|
89
|
+
ArchivedObservedAt: # ObservedAt 在归档来源(如 Arctic)上的具体形态;
|
|
90
|
+
# live-only 来源填 null 并注明,不得为了凑字段编一个归档时刻
|
|
91
|
+
LastVerifiedAt: # 三字段之二(必填):最近一次状态核验时刻
|
|
92
|
+
CurrentStatus: # 三字段之三(必填):Live | Removed | Deleted | Unknown
|
|
93
|
+
EvidenceRef: # 指回采集记录(run / evidence / sample)——「可追溯」的落点
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
**适用面(避免过宽):**
|
|
97
|
+
|
|
98
|
+
| URL 类型 | 是否受 G3 约束 |
|
|
99
|
+
|---|---|
|
|
100
|
+
| **证据 URL**(支撑结论、对标帖、样本、先例) | **受约束**,三字段齐全 |
|
|
101
|
+
| **导航/参考 URL**(板块首页、规则页链接等纯导航,不作为结论依据) | 不受约束 |
|
|
102
|
+
| **历史研究样本** | 受约束,但**允许 `CurrentStatus: Removed`**(历史存在过是有效事实) |
|
|
103
|
+
| **当期排期用 URL**(排期对标帖、要去回复的外部评论) | 受约束,且必须 `CurrentStatus: Live` |
|
|
104
|
+
|
|
105
|
+
**`Live` 的定义不等于「每次都直连 Reddit」。** Hub-First 允许新鲜缓存直接消费、零 Reddit 请求
|
|
106
|
+
(`reddit-voc-volume/references/hub-first.md` L1)。因此:
|
|
107
|
+
|
|
108
|
+
> `CurrentStatus: Live` = **Hub 当前状态记录仍在 freshness window 内**,或经过一次明确的 live probe。
|
|
109
|
+
|
|
110
|
+
没有新鲜状态记录时 → `Unknown` → **hold**,不得把 stale 或 `failed` 当成 `Live`。这条与 Hub-First
|
|
111
|
+
的缓存优先原则不冲突:G3 要求的是「有新鲜的状态事实」,不是「必须重新请求」。
|
|
112
|
+
|
|
113
|
+
**数量不足时诚实少给,禁止补齐。** 需要 10 条对标帖只核到 6 条 → 给 6 条 + 记缺口,
|
|
114
|
+
**不得**用未核验、编造、或从别处凑来的 URL 补到 10。
|
|
115
|
+
|
|
116
|
+
**与既有枚举的映射(G3 是消费口径,不是新建的存储枚举):**
|
|
117
|
+
|
|
118
|
+
| 既有来源 | 既有取值 | 映射到 `CurrentStatus` |
|
|
119
|
+
|---|---|---|
|
|
120
|
+
| 帖子/评论存活观测(`packages/contracts/src/reddit-post-survival.ts`) | `alive` / `dead` / `unknown` / `unsupported` | `Live` / `Removed`\|`Deleted`(按来源给出的删除类型)/ `Unknown` / `Unknown` |
|
|
121
|
+
|
|
122
|
+
**`subreddit_evidence` 的 `available` / `not_visible` / `failed` 不参与本映射。** 那是**板块证据
|
|
123
|
+
页面/项目**的可见性,与某条帖子 URL 的存活是两个正交的轴:rules 页不可见推不出任何帖子被移除。
|
|
124
|
+
把 `not_visible` 映射成 `CurrentStatus: Removed` 是类型错误,禁止。
|
|
125
|
+
|
|
126
|
+
来源未区分「版主移除」与「作者自删」时,**不得猜**——填 `Removed` 或 `Deleted` 之一都是编造,
|
|
127
|
+
应填 `Unknown` 并在 note 说明。**「作者账号已注销」是正交属性**,不等于帖子被删,不得映射成
|
|
128
|
+
`Deleted`。存活状态出现 `dead → alive` 这类冲突时按既有约定交人工,G3 不静默翻转。
|
|
129
|
+
|
|
130
|
+
**保留既有语义:** `failed` ≠「不存在」;只有页面明确显示不存在(`not_visible`)才是负证据。
|
|
131
|
+
采集时点的 `_removed` 标记只反映采集时点,不等于当前状态——当前状态看 `LastVerifiedAt` +
|
|
132
|
+
`CurrentStatus`。
|
|
133
|
+
|
|
134
|
+
**失败后果.** 缺字段或 `CurrentStatus: Unknown` 的证据 URL → 从该结论的证据集中剔除;
|
|
135
|
+
若剔除后结论失去支撑 → `BlockingGap`。
|
|
136
|
+
|
|
137
|
+
## G5 · 来源职责矩阵
|
|
138
|
+
|
|
139
|
+
上面的 Source Layers 表已经写清了**每层是什么**;G5 补的是**每层能支撑什么结论、不能支撑什么**。
|
|
140
|
+
来源类型 × 结论类型是一个合法矩阵,越界即证据不成立——**不是「弱证据」,是「无证据」**。
|
|
141
|
+
|
|
142
|
+
| 来源 | 可支撑 | **不可支撑** |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| `eclickkb` / 品牌 KB | SKU、规格、价格、产品事实 | subreddit 帖型可行性、板块风格、合规裁决、禁用话术清单 |
|
|
145
|
+
| 客户约束材料(info sheet / 合同 / 书面确认) | 禁用话术、优先 SKU、竞品提及许可、目标市场、交付量 | 产品规格真值、版规、板块分布 |
|
|
146
|
+
| KG markdown(`kg-reddit-check`) | positioning、场景、叙事方向 | 产品规格、版规、板块分布 |
|
|
147
|
+
| Hub **帖子样本**(hot-posts / 历史帖 / 全窗口采样) | SRP 的帖子分布、内容类型、互动样本、标题风格 | 版规结论、发布放行(**样本 ≠ 规则证据**;规则证据见下一行,它是有效的**原始**规则来源) |
|
|
148
|
+
| Hub `rules`/`wiki`/`about`/`submit_text`/`pinned`/`flair` 原始证据 | compliance 的**输入** | 直接宣布「允许 / 禁止」(那是 compliance 的裁决) |
|
|
149
|
+
| `reddit-subreddit-compliance` 输出 | 板块 eligibility、risk、账号门槛 | 产品事实、价格、规格 |
|
|
150
|
+
| SRP(`references/subreddit-research-profile.md`,`Verified` 也只是必要输入) | 板块整体分布、进入方式的证据、风险信号 | 发布放行、单 flair 写作规格 |
|
|
151
|
+
| baseline 卡 | 单 flair 写作基线与风格门 | 独立发布放行、板块总体占比 |
|
|
152
|
+
| 帖子级分类(`content_classification_runs`) | 帖子级内容类型事实、SRP `contentTypes` 的原料 | 版规结论、发布放行 |
|
|
153
|
+
| 人工标注(`subreddit_post_annotations`) | 帖子对板块/品牌的 1–5 分**人工评价** | content type taxonomy、写作基线、发布放行 |
|
|
154
|
+
| approved `subreddit_style_profiles` | 审核门 soft enrich(tone/taboo) | SRP 总体统计、合规裁决 |
|
|
155
|
+
|
|
156
|
+
**典型越界(必须拦):** 据品牌语料库/KB 宣布「所有帖子内容类型和板块安排均与语料库无冲突」。
|
|
157
|
+
品牌 KB 里没有 subreddit 版规,也没有板块分布——它**结构上**无法支撑这个结论。正确路径是
|
|
158
|
+
compliance(裁决)+ SRP(分布证据)。
|
|
159
|
+
|
|
160
|
+
**检查点命名.** 引用时用 `G5-<来源>×<结论>` 越界的形式描述,不要引用尚不存在的 validator 脚本;
|
|
161
|
+
runtime 校验属于后续变更。
|
|
162
|
+
|
|
163
|
+
## G6 · fail-closed 的适用面与例外
|
|
164
|
+
|
|
165
|
+
**核心区分:证据要求 ≠ 采集通道。** 采集通道可以降级,证据要求不可以。混淆这两者就是那类
|
|
166
|
+
「eclickkb 超时了,先用能拿到的 SKU 文档继续」——恢复后发现价格与时效冲突、已进排期的卖点全线返工。
|
|
167
|
+
|
|
168
|
+
### 两段式判定
|
|
169
|
+
|
|
170
|
+
**第一段:结论属于哪类?**
|
|
171
|
+
|
|
172
|
+
| 结论类型 | 处理 |
|
|
173
|
+
|---|---|
|
|
174
|
+
| 合规结论(能不能发、发什么受限) | **fail-closed** |
|
|
175
|
+
| URL 真实性 / 存活状态 | **fail-closed**(见 G3) |
|
|
176
|
+
| 数字、规格、价格、时效 | **fail-closed** |
|
|
177
|
+
| 品牌位置依据(`BrandEntryMode` 等结构决策的依据) | **fail-closed** |
|
|
178
|
+
|
|
179
|
+
fail-closed 的含义是:证据拿不到就**拦截**,输出 `Unknown` / `BlockingGap` / `Hold`。
|
|
180
|
+
**不得「先用能拿到的继续」**,不得用相邻来源顶替(那会同时违反 G5)。
|
|
181
|
+
|
|
182
|
+
**表里没列的结论不是「随便放行」,也不是「一律拦截」。** 普通定性研究结论(板块氛围、讨论方向、
|
|
183
|
+
风格观察等)按证据强度**降级表述**即可:标 `claimScope: SampleOnly` 或整体 `Provisional`,
|
|
184
|
+
说明样本口径,不进入 fail-closed 拦截;但它们同样不得升格去支撑上表四类结论。
|
|
185
|
+
|
|
186
|
+
**第二段:采集通道怎么走?**
|
|
187
|
+
|
|
188
|
+
采集通道**允许受控降级,不拦截**:Hub cache(L1)→ Hub 派发(L2)→ Emergency Acquisition(L3)
|
|
189
|
+
→ 回灌(L4),见 `reddit-voc-volume/references/hub-first.md`;429 走 Emergency Acquisition + 回灌。降级必须标
|
|
190
|
+
`provenance` 与 `fallbackReason`。
|
|
191
|
+
|
|
192
|
+
**通道全部失败时回到第一段**:证据缺失 → 按结论类型 fail-closed,输出 `Unknown` / `BlockingGap` /
|
|
193
|
+
`Hold`。通道降级用尽**不构成**放行理由。
|
|
194
|
+
|
|
195
|
+
**超时不是失败,也不是「无数据 / 无规则」。** 超时是**中间态**:输出 pending,并按 Hub-First 继续
|
|
196
|
+
往下一级通道走(L2 超时后仍可进 L3 Emergency Acquisition)。**在 fallback 走完之前不得下结论**,
|
|
197
|
+
也不得把 pending 当成「查过了、没有」。
|
|
198
|
+
|
|
199
|
+
**G3/G5/G6 的 `Unknown` / `BlockingGap` / `Hold` 是流程与证据状态,不是 claim 状态。**
|
|
200
|
+
进入可发布文本的实质性 claim 仍然一律走本文件上半部分的 `ClaimEvidenceStatus`
|
|
201
|
+
三态(`Cited` / `ExternallyVerified` / `Inferred`)——门禁状态不替代、也不放宽那三态。
|
|
202
|
+
|
|
203
|
+
### 有意 fail-open:不得改
|
|
204
|
+
|
|
205
|
+
已批准的板块画像用于**审核门 soft enrich** 时,现有实现**有意 fail-open**(画像查询/渲染异常时审核
|
|
206
|
+
继续,软维度由服务端剔除;见 `packages/review-engine/src/context/review-context-provider.ts`
|
|
207
|
+
`loadSubredditStyleProfile` 的注释)。**保持不动。**
|
|
208
|
+
|
|
209
|
+
该 fail-open 的适用面**仅限 style-profile soft enrich**,**不适用于** SRP、compliance、URL 真实性、
|
|
210
|
+
产品事实证据——那些一律按第一段 fail-closed。persona / brand enrich 同样仍是 fail-closed
|
|
211
|
+
(它们影响 block 语义)。
|
|
@@ -20,6 +20,15 @@ Required:
|
|
|
20
20
|
- `GeolyTopicId`
|
|
21
21
|
- `Phase16Status`
|
|
22
22
|
- `EvidenceGaps`
|
|
23
|
+
- `SubredditResearchProfiles` — every SRP that could be produced, one per passing subreddit;
|
|
24
|
+
a subreddit without one is listed explicitly with its reason, never silently omitted (contract:
|
|
25
|
+
`references/subreddit-research-profile.md`; produced by `reddit-phase-research` step 0.5.5 per S1–S9,
|
|
26
|
+
handed over with `memory/phase0.5-board-analysis.md`). Each profile must name its
|
|
27
|
+
`Confidence` and `AllowedUses` in `RequiredFieldsProvided` (SRP §12).
|
|
28
|
+
`Confidence: Insufficient` is a `BlockingGap` / `ReadyForNextPhase: No` — never a "use it for now".
|
|
29
|
+
A board with **no** SRP is not an error by itself; it is declared downstream as `SRPMode: Fallback`
|
|
30
|
+
(see `reddit-phase-planning/references/scheduling-decision-procedure.md` §0.1) — do not confuse it
|
|
31
|
+
with `Insufficient`.
|
|
23
32
|
|
|
24
33
|
## Compliance Output
|
|
25
34
|
|
|
@@ -37,15 +46,60 @@ Required:
|
|
|
37
46
|
- `NeedsVerificationCandidates`
|
|
38
47
|
- `NotRecommended`
|
|
39
48
|
- `MissingEvidence`
|
|
49
|
+
- `EvidenceGatheredAt`
|
|
50
|
+
- `EvidenceValidUntil`
|
|
40
51
|
|
|
41
52
|
`AboutPageEvidenceStatus=NeedsAcquisition` is required when `reddit-voc-volume about-page` reports `about_page_empty_rendered_content`; downstream skills must not treat that as `NotVisible`.
|
|
42
53
|
|
|
54
|
+
**Compliance evidence is a point-in-time snapshot, and this handoff carries the
|
|
55
|
+
time it was taken — not a standing clearance.** A batch is scheduled and
|
|
56
|
+
delivered after this report is written, and rules and pinned posts change in
|
|
57
|
+
between, so the report must say how old it is.
|
|
58
|
+
|
|
59
|
+
- `EvidenceGatheredAt` / `EvidenceValidUntil` are **batch-level worst-case
|
|
60
|
+
scalars**, defined precisely so a single pair is checkable: `EvidenceGatheredAt`
|
|
61
|
+
is the **earliest** gathering time among the delivery-required evidence items,
|
|
62
|
+
and `EvidenceValidUntil` is the **earliest** validity horizon among them. The
|
|
63
|
+
delivery-required items are `RulesEvidenceStatus` / `PinnedEvidenceStatus` /
|
|
64
|
+
`BotBannerEvidenceStatus` / `InstalledAppsStatus` / `AboutPageEvidenceStatus`.
|
|
65
|
+
Per-item timestamps may also be recorded, and must be when the items differ
|
|
66
|
+
enough that one worst-case pair would hide a stale item.
|
|
67
|
+
- **`Unknown` is not fresh.** If any delivery-required item has an unknown
|
|
68
|
+
gathering time or no declared horizon, the batch cannot be cleared on these
|
|
69
|
+
scalars: it is re-gathered and re-judged before delivery proceeds.
|
|
70
|
+
- **Expired evidence is re-gathered and re-judged; it is never carried forward.**
|
|
71
|
+
A stale rules snapshot is `NeedsAcquisition`, and the affected rows hold. Soft
|
|
72
|
+
style judgements may degrade gracefully when a source is missing; a compliance
|
|
73
|
+
judgement may not — "we could not check" is not "it is allowed".
|
|
74
|
+
- `reddit-delivery-check` re-checks freshness **at delivery** against this
|
|
75
|
+
handoff. A single check at compliance time does not satisfy the gate.
|
|
76
|
+
|
|
77
|
+
**A timestamp only re-opens a question; it never answers one.** Freshness applies
|
|
78
|
+
to *gathered evidence*. It does not apply to a permission that was never
|
|
79
|
+
adjudicated in the first place: where brand/vendor participation or a disclosure
|
|
80
|
+
requirement has no recorded human decision, it stays in `MissingEvidence` and the
|
|
81
|
+
rows hold, and no expiry or refresh converts that into a clearance.
|
|
82
|
+
|
|
83
|
+
**Two Gate 0 questions have no modelled answer and must not be presented as
|
|
84
|
+
decided:** whether the board permits brand or vendor participation at all, and
|
|
85
|
+
whether a disclosure is required. Neither is derivable from a style profile's
|
|
86
|
+
brand-friendliness note (that is a cultural description) nor from raw collected
|
|
87
|
+
evidence (that is unadjudicated material). Where a batch depends on either, the
|
|
88
|
+
answer belongs in `MissingEvidence`, the affected rows carry the corresponding
|
|
89
|
+
`PostRisk` / `CommentRisk`, and clearance is a human decision recorded by the
|
|
90
|
+
user. Do not add a field that makes an unadjudicated question look answered.
|
|
91
|
+
|
|
43
92
|
## Planning To Brief
|
|
44
93
|
|
|
45
94
|
Required:
|
|
46
95
|
|
|
47
96
|
- `memory/phase4-sku-基准表.md`
|
|
48
|
-
- `memory/phase4-board-quantity-plan.md`
|
|
97
|
+
- `memory/phase4-board-quantity-plan.md` with the declared `SRPMode` per board and the user-locked
|
|
98
|
+
`LockedPlanID` / `LockedBy` / `LockedAt` (D6)
|
|
99
|
+
- `memory/phase4-排期决策台账.md` — the per-post scheduling decision ledger from the D1–D7 procedure
|
|
100
|
+
(`reddit-phase-planning/references/scheduling-decision-procedure.md`), keyed by execution-table `Key`,
|
|
101
|
+
with all 9 fields present. It is the **only** landing place for `ProposedFlair` (the execution table
|
|
102
|
+
has no flair column); `reddit-phase-brief` reads it to verify and lock `AssignedFlair`
|
|
49
103
|
- `memory/phase4-执行表.md`
|
|
50
104
|
- `memory/phase4-external-post-audit.md` when external comment URLs exist, or an execution-table EPA status summary
|
|
51
105
|
- `memory/phase4-SKU品牌词映射.md`
|
|
@@ -70,7 +124,13 @@ Required:
|
|
|
70
124
|
- `memory/phase4-brand-risk-review.md` for any batch with brand-word rows, PGC rows, comparison/review language, external links, product claims, prior negative signals, or subreddit sensitivity; otherwise an explicit low-risk waiver from `reddit-brand-risk-response`
|
|
71
125
|
- `memory/phase4-叙事指纹索引.md` exists as a fixed table with the schema header (`WindowCount`, `WindowDays`, `WindowScope`, `WindowSort`, `BaselineMaxAgeDays`, `HashSchemaVersion`, `IndexRevision`), and has exactly one active `Planned` row for every briefed post Key
|
|
72
126
|
- a valid `SampleSetID` (flair-level subreddit baseline, 5–10 recent real posts, word-count median + IQR, with `AcquiredAt` / `ValidUntil`) for every target subreddit in the batch, recording flair coverage (`BaselineScope` / `BaselineFlair` / `FlairCoverageStatus`); missing or expired baseline, or `FlairCoverageStatus: Insufficient`, is a `BlockingGap`
|
|
73
|
-
- every post Brief row
|
|
127
|
+
- every main-post Brief row's `AssignedFlair` was **verified against the ledger's `ProposedFlair`**, not re-chosen: `FlairVerificationStatus` is `Verified` or `FallbackAssigned` (the latter only for `ProposedFlair: Unknown(NoSRP)`); `Rejected` is a `BlockingGap` back to `reddit-phase-planning` D2
|
|
128
|
+
- every post Brief row carries the nine `LockedFingerprintFields` (`ContentFunction`, `StructureFamily`, `OpeningMove`, `EvidenceShape`, `BrandEntryMode`, `CaveatMode`, `EndingMode`, `LengthBand`, `AnchorSlot`), the three `PrewritingControlFields` (`AssignedFlair` non-empty; `PostingTrigger` from the controlled five values satisfying the `PostingTrigger × BrandEntryMode` cross-constraint; `PersonaCardRef` non-empty with its `PersonaCardVersion` / `PersonaCardHash`), and the four `TraceFields` (`SampleSetID`, `RecentCollisionCheck`, `MappingRuleID`, `MappingVersion`)
|
|
129
|
+
- `PersonaCardRef` is required for **main-post rows only** (contract:
|
|
130
|
+
`references/persona-card-contract.md`). Self-comments, external comments, and
|
|
131
|
+
titles carry `N/A`. The Card is authored by `reddit-phase-brief`; a row whose
|
|
132
|
+
Card is missing is a `BlockingGap` back to Brief, never a Card the writer
|
|
133
|
+
supplies
|
|
74
134
|
- every post Brief row carries a `Routing Decision` block with the five candidate-narrowing steps, `MatchedPredicate`, `SelectedStructureFamily`, and `CollisionRepairPath`
|
|
75
135
|
- `RecentCollisionCheck` is `Pass` (or `Exception` with an approved `ExceptionRef`) for every row
|
|
76
136
|
- `brief_approval_mode`
|
|
@@ -120,6 +180,9 @@ MappingRuleID: # when a client prototype applies
|
|
|
120
180
|
StructureFamily:
|
|
121
181
|
AssignedFlair: # PrewritingControlField; non-empty; NoFlairAvailable/NoFlairRequired for flairless boards
|
|
122
182
|
PostingTrigger: # PrewritingControlField; controlled 5 values; not in the collision triple
|
|
183
|
+
PersonaCardRef: # PrewritingControlField; Brief-assigned, post-only
|
|
184
|
+
PersonaCardVersion: # integer; a change invalidates prior boundary checks
|
|
185
|
+
PersonaCardHash: # sha256 of the assigned Card; rewrite preserves, never edits
|
|
123
186
|
OpeningMove:
|
|
124
187
|
EvidenceShape:
|
|
125
188
|
BrandEntryMode:
|
|
@@ -137,6 +200,7 @@ DraftHash: # PENDING until the post-review recompute
|
|
|
137
200
|
|
|
138
201
|
**Not required for `Comment` / `Reply` / `Title`:** `PrimaryPostType`,
|
|
139
202
|
`StructureFamily`, `SampleSetID`, `AnchorSlot`, `RecentCollisionCheck`,
|
|
203
|
+
`PersonaCardRef` / `PersonaCardVersion` / `PersonaCardHash`,
|
|
140
204
|
`DraftHash` from a fingerprint row. These artifacts carry no fingerprint row
|
|
141
205
|
(`WindowScope: PostOnly`); they still need Hub review and `FinalDraftSha256`,
|
|
142
206
|
and the fabricated-human-signal rules still apply to them.
|
|
@@ -153,6 +217,14 @@ Rules:
|
|
|
153
217
|
- Rewrite may not reorder sections, add a failed attempt, add a question ending, add a caveat, add a community-observation line, move the brand mention, change `AnchorSlot`, or change any of the nine `LockedFingerprintFields`.
|
|
154
218
|
- Rewrite must **preserve `PostingTrigger`** for `ArtifactType: Post`: a body edit that changes the post's real-world trigger (or that breaks the `PostingTrigger × BrandEntryMode` cross-constraint) is out of allowance — flag it instead of applying, so the finished body still re-derives to the `Planned` `PostingTrigger`.
|
|
155
219
|
- Hub `optimized` output that changes a protected structure field may not be adopted wholesale; record `HubStructureConflictStatus: None | Escalated` (see `content-review-gate.md` §3.1). `Escalated` holds the draft and routes to `reddit-phase-brief`.
|
|
220
|
+
- Rewrite **preserves `PersonaCardRef` / `PersonaCardVersion` / `PersonaCardHash`
|
|
221
|
+
unchanged** and may not author, extend, or reinterpret a Card
|
|
222
|
+
(`references/persona-card-contract.md`). Repairing a claim so that it stops
|
|
223
|
+
contradicting the assigned Card is in allowance — it is the existing
|
|
224
|
+
`FactualExpression` duty, since an unauthorised firsthand claim is an
|
|
225
|
+
unsupported claim. Needing a *wider* boundary than the Card grants is not:
|
|
226
|
+
return `PersonaCardConflict: Yes` with the contradicting phrase and route to
|
|
227
|
+
`reddit-phase-brief` for a new Card version.
|
|
156
228
|
- `reddit-content-rewrite` does **not** own `memory/phase4-叙事指纹索引.md`. When its edits change the body, it returns `FingerprintSyncRequired: Yes` / `FingerprintSyncStatus: PendingWritingOwner`; `reddit-content-writing` (the index owner) performs the re-review and hash write-back.
|
|
157
229
|
|
|
158
230
|
## Brand Risk To Writing
|
|
@@ -183,13 +255,26 @@ Required:
|
|
|
183
255
|
- `memory/content-review-log.md`
|
|
184
256
|
- `memory/phase4-叙事指纹索引.md` has exactly one active `Final` row for every delivered **main-post** Key (`WindowScope: PostOnly`; comments and external comments need no fingerprint row, only Hub `FinalDraftSha256`)
|
|
185
257
|
- each `Final` row's `DraftHash` equals the `FinalDraftSha256` in `memory/content-review-log.md` and a recomputation from the delivered text using `HashSchemaVersion: reddit-final-draft-sha256-v1`
|
|
186
|
-
- all nine `LockedFingerprintFields` of a delivered post match the Brief's `Planned` values, and the
|
|
258
|
+
- all nine `LockedFingerprintFields` of a delivered post match the Brief's `Planned` values, and the three `PrewritingControlFields` match too: `AssignedFlair` equals the Brief value (and the baseline flair coverage it was written against), the delivered body's re-derived `PostingTrigger` equals the `Planned` value while satisfying the `PostingTrigger × BrandEntryMode` cross-constraint, and `PersonaCardRef` / `PersonaCardVersion` / `PersonaCardHash` equal the Brief's assigned Card with `PersonaCardSelfCheck: Pass` recorded against that same version
|
|
187
259
|
- no delivered post Key collides with any other Key in the rolling window unless an approved `ExceptionRef` exists
|
|
188
260
|
- every post/comment to be delivered has Hub `executionStatus=completed` and `verdict=pass`
|
|
189
261
|
- final delivery rows have `ReviewMode: AccountBound` and a real `accountId`
|
|
190
262
|
- ContentOnly rows may hand off to account selection with `AccountBindingStatus: Pending`, but cannot be marked `ReadyForDelivery: Yes`
|
|
191
263
|
- no delivered row has unresolved `brandFitReviewRequired` or blocking `accountCandidateFeedback`
|
|
192
264
|
- Hub review feedback was applied to the exact final draft
|
|
265
|
+
- every dimension the Hub result reports as `not_assessed` is carried through as
|
|
266
|
+
NotAssessed, with its `notAssessedReason` — never as a low score, a passing
|
|
267
|
+
score, or a partial check, and never averaged. Scores are compared only within
|
|
268
|
+
the same `applicabilitySignature`; the semantics are in
|
|
269
|
+
`references/content-review-gate.md` and are not restated per row
|
|
270
|
+
- compliance evidence is still fresh **as of delivery**, re-checked against the
|
|
271
|
+
Compliance Output handoff; evidence that expired since that report holds the
|
|
272
|
+
affected rows
|
|
273
|
+
- when `AcceptanceProfile: NativeCopy` was selected, `NativeCopyProfileStatus` is
|
|
274
|
+
recorded. While it is `Unavailable(ServerContractMissing)` no row may be marked
|
|
275
|
+
`ReadyForDelivery: Yes` under that profile, and the profile may not be silently
|
|
276
|
+
downgraded to `Default` to release the batch
|
|
277
|
+
(`references/native-copy-profile.md`)
|
|
193
278
|
- single Feishu draft document exists when Feishu delivery was selected
|
|
194
279
|
- `memory/phase5-交付清单.md` is written at delivery
|
|
195
280
|
|
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
# Native Copy Acceptance Profile
|
|
2
|
+
|
|
3
|
+
An **optional overlay** for clients who commission a stricter native-copy
|
|
4
|
+
standard than the matrix default.
|
|
5
|
+
|
|
6
|
+
```markdown
|
|
7
|
+
AcceptanceProfile: Default | NativeCopy
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
`Default` is the standing behaviour of every skill in this matrix and is what
|
|
11
|
+
runs when the field is absent. **Nothing in this file changes `Default`.** Every
|
|
12
|
+
rule here applies only while `AcceptanceProfile: NativeCopy` is selected for the
|
|
13
|
+
batch.
|
|
14
|
+
|
|
15
|
+
This separation is the whole point of the file. A brand-mention ceiling, a
|
|
16
|
+
required question ending, or a fixed output format folded into the default layer
|
|
17
|
+
would impose one client's house voice on every brand — which is precisely what
|
|
18
|
+
`reddit-content-rewrite` was redefined as a constraint-preserving repairer to
|
|
19
|
+
prevent. Keep client strictness in the overlay.
|
|
20
|
+
|
|
21
|
+
## 1. Current status: `Unavailable`
|
|
22
|
+
|
|
23
|
+
**`NativeCopyProfileStatus: Unavailable(ServerContractMissing)`.**
|
|
24
|
+
|
|
25
|
+
The profile requires the server to state, per review, which scope was requested,
|
|
26
|
+
which was resolved, and whether the declaration was honoured or inferred. Social
|
|
27
|
+
Hub does not expose that today — there is no scope field on the review request
|
|
28
|
+
and no scope receipt on the response.
|
|
29
|
+
|
|
30
|
+
While the status is `Unavailable`:
|
|
31
|
+
|
|
32
|
+
- Planning, Brief, Persona Cards, drafting, and the local self-checks below all
|
|
33
|
+
run normally.
|
|
34
|
+
- Hub review runs normally, under `Default` semantics, and its verdict is read
|
|
35
|
+
exactly as `references/content-review-gate.md` describes.
|
|
36
|
+
- **No row may be marked `ReadyForDelivery: Yes` under this profile.** Report
|
|
37
|
+
`NativeCopyProfileStatus: Unavailable(ServerContractMissing)` and name the
|
|
38
|
+
missing capability.
|
|
39
|
+
- **Never silently fall back to `Default` and call the result a profile pass.**
|
|
40
|
+
Fail closed: a client who commissioned the stricter standard must not be handed
|
|
41
|
+
a delivery that was measured against the looser one. Equally, never strip
|
|
42
|
+
fields to make a call succeed and then treat the result as satisfying the
|
|
43
|
+
profile — a request that had to be weakened to be accepted did not verify what
|
|
44
|
+
it was supposed to verify.
|
|
45
|
+
|
|
46
|
+
Selecting `NativeCopy` is therefore useful now for the writing-side discipline it
|
|
47
|
+
imposes, and cannot yet produce a delivery. That is intended, not a defect.
|
|
48
|
+
|
|
49
|
+
## 2. Review scope: local intent only
|
|
50
|
+
|
|
51
|
+
The four quadrants — account-bound vs persona-less, managed brand vs organic —
|
|
52
|
+
are real and the planner should be explicit about which one a batch is written
|
|
53
|
+
for. Record that as **intent**:
|
|
54
|
+
|
|
55
|
+
```markdown
|
|
56
|
+
LocalReviewIntent:
|
|
57
|
+
accountBinding: account_bound | persona_less
|
|
58
|
+
brandTreatment: managed_brand | organic
|
|
59
|
+
HubReviewScopeStatus: Unavailable(ServerContractMissing)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
`LocalReviewIntent` is a planner declaration in matrix memory. It is **not** sent
|
|
63
|
+
to Hub, and it is **not** a claim about how Hub actually resolved the review.
|
|
64
|
+
|
|
65
|
+
Two disciplines follow from writing it down:
|
|
66
|
+
|
|
67
|
+
- **"Managed brand" means a managed brand context, not a brand string in the
|
|
68
|
+
body.** A batch does not become `organic` by omitting the brand context from
|
|
69
|
+
the review call. If the content is written for a managed brand, the intent is
|
|
70
|
+
`managed_brand` regardless of what the request carries.
|
|
71
|
+
- **Omitting an account is a decision, not an accident.** `persona_less` must be
|
|
72
|
+
a recorded choice. "We forgot to resolve the publishing account" and "this is
|
|
73
|
+
deliberately content-only work" produce identical review calls, so the
|
|
74
|
+
distinction only exists if the planner states it.
|
|
75
|
+
|
|
76
|
+
Do not invent or report a server-side scope status. When Hub later echoes a real
|
|
77
|
+
scope and the source of that scope, record what it returns; until then
|
|
78
|
+
`HubReviewScopeStatus` is `Unavailable(ServerContractMissing)` and the matrix
|
|
79
|
+
makes no claim about which quadrant the server believed it was reviewing.
|
|
80
|
+
|
|
81
|
+
## 3. Tightenings that are in scope
|
|
82
|
+
|
|
83
|
+
**Each tightening is applied by exactly the stage named below, and the split is
|
|
84
|
+
not cosmetic.** Structural tightenings touch locked fingerprint fields, so only
|
|
85
|
+
`reddit-phase-brief` may apply them, at assignment. Register tightenings are about
|
|
86
|
+
how the prose reads, so the writer observes them while producing the first draft.
|
|
87
|
+
|
|
88
|
+
`reddit-content-rewrite` applies **neither kind**: it may not add a structural
|
|
89
|
+
constraint (that would change a locked field after the collision check) and it may
|
|
90
|
+
not newly impose or escalate a register rule (that would be house-voice
|
|
91
|
+
normalisation of a draft it was asked only to repair).
|
|
92
|
+
|
|
93
|
+
| Tightening | Owner stage | Rule |
|
|
94
|
+
| ------------------------------ | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
95
|
+
| Brand-mention ceiling | `reddit-phase-brief` (placement) | A per-post ceiling may be set for the batch. It constrains `BrandEntryMode` / placement **at assignment**, and never becomes a global default |
|
|
96
|
+
| Restricted `EndingMode` set | `reddit-phase-brief` | The profile may narrow the *allowed set* the Brief picks from. See §4 |
|
|
97
|
+
| PDP / spec-speak language | `reddit-content-writing` | Avoid product-page register and specification recitation where the account's `knowledgeAccess` does not support it |
|
|
98
|
+
| Fake-Reddit-English | `reddit-content-writing` | No slang, emoji, or broken grammar added to *seem* native. This is the existing fabricated-signal red line, stated in the other direction |
|
|
99
|
+
| Full official product names | `reddit-content-writing` | Only against an explicitly maintained, approved list of forbidden strings. Never inferred from an SKU or model name — see §6 |
|
|
100
|
+
|
|
101
|
+
**Scoring thresholds are out of scope.** A stricter numeric bar (a client's own
|
|
102
|
+
100-point scale, a 90/80 two-tier gate) is **not** part of this train. It is not a
|
|
103
|
+
tightening you may apply, and no local computation may produce a profile score, a
|
|
104
|
+
profile pass, or delivery eligibility. If a client scale is useful for internal
|
|
105
|
+
discussion, keep it as a non-delivery preview and label it as such. The
|
|
106
|
+
authoritative verdict is Hub's, under `Default` semantics, read per
|
|
107
|
+
`references/content-review-gate.md`.
|
|
108
|
+
|
|
109
|
+
## 4. Endings are assigned, not appended
|
|
110
|
+
|
|
111
|
+
A client requirement that posts end on a specific question is a constraint on
|
|
112
|
+
**which `EndingMode` the Brief may assign**, not a licence to append a question
|
|
113
|
+
to a finished draft.
|
|
114
|
+
|
|
115
|
+
`EndingMode` is one of the nine `LockedFingerprintFields` and one of the three
|
|
116
|
+
fields in the collision triple (`references/content-diversity-contract.md`). A
|
|
117
|
+
writer or rewriter adding a question ending changes a locked field, bypasses
|
|
118
|
+
structural pre-assignment, and voids the collision check that was run against the
|
|
119
|
+
old value.
|
|
120
|
+
|
|
121
|
+
So: the profile narrows the allowed set, `reddit-phase-brief` assigns from the
|
|
122
|
+
narrowed set and runs the collision check on the result, and the writer preserves
|
|
123
|
+
what was assigned. If the narrowed set leaves no collision-free option, that is a
|
|
124
|
+
`BlockingGap` back to planning — not a reason to append.
|
|
125
|
+
|
|
126
|
+
The same reasoning applies to every other tightening that touches a locked field:
|
|
127
|
+
express it as a constraint on assignment, never as a post-hoc edit.
|
|
128
|
+
|
|
129
|
+
## 5. Content-logic types stay separate
|
|
130
|
+
|
|
131
|
+
A client taxonomy of content logic types — question, buying decision, personal
|
|
132
|
+
story, ownership experience, show & tell, styling, quality check — may be recorded
|
|
133
|
+
as a profile-local label:
|
|
134
|
+
|
|
135
|
+
```markdown
|
|
136
|
+
NativeCopyLogicType: # profile-local label; optional
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
It **may not** be mapped onto, merged with, or substituted for `ContentFunction`.
|
|
140
|
+
They are different taxonomies with different value sets, and routing already keys
|
|
141
|
+
off `ContentFunction`; overloading it would corrupt live routing decisions for
|
|
142
|
+
every non-profile batch.
|
|
143
|
+
|
|
144
|
+
**The ownership / brand-review collision is real and must be handled at
|
|
145
|
+
assignment.** `PostingTrigger: UnsolicitedTestimony` requires
|
|
146
|
+
`BrandEntryMode: 不出现`, and conversely any `BrandEntryMode ≠ 不出现` forbids
|
|
147
|
+
`UnsolicitedTestimony` (`references/content-diversity-contract.md`). A client
|
|
148
|
+
category that is simultaneously "ownership testimony" and "names the brand" cannot
|
|
149
|
+
be satisfied by both at once. Resolve it in the Brief by choosing which of the two
|
|
150
|
+
the post actually is, and record the choice. Any mapping table that quietly places
|
|
151
|
+
a brand-naming ownership post on `UnsolicitedTestimony` is a hard contradiction,
|
|
152
|
+
not a preference to reconcile in the draft.
|
|
153
|
+
|
|
154
|
+
## 6. What the profile explicitly does not get
|
|
155
|
+
|
|
156
|
+
- **Forbidden product-name strings are maintained, never derived.** Approved
|
|
157
|
+
product facts (SKU, model name) cannot be recombined into an official
|
|
158
|
+
product-page title; attempting it produces both misses and false positives on
|
|
159
|
+
ordinary phrasing. Only an explicit, approved list of forbidden strings is
|
|
160
|
+
actionable, and a client who wants this enforcement has to supply and maintain
|
|
161
|
+
that list.
|
|
162
|
+
- **No cross-post template detection exists server-side.** The rolling
|
|
163
|
+
fingerprint index is a matrix memory file. It is strong within one project's
|
|
164
|
+
memory and it is **not** a service-side gate: it does not span authors,
|
|
165
|
+
campaigns, or runs, and it cannot see a sibling batch. A client pattern
|
|
166
|
+
checklist may be used as supplementary observation against the existing
|
|
167
|
+
fingerprint fields; it must not be presented as a guarantee that no two posts
|
|
168
|
+
anywhere share a template, and it must not become a second fingerprint system
|
|
169
|
+
alongside the contract's.
|
|
170
|
+
- **The brand-removal question is a diagnostic.** "Would this post still be worth
|
|
171
|
+
posting with the brand name deleted?" is a useful prompt for judging whether the
|
|
172
|
+
brand is the post's only payoff. It is not a mechanical rule: a vendor review, a
|
|
173
|
+
purchase-decision post, or a board that requires vendor identification is
|
|
174
|
+
legitimately incomplete without the brand. Ask whether the brand is the *sole*
|
|
175
|
+
payoff; never run a literal string deletion and fail the result.
|
|
176
|
+
- **Exemplar phrases are not a phrase library.** Sampled community wording may be
|
|
177
|
+
read as analysis or as negative examples. Copying another user's wording into a
|
|
178
|
+
draft is forbidden by both this profile and the matrix's own red lines.
|
|
179
|
+
- **No fixed output format.** A client's prescribed multi-section deliverable
|
|
180
|
+
format is not adopted. Its useful content maps onto existing handoff fields —
|
|
181
|
+
flagged risks into `BlockingGaps`, brand-mention reasoning into the Brief's
|
|
182
|
+
placement rationale. A second mandatory output shape layered over
|
|
183
|
+
`references/handoff-schemas.md` produces two contracts that disagree.
|
|
184
|
+
- **No relaxation of the fabricated-signal rules.** Nothing in the profile
|
|
185
|
+
licenses invented experience, invented flaws, invented community history, or
|
|
186
|
+
deliberate typos. Where the profile and the matrix red lines overlap, they are
|
|
187
|
+
the same rule stated once — do not restate it as a second rule with its own
|
|
188
|
+
wording.
|
|
189
|
+
|
|
190
|
+
## 7. Versioning
|
|
191
|
+
|
|
192
|
+
The matrix package version, this profile, and the server's review semantics are
|
|
193
|
+
**independent identifiers and are not kept in step**. Do not require them to
|
|
194
|
+
match, and do not assert that a Hub response carries a particular review-semantics
|
|
195
|
+
version.
|
|
196
|
+
|
|
197
|
+
This profile has been authored against post-review `v4` and content-review `v5`
|
|
198
|
+
semantics. That is a statement about what it was written for, not a runtime
|
|
199
|
+
assertion: **never branch on a version string in a response.**
|
|
200
|
+
|
|
201
|
+
The capability the profile is waiting on is a server-stated review scope —
|
|
202
|
+
`review-scope.v1` in the plan's naming. When the server begins declaring its
|
|
203
|
+
capabilities and echoing the scope it resolved, this section is what changes: the
|
|
204
|
+
matrix will read that declaration and that scope, and `NativeCopyProfileStatus`
|
|
205
|
+
will follow from whether the required capability is present. Until then the status
|
|
206
|
+
stays `Unavailable(ServerContractMissing)`, and no skill infers the capability
|
|
207
|
+
from a version string, a successful call, or the absence of an error.
|
|
@@ -53,6 +53,27 @@ same way:
|
|
|
53
53
|
~/.cursor/skills/reddit-strategy-shared/references/content-diversity-contract.md
|
|
54
54
|
```
|
|
55
55
|
|
|
56
|
+
The SRP contract is a shared reference too (it is consumed by four phases, so it does
|
|
57
|
+
not live in any one phase's `references/`):
|
|
58
|
+
|
|
59
|
+
```text
|
|
60
|
+
~/.cursor/skills/reddit-strategy-shared/references/subreddit-research-profile.md
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
The D1–D7 scheduling decision procedure is **planning-owned**, so it is read from that
|
|
64
|
+
skill's own `references/` (and by that skill only — downstream reads its *output*,
|
|
65
|
+
`memory/phase4-排期决策台账.md`):
|
|
66
|
+
|
|
67
|
+
```text
|
|
68
|
+
~/.cursor/skills/reddit-phase-planning/references/scheduling-decision-procedure.md
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
The archived legacy prerequisites are the one directory no agent may read:
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
~/.cursor/skills/reddit-strategy-shared/references/prerequisites/archive/ # AgentReadPolicy: DoNotRead
|
|
75
|
+
```
|
|
76
|
+
|
|
56
77
|
## Project Memory Paths
|
|
57
78
|
|
|
58
79
|
Contracts are installed skill files; the data they govern is project-side.
|
|
@@ -62,12 +83,13 @@ an installed-skill path and never as an absolute user path:
|
|
|
62
83
|
```text
|
|
63
84
|
memory/phase0-客户内容原型映射.md
|
|
64
85
|
memory/phase4-叙事指纹索引.md
|
|
86
|
+
memory/phase4-排期决策台账.md
|
|
65
87
|
```
|
|
66
88
|
|
|
67
|
-
The
|
|
68
|
-
prerequisites: `reddit-phase-planning` creates the prototype mapping in Phase 0
|
|
69
|
-
`reddit-phase-brief` seeds the fingerprint
|
|
70
|
-
`reddit-content-writing` owns it from drafting onward. A missing file is a
|
|
89
|
+
The three files above are **not** created by the installers. They are project
|
|
90
|
+
prerequisites: `reddit-phase-planning` creates the prototype mapping in Phase 0 and the
|
|
91
|
+
scheduling decision ledger in Phase 4.0.0.4, `reddit-phase-brief` seeds the fingerprint
|
|
92
|
+
index with `Planned` rows, and `reddit-content-writing` owns it from drafting onward. A missing file is a
|
|
71
93
|
`BlockingGap`, not an empty history.
|
|
72
94
|
|
|
73
95
|
## Rule
|