@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.
- package/CHANGELOG.md +23 -0
- package/dist/accounts-list-offset.test.d.ts +2 -0
- package/dist/accounts-list-offset.test.d.ts.map +1 -0
- package/dist/accounts-list-offset.test.js +53 -0
- package/dist/accounts-list-offset.test.js.map +1 -0
- package/dist/cmd-manifest.json +4 -2
- package/dist/compliance-risk-list-offset.test.d.ts +2 -0
- package/dist/compliance-risk-list-offset.test.d.ts.map +1 -0
- package/dist/compliance-risk-list-offset.test.js +63 -0
- package/dist/compliance-risk-list-offset.test.js.map +1 -0
- package/dist/content-review.test.js +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +40 -4
- package/dist/index.js.map +1 -1
- package/dist/index.test.js +16 -0
- package/dist/index.test.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/register-shared.d.ts.map +1 -1
- package/dist/register-shared.js +13 -2
- package/dist/register-shared.js.map +1 -1
- package/dist/register-shared.test.js +78 -0
- package/dist/register-shared.test.js.map +1 -1
- 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 +53 -4
- package/skills/reddit-delivery-check/SKILL.md +38 -6
- package/skills/reddit-matrix.lock.json +6 -6
- package/skills/reddit-phase-brief/SKILL.md +39 -4
- package/skills/reddit-phase-brief/references/phase4-brief-workflow.md +43 -3
- package/skills/reddit-strategy-shared/references/content-diversity-contract.md +7 -2
- package/skills/reddit-strategy-shared/references/content-review-gate.md +48 -1
- package/skills/reddit-strategy-shared/references/handoff-schemas.md +72 -2
- package/skills/reddit-strategy-shared/references/native-copy-profile.md +207 -0
- package/skills/reddit-strategy-shared/references/persona-card-contract.md +210 -0
- package/skills/reddit-strategy-shared/references/version-manifest.md +60 -0
- package/skills/reddit-subreddit-compliance/SKILL.md +28 -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
|
@@ -535,8 +535,11 @@ ASK / GUIDE / ROUNDUP / OWNER / OPINION / RANT / FOLLOWUP / LIST / REPUTATION
|
|
|
535
535
|
`EndingMode` / `LengthBand`(由该 subreddit baseline 的中位数 + IQR 派生)/
|
|
536
536
|
`AnchorSlot`(`ABURequired=Yes` 时须在该 family 的 `AllowedAnchorSlots` 内;
|
|
537
537
|
否则填 `N/A`)。
|
|
538
|
-
|
|
539
|
-
|
|
538
|
+
**并预分配三个前置控制字段**(`PrewritingControlFields`;`AssignedFlair` /
|
|
539
|
+
`PostingTrigger` 的权威定义见
|
|
540
|
+
`../../reddit-strategy-shared/references/content-diversity-contract.md`,
|
|
541
|
+
`PersonaCardRef` 见
|
|
542
|
+
`../../reddit-strategy-shared/references/persona-card-contract.md`):
|
|
540
543
|
- `AssignedFlair`:已在 B-1.0/W0 由台账 `ProposedFlair` 验证锁定(`FlairVerificationStatus`
|
|
541
544
|
须为 `Verified` 或 `FallbackAssigned`);板块无
|
|
542
545
|
flair 或允许不选时填哨兵值 `NoFlairAvailable` / `NoFlairRequired`,不得留空、
|
|
@@ -550,6 +553,23 @@ ASK / GUIDE / ROUNDUP / OWNER / OPINION / RANT / FOLLOWUP / LIST / REPUTATION
|
|
|
550
553
|
⚠️ **该交叉约束只能在 5-brand 产出 `BrandEntryMode` 之后校验**:本步先记下
|
|
551
554
|
`PostingTrigger` 候选,5-brand 完成后再判定;不得为了让交叉约束通过而反向决定
|
|
552
555
|
`BrandEntryMode`。
|
|
556
|
+
- `PersonaCardRef`:本 Key 的 Persona Card 引用(+ `PersonaCardVersion` /
|
|
557
|
+
`PersonaCardHash`)。**Card 由本 skill 产出,撰写 skill 不得临场写**——否则等于让
|
|
558
|
+
稿子自己批准自己需要的知识边界。字段与生命周期见
|
|
559
|
+
`../../reddit-strategy-shared/references/persona-card-contract.md`:
|
|
560
|
+
`knowledgeAccess`(单值)/ `permittedExperienceClaims`(`{ownership, delivery,
|
|
561
|
+
wear, service}` 的子集,**可以为空集**)/ `attentionFocus` / `questionIntent`,
|
|
562
|
+
以及逐稿的 `postingWhy` / `knows[]` / `doesNotKnow[]` / `permittedFactRefs` /
|
|
563
|
+
`brandRelationshipDisclosed`。
|
|
564
|
+
⚠️ `postingWhy` 与 `PostingTrigger` **是两个字段,互不替代**:后者是「这篇帖为什么
|
|
565
|
+
现在值得发」的受控五值,前者是「这个账号自己为什么发」。二者必须能共存,否则
|
|
566
|
+
`BlockingGap`。
|
|
567
|
+
⚠️ `permittedExperienceClaims` 只能来自**已提交的上下文**,不得从品牌关系推断
|
|
568
|
+
(合作方也可能真实拥有该产品);五个角色名(Researcher / Owner / GiftBuyer /
|
|
569
|
+
CategoryEnthusiast / LifestyleUser)只是**可选标签,任何门禁都不读它**。
|
|
570
|
+
评论 / 自评 / 外部评论填 `N/A`——本期不把评论纳入 Card。
|
|
571
|
+
⚠️ Card 是**已声明的发帖上下文,不是已验证身份**:`LocalOnly`,不进任何 Hub 请求,
|
|
572
|
+
也不代表发布账号已解析。
|
|
553
573
|
**5-brand · `BrandPlacementGate`(G2,硬门):** `BrandEntryMode` 与「标题是否出现
|
|
554
574
|
品牌名」**只能由证据决定,不得由 P-B 标签推导**。
|
|
555
575
|
> **出处(真实返工):** 需求方质问「**为什么你把 P-B 的标题都统一加上了 aporro
|
|
@@ -714,6 +734,25 @@ ASK / GUIDE / ROUNDUP / OWNER / OPINION / RANT / FOLLOWUP / LIST / REPUTATION
|
|
|
714
734
|
**PrewritingControlFields(前置控制字段,主帖必填,先于 baseline 与结构):**
|
|
715
735
|
- AssignedFlair: (现行 flair 之一;无 flair 板块填 NoFlairAvailable / NoFlairRequired,不留空)
|
|
716
736
|
- PostingTrigger: (ConcreteFailure / PurchaseDecision / MeasurementResult / CompatibilityGap / UnsolicitedTestimony;须满足 × BrandEntryMode 交叉约束)
|
|
737
|
+
- PersonaCardRef: (本 Key 的 Persona Card 引用;评论填 N/A)
|
|
738
|
+
- PersonaCardVersion: (整数;改 Card 必须递增,并作废下游已做的边界自检)
|
|
739
|
+
- PersonaCardHash: (该 Card 正文的 sha256;改写 skill 只保持、不得改)
|
|
740
|
+
- knowledgeAccess: (research / owned / used / observed / supplied_by_brand,单选)
|
|
741
|
+
- permittedExperienceClaims: ({ownership, delivery, wear, service} 的子集;**空集是合法且常见的**)
|
|
742
|
+
- attentionFocus: (这个账号在该品类里真正在意什么)
|
|
743
|
+
- questionIntent: (它真正想弄清什么;没有就写 None)
|
|
744
|
+
- postingWhy: (这个账号自己为什么发;**不是 PostingTrigger 的复述**,二者须能共存)
|
|
745
|
+
- knows: (本稿可假定它知道什么;可多条)
|
|
746
|
+
- doesNotKnow: (本稿**不得**表现出掌握什么;可多条)
|
|
747
|
+
- permittedFactRefs: (本稿可用的已批准产品事实引用)
|
|
748
|
+
- brandRelationshipDisclosed: (Yes / No / NotApplicable —— 指**稿件声明了什么**,不是事实为何)
|
|
749
|
+
- DeclaredBy: (是谁授权了这些主张:人或角色,**不能是生成 agent 自己**)
|
|
750
|
+
- ClaimAuthorizationRef: (授权 permittedExperienceClaims 的已提交材料引用)
|
|
751
|
+
- RoleLabels: (可选、非权威;任何门禁都不读它)
|
|
752
|
+
|
|
753
|
+
⚠️ `permittedExperienceClaims` 非空但 `DeclaredBy` / `ClaimAuthorizationRef` 缺失时,该 Card
|
|
754
|
+
记录的是「Brief 声明了什么」而不是「谁授权了什么」——只能按前者汇报,不得称已授权。
|
|
755
|
+
`PersonaCardHash` 只防篡改,不代表授权。
|
|
717
756
|
|
|
718
757
|
**NarrativeLayering(G1,主帖与评论均必填,先于标题方向与大纲):**
|
|
719
758
|
- InternalCoverageIntent: (仅内部:FAQ 编号/原文、fanout 子查询、关键词、缺口象限码、prompt_id;可多条)
|
|
@@ -904,7 +943,8 @@ C-B 评论**不填本块**,改用评论模板的 `InheritedBrandPlacementBasis
|
|
|
904
943
|
[ ] 【v2.12.26】项目差异化窗口已锁定(WindowCount 8–12 且 WindowDays 30–60 同时生效 / WindowScope: PostOnly / WindowSort / BaselineMaxAgeDays / IndexRevision),写入指纹索引文件头
|
|
905
944
|
[ ] 【v2.12.26】每个**主帖** Key 的「客户内容原型」均命中 memory/phase0-客户内容原型映射.md 的 Approved 行,MappingRuleID 与 MappingVersion 已记入 Routing Decision;无未映射代号(自评继承配对主帖的原型值,外部评论填「—」,不单独要求映射)
|
|
906
945
|
[ ] 【v2.12.26】每条主帖 Brief 均含 9 项 LockedFingerprintFields:ContentFunction / StructureFamily / OpeningMove / EvidenceShape / BrandEntryMode / CaveatMode / EndingMode / LengthBand / AnchorSlot
|
|
907
|
-
[ ] 【P0-C】每条主帖 Brief 均含
|
|
946
|
+
[ ] 【P0-C】每条主帖 Brief 均含 3 项 PrewritingControlFields:AssignedFlair(非空,现行 flair 或 NoFlairAvailable/NoFlairRequired;且已按 B-1.0/W0 对台账 ProposedFlair 完成验证锁定,FlairVerificationStatus ∈ {Verified, FallbackAssigned},无 Rejected 遗留)+ PostingTrigger(受控五值,满足 × BrandEntryMode 交叉约束)+ PersonaCardRef(非空,带 PersonaCardVersion / PersonaCardHash)
|
|
947
|
+
[ ] 每条主帖 Brief 的 Persona Card 完整:knowledgeAccess 单值、permittedExperienceClaims 只取自 {ownership, delivery, wear, service}(空集合法)、postingWhy 非空且能与 PostingTrigger 共存;评论行填 N/A。permittedExperienceClaims 未从品牌关系推断,RoleLabels 未被任何判据使用
|
|
908
948
|
[ ] 【P0-C】每张 baseline 卡记录 flair 覆盖:BaselineScope / BaselineFlair / FlairSampleCount / FlairCoverageStatus(Exact 或 ApprovedFallback;Insufficient → BlockingGap)/ FallbackApprovalRef(fallback 时须署名)
|
|
909
949
|
[ ] 【v2.12.26】每条主帖 Brief 均含 4 项 TraceFields:SampleSetID / RecentCollisionCheck / MappingRuleID / MappingVersion
|
|
910
950
|
[ ] 【v2.12.26】每条主帖 Brief 均含 Routing Decision 块,五层候选收敛轨迹齐全(Baseline / Function / Evidence / PrimaryAndCompliance / MappingPredicates + MatchedPredicate),SelectedCandidateRank 与 SkippedCandidates(CandidateRank + RejectionReason)已记录;跳过更靠前候选的理由均为 1–5 层硬失败,差异化仅作 tie-breaker,CollisionRepairPath 已记录
|
|
@@ -103,13 +103,18 @@ LastUpdatedAt: <ISO timestamp>
|
|
|
103
103
|
| `LengthBand` | 依据该 subreddit baseline 的中位数 + IQR 派生的档位,**不设跨板块固定词数** |
|
|
104
104
|
| `AnchorSlot` | 见 ABU 七种合法位置;无需 ABU 时填 `N/A` |
|
|
105
105
|
|
|
106
|
-
|
|
106
|
+
**三个前置控制字段(`PrewritingControlFields`,与 9 个 `LockedFingerprintField`
|
|
107
107
|
并列但不并入锁字段集,也不进硬碰撞三元组):**
|
|
108
108
|
|
|
109
109
|
| 字段 | 受控值 |
|
|
110
110
|
|---|---|
|
|
111
111
|
| `AssignedFlair` | 该主帖 Key 的目标发布 flair(**受控于该 subreddit 的现行 flair 列表**,不得自造)。主帖必填、不得留空;板块无 flair 或允许不选时用哨兵值 `NoFlairAvailable` / `NoFlairRequired`(不得与评论的 `N/A` 混用)。评论 / 回复填 `N/A` |
|
|
112
112
|
| `PostingTrigger` | `ConcreteFailure` / `PurchaseDecision` / `MeasurementResult` / `CompatibilityGap` / `UnsolicitedTestimony`(闭集)。回答「这篇帖为什么现在值得发」 |
|
|
113
|
+
| `PersonaCardRef` | 该主帖 Key 的 Persona Card 引用(+ `PersonaCardVersion` / `PersonaCardHash`)。回答「这个账号凭什么知道这些、可以声称哪些第一手经历」。字段与生命周期见 `persona-card-contract.md`。评论 / 回复填 `N/A` |
|
|
114
|
+
|
|
115
|
+
⚠️ `PersonaCardRef` 与另两个前置字段同样由 Brief 预分配、writer 不得自选,但它**不是指纹字段**:
|
|
116
|
+
不进 `memory/phase4-叙事指纹索引.md` 的固定表、不进 `HashSchemaVersion` 的 hash 定义、
|
|
117
|
+
不进硬碰撞三元组。指纹索引的表结构与 hash 定义不因本字段变更。
|
|
113
118
|
|
|
114
119
|
字段语义补充:
|
|
115
120
|
|
|
@@ -460,7 +465,7 @@ FingerprintSyncStatus: PendingWritingOwner
|
|
|
460
465
|
|
|
461
466
|
| 层 | 执行者 | 内容 | 失败行为 |
|
|
462
467
|
|---|---|---|---|
|
|
463
|
-
| 1 · 预分配 | `reddit-phase-brief` | 在 Brief 里预先锁定 9 个结构字段 +
|
|
468
|
+
| 1 · 预分配 | `reddit-phase-brief` | 在 Brief 里预先锁定 9 个结构字段 + 3 个 `PrewritingControlField`(`AssignedFlair` / `PostingTrigger` / `PersonaCardRef`)并写入 `Planned` 指纹行(**`PersonaCardRef` 只进 Brief,不写入指纹行**);**不让 writer 临场自选** | Brief 缺字段(含 `AssignedFlair` / `PostingTrigger` / `PersonaCardRef`)→ `BlockingGap`,不得进入写作 |
|
|
464
469
|
| 2 · 写作硬门禁 | `reddit-content-writing` | 开写前必须读取有效窗口并完成碰撞检查;写完后从终稿推导实际指纹与 `PostingTrigger` | 未读窗口 / 未做碰撞检查 / 实际与 `Planned` 结构字段或 `PostingTrigger` 不符 → 停止并退回 Brief |
|
|
465
470
|
| 3 · 交付反查 | `reddit-delivery-check` | 反向校验窗口无碰撞、映射已批准、结构未被 rewrite 改动、`AnchorSlot` 合法 | 任一不符 → `OverallStatus: NeedsFix` |
|
|
466
471
|
| 4 · hash 绑定 | `reddit-delivery-check` | 重算终稿 hash,与指纹行、review log 三方比对 | 任意两者不一致 → 阻断交付 |
|
|
@@ -33,7 +33,54 @@ when the brand or campaign context is approved and known.
|
|
|
33
33
|
subreddit-rule fit from supplied evidence, context, natural intent, and
|
|
34
34
|
compliance red lines.
|
|
35
35
|
- persona_consistency is not a completed account-persona check. Report it as
|
|
36
|
-
NotAssessed
|
|
36
|
+
NotAssessed, never as confirmed account fit. There is no partially-verified
|
|
37
|
+
tier: Hub stamps this dimension `not_assessed` with reason
|
|
38
|
+
`no_persona_voice_profile` and drops it from the denominator, so NotAssessed is
|
|
39
|
+
the whole of what the payload supports. Reporting a middle grade would be
|
|
40
|
+
inventing a confidence the review never established.
|
|
41
|
+
- Hub now says so in the payload instead of leaving you to infer it. Every
|
|
42
|
+
dimension carries `status`, which is server-stamped and overrides anything the
|
|
43
|
+
model claimed. When `status` is `not_assessed`, that dimension was excluded
|
|
44
|
+
from the score entirely — its weight was removed from the denominator, and
|
|
45
|
+
`notAssessedReason` says why (`no_persona_voice_profile`, `no_account`,
|
|
46
|
+
`no_completed_review_excerpts`, `no_subreddit_rules`, `not_applicable`,
|
|
47
|
+
`insufficient_context`, `dimension_missing`, `not_evaluated_deterministic`).
|
|
48
|
+
- `thresholdSnapshot` carries the same facts in aggregate form:
|
|
49
|
+
`scoredDimensions`, `excludedDimensions` (`{dimension, reason}[]` on both the
|
|
50
|
+
post and comment endpoints), `denominator`, and `applicabilitySignature`. On a
|
|
51
|
+
`degraded` result, `unevaluatedDimensions` lists dimensions that were
|
|
52
|
+
assessable but never got a model answer — those are not exclusions and are not
|
|
53
|
+
reflected in the denominator.
|
|
54
|
+
- `dimensionsEvaluated: false` means no dimension was actually scored at all
|
|
55
|
+
(a deterministic compliance short-circuit, or a degraded run). On those
|
|
56
|
+
results `scoredDimensions`, `denominator`, and `applicabilitySignature`
|
|
57
|
+
describe the denominator that *would* have applied, not a review that
|
|
58
|
+
happened. Never read them as coverage.
|
|
59
|
+
- `status: guardrail` is a third case, and it is not the same as `scored`. A
|
|
60
|
+
guardrail dimension was assessable, but it never enters the score — it can only
|
|
61
|
+
push a `pass` down to `revise`. The two subreddit style dimensions are the
|
|
62
|
+
guardrails: `subreddit_style_fit` is a guardrail whenever an approved style
|
|
63
|
+
profile applied, and `brand_exposure_fit` additionally requires a brand policy
|
|
64
|
+
to be in play — on an organic review it comes back `not_assessed` even with a
|
|
65
|
+
style profile present. Report guardrails as observations, never as part of the
|
|
66
|
+
score.
|
|
67
|
+
- Only `status: scored` dimensions are in the score. `scoredDimensions` in the
|
|
68
|
+
snapshot lists exactly those, so filtering the payload for `scored` and
|
|
69
|
+
filtering the snapshot agree; anything else (`not_assessed`, `guardrail`) is
|
|
70
|
+
outside both the numerator and the denominator.
|
|
71
|
+
- Report every `status: not_assessed` dimension as NotAssessed. Do not report it
|
|
72
|
+
as a low score, a passing score, or a partial check.
|
|
73
|
+
- A `not_assessed` dimension still carries a `score` number. That number is the
|
|
74
|
+
raw model output kept for audit only; it did not enter the average or any
|
|
75
|
+
threshold. Never quote it as a result and never aggregate it.
|
|
76
|
+
- In ContentOnly, expect `persona_consistency` (posts) and `persona_voice`
|
|
77
|
+
(comments) to come back `not_assessed`, plus `self_repetition` when the
|
|
78
|
+
account has no recent-comment excerpts on file. That is correct behaviour, not
|
|
79
|
+
a degraded review.
|
|
80
|
+
- Because the denominator depends on what was assessable, scores are only
|
|
81
|
+
comparable within the same `rubricVersion` **and** the same
|
|
82
|
+
`thresholdSnapshot.applicabilitySignature`. Do not compare or average a
|
|
83
|
+
ContentOnly score against an AccountBound one.
|
|
37
84
|
- accountCandidateFeedback is advisory account-selection feedback in this mode.
|
|
38
85
|
It must not block a content-only completed/pass result.
|
|
39
86
|
- A ContentOnly brandFitReviewRequired signal is deferred to AccountBound. It
|
|
@@ -46,9 +46,49 @@ Required:
|
|
|
46
46
|
- `NeedsVerificationCandidates`
|
|
47
47
|
- `NotRecommended`
|
|
48
48
|
- `MissingEvidence`
|
|
49
|
+
- `EvidenceGatheredAt`
|
|
50
|
+
- `EvidenceValidUntil`
|
|
49
51
|
|
|
50
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`.
|
|
51
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
|
+
|
|
52
92
|
## Planning To Brief
|
|
53
93
|
|
|
54
94
|
Required:
|
|
@@ -85,7 +125,12 @@ Required:
|
|
|
85
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
|
|
86
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`
|
|
87
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
|
|
88
|
-
- every post Brief row carries the nine `LockedFingerprintFields` (`ContentFunction`, `StructureFamily`, `OpeningMove`, `EvidenceShape`, `BrandEntryMode`, `CaveatMode`, `EndingMode`, `LengthBand`, `AnchorSlot`), the
|
|
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
|
|
89
134
|
- every post Brief row carries a `Routing Decision` block with the five candidate-narrowing steps, `MatchedPredicate`, `SelectedStructureFamily`, and `CollisionRepairPath`
|
|
90
135
|
- `RecentCollisionCheck` is `Pass` (or `Exception` with an approved `ExceptionRef`) for every row
|
|
91
136
|
- `brief_approval_mode`
|
|
@@ -135,6 +180,9 @@ MappingRuleID: # when a client prototype applies
|
|
|
135
180
|
StructureFamily:
|
|
136
181
|
AssignedFlair: # PrewritingControlField; non-empty; NoFlairAvailable/NoFlairRequired for flairless boards
|
|
137
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
|
|
138
186
|
OpeningMove:
|
|
139
187
|
EvidenceShape:
|
|
140
188
|
BrandEntryMode:
|
|
@@ -152,6 +200,7 @@ DraftHash: # PENDING until the post-review recompute
|
|
|
152
200
|
|
|
153
201
|
**Not required for `Comment` / `Reply` / `Title`:** `PrimaryPostType`,
|
|
154
202
|
`StructureFamily`, `SampleSetID`, `AnchorSlot`, `RecentCollisionCheck`,
|
|
203
|
+
`PersonaCardRef` / `PersonaCardVersion` / `PersonaCardHash`,
|
|
155
204
|
`DraftHash` from a fingerprint row. These artifacts carry no fingerprint row
|
|
156
205
|
(`WindowScope: PostOnly`); they still need Hub review and `FinalDraftSha256`,
|
|
157
206
|
and the fabricated-human-signal rules still apply to them.
|
|
@@ -168,6 +217,14 @@ Rules:
|
|
|
168
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`.
|
|
169
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`.
|
|
170
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.
|
|
171
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.
|
|
172
229
|
|
|
173
230
|
## Brand Risk To Writing
|
|
@@ -198,13 +255,26 @@ Required:
|
|
|
198
255
|
- `memory/content-review-log.md`
|
|
199
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`)
|
|
200
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`
|
|
201
|
-
- 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
|
|
202
259
|
- no delivered post Key collides with any other Key in the rolling window unless an approved `ExceptionRef` exists
|
|
203
260
|
- every post/comment to be delivered has Hub `executionStatus=completed` and `verdict=pass`
|
|
204
261
|
- final delivery rows have `ReviewMode: AccountBound` and a real `accountId`
|
|
205
262
|
- ContentOnly rows may hand off to account selection with `AccountBindingStatus: Pending`, but cannot be marked `ReadyForDelivery: Yes`
|
|
206
263
|
- no delivered row has unresolved `brandFitReviewRequired` or blocking `accountCandidateFeedback`
|
|
207
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`)
|
|
208
278
|
- single Feishu draft document exists when Feishu delivery was selected
|
|
209
279
|
- `memory/phase5-交付清单.md` is written at delivery
|
|
210
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.
|