@geoly-ai/social-hub-cli 0.3.19 → 0.3.21

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 (50) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/dist/accounts-list-offset.test.d.ts +2 -0
  3. package/dist/accounts-list-offset.test.d.ts.map +1 -0
  4. package/dist/accounts-list-offset.test.js +53 -0
  5. package/dist/accounts-list-offset.test.js.map +1 -0
  6. package/dist/cmd-manifest.json +4 -2
  7. package/dist/compliance-risk-list-offset.test.d.ts +2 -0
  8. package/dist/compliance-risk-list-offset.test.d.ts.map +1 -0
  9. package/dist/compliance-risk-list-offset.test.js +63 -0
  10. package/dist/compliance-risk-list-offset.test.js.map +1 -0
  11. package/dist/content-review.test.js +1 -1
  12. package/dist/index.d.ts.map +1 -1
  13. package/dist/index.js +40 -4
  14. package/dist/index.js.map +1 -1
  15. package/dist/index.test.js +16 -0
  16. package/dist/index.test.js.map +1 -1
  17. package/dist/register-calendar-directives.d.ts +64 -0
  18. package/dist/register-calendar-directives.d.ts.map +1 -0
  19. package/dist/register-calendar-directives.js +135 -0
  20. package/dist/register-calendar-directives.js.map +1 -0
  21. package/dist/register-calendar-directives.test.d.ts +2 -0
  22. package/dist/register-calendar-directives.test.d.ts.map +1 -0
  23. package/dist/register-calendar-directives.test.js +127 -0
  24. package/dist/register-calendar-directives.test.js.map +1 -0
  25. package/dist/register-shared.d.ts.map +1 -1
  26. package/dist/register-shared.js +13 -2
  27. package/dist/register-shared.js.map +1 -1
  28. package/dist/register-shared.test.js +78 -0
  29. package/dist/register-shared.test.js.map +1 -1
  30. package/package.json +2 -2
  31. package/skills/README.md +23 -22
  32. package/skills/manifest.json +6 -1
  33. package/skills/reddit-content-rewrite/SKILL.md +29 -0
  34. package/skills/reddit-content-writing/SKILL.md +53 -4
  35. package/skills/reddit-delivery-check/SKILL.md +38 -6
  36. package/skills/reddit-matrix.lock.json +6 -6
  37. package/skills/reddit-phase-brief/SKILL.md +39 -4
  38. package/skills/reddit-phase-brief/references/phase4-brief-workflow.md +43 -3
  39. package/skills/reddit-strategy-shared/references/content-diversity-contract.md +7 -2
  40. package/skills/reddit-strategy-shared/references/content-review-gate.md +48 -1
  41. package/skills/reddit-strategy-shared/references/handoff-schemas.md +72 -2
  42. package/skills/reddit-strategy-shared/references/native-copy-profile.md +207 -0
  43. package/skills/reddit-strategy-shared/references/persona-card-contract.md +210 -0
  44. package/skills/reddit-strategy-shared/references/version-manifest.md +60 -0
  45. package/skills/reddit-subreddit-compliance/SKILL.md +28 -1
  46. package/skills/social-hub-calendar-directives/SKILL.md +548 -0
  47. package/skills/social-hub-calendar-jobs/SKILL.md +10 -0
  48. package/skills/social-hub-cli/SKILL.md +2 -0
  49. package/skills/social-hub-notifications/SKILL.md +7 -0
  50. package/skills/social-hub-publishing/SKILL.md +5 -0
@@ -0,0 +1,210 @@
1
+ # Persona Card Contract
2
+
3
+ The **Persona Card** is the per-draft posting context: why this account is
4
+ posting this now, what it may legitimately be assumed to know, what it must not
5
+ claim to know, and which firsthand experience claims are authorised.
6
+
7
+ It is a **Brief-stage artifact**. The writer never authors one.
8
+
9
+ **Scope: `ArtifactType: Post` only.** Comments, replies, and titles carry no
10
+ Persona Card and no `PersonaCardRef`. The full knowledge-boundary and disclosure
11
+ judgement for comments is a later stage of work; do not let this contract turn
12
+ into a required field on comment rows.
13
+
14
+ ## 1. Why it is not part of the persona record
15
+
16
+ `personas` / `account_personas` describe **WHO** the account is — archetype, age
17
+ range, occupation, tone, avoid-topics, style guide. Those are stable.
18
+
19
+ `postingWhy`, this draft's `knows` / `doesNotKnow`, this draft's brand
20
+ relationship, and the facts this draft is allowed to use are **per-submission**.
21
+ Their lifecycle is the draft's, not the persona's. Recording them on the persona
22
+ would make every later draft inherit one draft's context.
23
+
24
+ `avoidTopics` / `avoidPatterns` say what the account **should not say**. The Card
25
+ says what the account **does not know**. These are different constraints and one
26
+ does not substitute for the other.
27
+
28
+ ## 2. Capability model, not role taxonomy
29
+
30
+ The Card describes **access and permitted claims**, never a role name.
31
+
32
+ ```markdown
33
+ PersonaCardRef: # stable local id, unique per post ContentKey
34
+ PersonaCardVersion: # integer, incremented by reddit-phase-brief only
35
+ PersonaCardHash: # sha256 over the normalised Card body
36
+
37
+ # ── stable capability fields ──
38
+ knowledgeAccess: # exactly one: research | owned | used | observed | supplied_by_brand
39
+ permittedExperienceClaims: # subset of the closed set {ownership, delivery, wear, service}; may be empty
40
+ attentionFocus: # what this account actually cares about in this category
41
+ questionIntent: # what it is actually trying to find out, if anything
42
+
43
+ # ── per-draft fields ──
44
+ postingWhy: # why this account is posting this, now
45
+ knows: # list; what it may be assumed to know here
46
+ doesNotKnow: # list; what it must not display knowledge of here
47
+ permittedFactRefs: # references to approved product facts usable in this draft
48
+ brandRelationshipDisclosed: # Yes | No | NotApplicable — what the draft states, not what is true
49
+
50
+ # ── provenance ──
51
+ DeclaredBy: # who authorised this Card's claims (person or role), not the agent
52
+ ClaimAuthorizationRef: # the submitted material that authorises permittedExperienceClaims
53
+
54
+ # ── transport ──
55
+ PersonaCardTransportStatus: LocalOnly(ServerContractMissing)
56
+ PersonaCardAuthorizationStatus: Authorized | DeclaredOnly | NotApplicable
57
+ RoleLabels: # optional, non-authoritative; see §3
58
+ ```
59
+
60
+ `knowledgeAccess` is single-valued because it answers "where did this account's
61
+ information come from". `permittedExperienceClaims` is a multi-select closed set
62
+ because one account can legitimately be authorised for some firsthand claims and
63
+ not others — "may say the item arrived" and "may describe wearing it" are
64
+ separate authorisations.
65
+
66
+ An empty `permittedExperienceClaims` is a valid, common Card. It means the draft
67
+ may discuss the category from research or observation and may **not** claim
68
+ ownership, delivery, wear, or service experience.
69
+
70
+ ## 3. Role names are labels, never judgement
71
+
72
+ `Researcher` / `Owner` / `GiftBuyer` / `CategoryEnthusiast` / `LifestyleUser` may
73
+ appear in `RoleLabels` as a convenience for humans reading the Brief. They are
74
+ **not** a classification, **not** exhaustive, and **never** the basis of any
75
+ check.
76
+
77
+ One account is legitimately both an Owner and a CategoryEnthusiast. No role name
78
+ can express "may this draft say the parcel arrived" — only
79
+ `permittedExperienceClaims` can. Any check that reads `RoleLabels` instead of the
80
+ capability fields is wrong.
81
+
82
+ Likewise, do not derive a rule such as "a gift buyer must not discuss
83
+ specifications". Buying a gift for a technical hobbyist makes specifications the
84
+ core of the post.
85
+
86
+ ## 4. Lifecycle: assigned, never improvised
87
+
88
+ The Card is the **third** `PrewritingControlField`, alongside `AssignedFlair` and
89
+ `PostingTrigger`. Same discipline as those two:
90
+
91
+ | Stage | Duty |
92
+ | ------------------------ | ------------------------------------------------------------------------------- |
93
+ | `reddit-phase-brief` | **Owns** the Card. Creates it, versions it, writes `PersonaCardRef` per post Key |
94
+ | `reddit-content-writing` | Reads it. Writes within it. May not author, extend, or reinterpret it |
95
+ | `reddit-content-rewrite` | Reads it. Preserves `PersonaCardRef`. May not author or edit one |
96
+ | `reddit-delivery-check` | Verifies the delivered row's `PersonaCardRef` / `PersonaCardHash` match the Brief |
97
+
98
+ A draft that needs a knowledge boundary the Card does not grant is a
99
+ `BlockingGap` back to `reddit-phase-brief` for a new Card version — not a local
100
+ edit and not a Card the writer fills in. Letting the writer author the Card
101
+ re-opens exactly the bypass that pre-assignment exists to close: the writer would
102
+ grant itself whatever boundary the draft it already wrote happens to need.
103
+
104
+ Changing the Card bumps `PersonaCardVersion` and invalidates `PersonaCardHash`
105
+ downstream: any row already checked against the old hash must be re-checked.
106
+
107
+ ## 5. What the Card does **not** establish
108
+
109
+ - **It does not verify identity.** In ContentOnly / persona-less work the Card is
110
+ a *declared, auditable posting context* and nothing more. Never report it as a
111
+ confirmed account persona check, and never let its presence imply the posting
112
+ account was resolved.
113
+ - **It does not prove any experience is real.** No local check and no model can
114
+ establish that a parcel actually arrived. The Card records what is
115
+ **authorised**, and authorisation comes from the submitted context, not from
116
+ inference about the relationship.
117
+ - **A Card without provenance records a declaration, not an authorisation.**
118
+ `PersonaCardHash` makes a Card tamper-evident; it says nothing about who granted
119
+ the claims in it. `DeclaredBy` + `ClaimAuthorizationRef` are what make
120
+ `permittedExperienceClaims` auditable. A Card carrying `permittedExperienceClaims`
121
+ with neither field is describing what the Brief asserted, and must be reported
122
+ that way — never as an authorised claim set. The generating agent is never a
123
+ valid `DeclaredBy`.
124
+
125
+ This distinction must survive the handoff, or it is unauditable: a downstream
126
+ reader seeing only "self-check passed" and "reference preserved" cannot tell an
127
+ authorised claim set from an asserted one. So the Brief sets
128
+ `PersonaCardAuthorizationStatus` and every stage carries it through:
129
+
130
+ | Value | Meaning |
131
+ | --------------- | ------------------------------------------------------------------------------------ |
132
+ | `Authorized` | `permittedExperienceClaims` non-empty, with both `DeclaredBy` and `ClaimAuthorizationRef` |
133
+ | `DeclaredOnly` | `permittedExperienceClaims` non-empty, provenance incomplete — a Brief assertion |
134
+ | `NotApplicable` | `permittedExperienceClaims` empty — there is no experience claim to authorise |
135
+
136
+ `DeclaredOnly` does not by itself block: the local boundary check still runs and
137
+ the Hub gate is unchanged. It does mean no output may describe the claim set as
138
+ authorised, and it is the honest state to report to a client asking on what
139
+ basis a firsthand claim was permitted. Like the rest of the Card, this status is
140
+ local and is never sent to Hub.
141
+ - **A brand relationship does not by itself make a firsthand claim false.** A
142
+ partner may genuinely own the product. The only self-evident contradiction is a
143
+ draft asserting an experience type the Card did not authorise.
144
+
145
+ ## 6. Firsthand markers are evidence, not violations
146
+
147
+ Phrases such as "mine arrived", "I've had it since", "after a month of wearing
148
+ it" are **markers**, not offences. `mine arrived` is unremarkable when
149
+ `permittedExperienceClaims` includes `delivery`.
150
+
151
+ A marker matters only when it contradicts the Card: the draft claims an
152
+ experience type the Card did not authorise, or displays knowledge listed in
153
+ `doesNotKnow`. Report the contradiction, cite both the phrase and the Card field
154
+ it contradicts, and route back to Brief. Never flag a marker on its own.
155
+
156
+ ## 7. Transport boundary — the Card stays local
157
+
158
+ **`PersonaCardTransportStatus` is `LocalOnly(ServerContractMissing)`.**
159
+
160
+ Social Hub has no field for the Card on the post-review or content-review
161
+ request, and both request schemas are strict: an extra field is a request
162
+ rejection, not an ignored key. Do not add the Card, any of its fields, or a
163
+ Card-derived score to a Hub review call. Do not restructure the Card into an
164
+ existing free-text field (`subredditRules`, thread context) to smuggle it
165
+ through — that injects planner text into a prompt slot reserved for other
166
+ evidence.
167
+
168
+ So the Card governs **writing**: Brief assigns the boundary, the writer stays
169
+ inside it, delivery verifies the reference was preserved. Hub review runs
170
+ unchanged alongside it, and the Card changes nothing about how a Hub verdict is
171
+ read or reported.
172
+
173
+ The local boundary check therefore reports only what it is: a local check.
174
+ `ClaimEvidenceStatus` (`references/evidence-policy.md`) remains the authority on
175
+ whether a claim may appear in publishable text; the Card adds *who may claim it*
176
+ on top of *whether it is sourced*. Do not describe a local Card check as a review,
177
+ a verdict, a dimension, or a pass.
178
+
179
+ ## 8. Local boundary self-check (writing side)
180
+
181
+ Before handing a draft to Hub review, for each post row:
182
+
183
+ 1. Every firsthand experience claim in the draft maps to an entry in
184
+ `permittedExperienceClaims`.
185
+ 2. Nothing in the draft displays knowledge listed in `doesNotKnow`.
186
+ 3. Every substantive product claim still satisfies `ClaimEvidenceStatus`
187
+ (`Cited` or `ExternallyVerified`) — the Card never relaxes this.
188
+ 4. The draft's stated relationship matches `brandRelationshipDisclosed`.
189
+ 5. `postingWhy` is consistent with the assigned `PostingTrigger`. These are
190
+ different fields and neither replaces the other: `PostingTrigger` is the
191
+ controlled five-value reason the post is worth making now
192
+ (`references/content-diversity-contract.md`), `postingWhy` is this account's
193
+ own reason for making it. A draft whose `postingWhy` cannot coexist with the
194
+ assigned `PostingTrigger` is a `BlockingGap` back to Brief.
195
+
196
+ Record the outcome as `PersonaCardSelfCheck: Pass | BlockingGap`, with the
197
+ contradicting phrase and Card field for every gap. This is a local pre-submission
198
+ check. It never substitutes for Hub review and never produces a score.
199
+
200
+ ## 9. Deferred Hub mapping
201
+
202
+ The plan `docs/reddit-native-copy-integration-plan.md` (§2, §3.4, §6.4) intends a
203
+ server-side knowledge-boundary judgement that would consume a persisted,
204
+ snapshotted version of this Card. That contract does not exist yet: there is no
205
+ request field, no persisted snapshot, and no corresponding review dimension.
206
+
207
+ This note is informational. Until such a contract ships and its capability is
208
+ echoed by the server, no skill may name a knowledge-boundary review dimension,
209
+ report a knowledge-boundary review status, or claim any part of the Card was
210
+ assessed by Hub.
@@ -69,6 +69,66 @@ Copied independent skills should stay independently installable. Matrix wrappers
69
69
  warning-level sanity checks under `SRPMode: Full` / `Provisional`; the first two are
70
70
  per-board, the coverage count is plan-level (hard only when every board is `Fallback`).
71
71
 
72
+ ## Native-Copy Writing-Side Contracts (pending release roll-up)
73
+
74
+ > The `Package:` line above is **not** bumped here. These contracts land with the
75
+ > release that also relocks `skills/reddit-matrix.lock.json`; assigning them a
76
+ > package version before that roll-up would claim a distribution that does not
77
+ > exist yet.
78
+
79
+ Two new shared references, with **different opt-in status — do not read them as
80
+ one change**:
81
+
82
+ - The **Persona Card is a default protocol change** for every main post. Any
83
+ batch that briefs a post now assigns one, and delivery checks it. It is
84
+ post-only; comments are unaffected.
85
+ - The **NativeCopy profile is an opt-in overlay.** Nothing about it applies unless
86
+ a batch selects `AcceptanceProfile: NativeCopy`.
87
+
88
+ - `reddit-strategy-shared/references/persona-card-contract.md` — the **Persona
89
+ Card**: the per-draft posting context (why this account posts this now, what it
90
+ may be assumed to know, what it must not display knowledge of, which firsthand
91
+ experience claims are authorised). It is a **Brief-stage artifact** and the
92
+ **third `PrewritingControlField`** alongside `AssignedFlair` / `PostingTrigger`;
93
+ `reddit-phase-brief` owns it and the writer never authors one. Post-only —
94
+ comments carry `N/A`. Capability fields (`knowledgeAccess`,
95
+ `permittedExperienceClaims`, `attentionFocus`, `questionIntent`) rather than a
96
+ role taxonomy; the five familiar role names are optional labels that no gate
97
+ reads. **`PersonaCardTransportStatus: LocalOnly(ServerContractMissing)`** — Hub
98
+ has no field for it, both review request schemas are strict, so the Card
99
+ governs writing only and is never sent, never smuggled into a free-text slot,
100
+ and never reported as something Hub assessed.
101
+ - `reddit-strategy-shared/references/native-copy-profile.md` — the optional
102
+ `AcceptanceProfile: Default | NativeCopy` overlay. Client strictness applies
103
+ **only** under the profile, and each tightening is owned by one stage: the
104
+ **structural** ones (brand-mention ceiling, restricted `EndingMode` set) are
105
+ applied by `reddit-phase-brief` **at assignment** and never as a post-hoc edit
106
+ to a finished draft, because `EndingMode` / `BrandEntryMode` are locked
107
+ fingerprint fields; the **register** ones (PDP language, fake-Reddit-English,
108
+ forbidden official product-name strings) are the writer's while drafting.
109
+ Scoring thresholds are explicitly **not** in scope.
110
+ Current status is **`Unavailable(ServerContractMissing)`**: the profile needs a
111
+ server-stated review scope that does not exist yet, so it may not produce a
112
+ `ReadyForDelivery: Yes`, and it fails closed — never silently downgraded to
113
+ `Default`, never satisfied by a request weakened until it was accepted.
114
+
115
+ Also in this version:
116
+
117
+ - `handoff-schemas.md` — `PrewritingControlFields` goes from two to three;
118
+ compliance evidence now carries `EvidenceGatheredAt` / `EvidenceValidUntil` and
119
+ is **re-checked at delivery**, not cleared once; the two unadjudicated Gate 0
120
+ questions (brand/vendor participation, disclosure requirement) stay in
121
+ `MissingEvidence` behind a human decision rather than getting a field that makes
122
+ them look decided.
123
+ - `reddit-delivery-check` — structure checks go from nine to ten (check 10:
124
+ Persona Card preserved, self-check recorded against the delivered Card
125
+ version), plus delivery-time evidence freshness, correct `not_assessed`
126
+ reporting, and the profile eligibility gate.
127
+
128
+ Version identifiers stay independent: this package version, the profile, and the
129
+ server's review semantics are **not** kept in step, and no skill asserts a
130
+ review-semantics version it expects to see in a response.
131
+
72
132
  ## v2.12.30 Sample-Eligibility Contract
73
133
 
74
134
  A baseline card may only be built from **real user posts with an intact body**.
@@ -174,6 +174,12 @@ description: |
174
174
  - **敏感内容**:医疗、财务、法律、政治、仇恨、NSFW、安全风险等
175
175
  - **bot/banner/sidebar/Installed Apps 信号**:AutoModerator 提示、Installed Apps(如 Bot Bouncer)、版主警告、banner 标语、sidebar 禁令、置顶帖更新
176
176
  - **历史删除风险**:如果 `reddit-voc-volume` 或用户材料显示类似内容常被质疑/删除,需要标注
177
+ - **品牌 / vendor 是否被允许参与、是否需要 disclosure —— 这两项目前没有已裁定的答案,
178
+ 不得当成已判定输出。** 版规里的自推广条款是**规则文本**,板块画像里的「品牌友好度」是
179
+ **文化描述**,采集回来的 evidence 是**未裁定的原始材料**——三者都不是「该板块允许品牌/
180
+ vendor 发布」或「该板块要求披露」的裁定。缺裁定时的正确做法:写进 `MissingEvidence`,
181
+ 给对应行标上 `PostRisk` / `CommentRisk`,由用户记录人工决定。**不要新造一个字段把未裁定的
182
+ 问题写成已裁定的样子**;也不要因为「版规没写禁止」就当作允许——规则未提及不等于许可。
177
183
 
178
184
  ### Step 3.5: 账号条件与风控闸门
179
185
 
@@ -260,14 +266,30 @@ description: |
260
266
  - PinnedEvidenceStatus: Provided / NeedsAcquisition / NotVisible / Unavailable
261
267
  - BotBannerEvidenceStatus: Provided / NeedsAcquisition / Unavailable
262
268
  - InstalledAppsStatus: Provided / NeedsAcquisition / NotVisible / Unavailable
269
+ - AboutPageEvidenceStatus: Provided / NeedsAcquisition / NotVisible / Unavailable
263
270
  - PublicFlairFilterStatus: Provided / NeedsAcquisition / NotVisible / Unavailable
264
271
  - DataAcquisition: NotPerformedByThisSkill / ProvidedByUser / ProvidedByRedditVocVolume / ProvidedBySocialHub
272
+ - EvidenceGatheredAt: <ISO 时间戳 / Unknown> # 交付必需 5 项里**最早**的采集时点
273
+ - EvidenceValidUntil: <ISO 时间戳 / Unknown> # 其中**最早**的有效期(如 Hub freshUntil);无声明写 Unknown
265
274
  - RiskTriggerSummary: promotional / self-promotion / external links / weekly thread / flair / link-only / account age / comment karma / affiliate / discount code / Unknown
266
275
  - WritingOutput: NotProvided
267
276
  ```
268
277
 
269
278
  `RiskTriggerSummary` 要复用用户材料里的关键英文原词,例如 `promotional`、`self-promotion`、`external links`、`weekly thread`、`no link-only posts`、`low comment karma`。若出现 `DM me for discounts`、折扣码、官网链接、product website link、affiliate、UTM 或短链,也要列入并标为导流、促销或外链风险。
270
279
 
280
+ `EvidenceGatheredAt` / `EvidenceValidUntil` 存在是因为**本报告是时点快照,不是长期通行证**。
281
+ 排期与发布都发生在报告写完之后,版规会改、置顶会换。两个字段是**批次级最坏值**:
282
+ `EvidenceGatheredAt` 取交付必需证据里**最早**的采集时点,`EvidenceValidUntil` 取其中**最早**
283
+ 的有效期;各项差异大到一对最坏值会掩盖某项已过期时,须补记逐项时间。下游
284
+ `reddit-delivery-check` 会在**交付时**按这两个字段重新核验新鲜度,过期即 hold 对应行重新采集重判。
285
+ ⚠️ **`Unknown` 不算 fresh**:任一交付必需项的采集时点未知或来源未声明有效期,就不能靠这两个
286
+ 标量放行。
287
+ ⚠️ 时间戳只能**重新打开**一个问题,永远不能**回答**它:新鲜度只适用于「已采集的证据」,
288
+ 不适用于「从未裁定过的许可」。品牌/vendor 参与许可与 disclosure 要求若没有人工裁定,
289
+ 再新的时间戳也不构成放行。
290
+ ⚠️ 过期证据只能重采重判,**不得顺延**:过期的版规快照写 `NeedsAcquisition`。风格类软判断缺来源
291
+ 可以降级放行,**合规裁定不行**——「没查到」不等于「允许」。
292
+
271
293
  `RedditVocVolumeEvidenceRole` 用来防止把采样结果误当版规。帖子样本只能写 `PreferenceSignalOnly`;但 `subreddit_rules`、`wiki_page`、`subreddit_about.submit_text_excerpt/settings`、`pinned_post`、`subreddit_about_page.installed_apps[]` 可按对应公开来源进入 `EvidenceSources`。没有使用 VOC 时写 `NotProvided`。
272
294
 
273
295
  `WritingOutput` 对本 skill 永远是 `NotProvided`;如果用户混合要求写标题/正文,`TaskRoute` 用 `NeedsWritingSkillAfterCompliance`,但本 skill 仍然不输出写作内容。
@@ -287,8 +309,11 @@ description: |
287
309
  - `PinnedEvidenceStatus`
288
310
  - `BotBannerEvidenceStatus`
289
311
  - `InstalledAppsStatus`
312
+ - `AboutPageEvidenceStatus`
290
313
  - `PublicFlairFilterStatus`
291
314
  - `DataAcquisition`
315
+ - `EvidenceGatheredAt`
316
+ - `EvidenceValidUntil`
292
317
  - `RiskTriggerSummary`
293
318
  - `WritingOutput`: NotProvided
294
319
  - `MissingEvidence`
@@ -336,7 +361,7 @@ description: |
336
361
 
337
362
  ## 输出前自检
338
363
 
339
- 提交前检查:不生成/改写帖子、评论、标题;不自行写脚本或调用 `.json`、curl、浏览器抓 Reddit;数据需求交给 `reddit-voc-volume` 或用户材料;标明证据来源、缺口、规则/bot/sidebar/置顶帖信号、账号条件;输出 `RulesEvidenceStatus`、`PinnedEvidenceStatus`、`BotBannerEvidenceStatus`、`InstalledAppsStatus`、`PublicFlairFilterStatus`、`DataAcquisition`、`Fit`、`OverallRisk`、`EvidenceCompleteness`、`AccountGate`;不承诺“不会被删帖/不会封号”。
364
+ 提交前检查:不生成/改写帖子、评论、标题;不自行写脚本或调用 `.json`、curl、浏览器抓 Reddit;数据需求交给 `reddit-voc-volume` 或用户材料;标明证据来源、缺口、规则/bot/sidebar/置顶帖信号、账号条件;输出 `RulesEvidenceStatus`、`PinnedEvidenceStatus`、`BotBannerEvidenceStatus`、`InstalledAppsStatus`、`AboutPageEvidenceStatus`、`PublicFlairFilterStatus`、`DataAcquisition`、`EvidenceGatheredAt`、`EvidenceValidUntil`、`Fit`、`OverallRisk`、`EvidenceCompleteness`、`AccountGate`;未裁定的品牌/vendor 许可与 disclosure 要求留在 `MissingEvidence`,不写成已判定;不承诺“不会被删帖/不会封号”。
340
365
 
341
366
  ## HandoffContract
342
367
 
@@ -356,6 +381,8 @@ description: |
356
381
  - AboutPageEvidenceStatus:
357
382
  - PublicFlairFilterStatus:
358
383
  - AccountGate:
384
+ - EvidenceGatheredAt:
385
+ - EvidenceValidUntil:
359
386
  - MissingEvidence:
360
387
  - ReadyForNextSkill: Yes / No
361
388
  ```