user-visible-output-contract · git:20260827.f3bcda6 · 2026-08-27 · sha256 590fe544603f5122
user-visible-output-contract git:20260827.f3bcda6A
Immutable. This exact content is served forever at /api/v1/blob/590fe544603f5122.
--- name: user-visible-output-contract description: 用户可见输出契约 Owner — 统一入口检查、完成检查、确认、进度、结果、阻断及内部产物到用户交付的确定性投影 --- # User Visible Output Contract Skill ## 职责 当任务需要输出 PC0~PC7、FC/SC/RC/T、CP/危险动作确认、长任务进度、最终结果、阻断原因或文件交付列表时,本 Skill 是用户可见语义与渲染的唯一 Owner。 本 Skill 只负责 `ArtifactDeliveryManifestV1 → ArtifactAnchorProjectionV1 / UserFacingArtifactSetV1 → PostCompletionActionSetV1 → DevCodexVisibleEnvelopeV2 → renderer`。它不替代 `compliance` 的检查含义、`cp-gate` 的确认状态、`report`/`memory` 的写入职责、`host-contract-verification` 的宿主 direct replay,也不判断专业内容质量。`DevCodexVisibleEnvelopeV1` 只保留一个兼容窗口的读取能力,禁止新生产者继续写入。 确定性实现位于 `hooks/_runtime/visible-output-contract.cjs`,结构约束位于 `visible-output-contract.schema.json`。 ## 触发条件 | 场景 | 是否触发 | |---|:---:| | PC0~PC7 入口检查 | 必须;且须作为用户**首次可见**块先于实质正文与产物 mutation(S07 时序;文首补 PC ≠ 先输出) | | FC/SC/RC/T 完成检查 | 必须 | | CP1/CP2/CP3、验证预算、发布或其他 DevCodex 工作流确认 | 必须;文件/命令操作权限提示由宿主自身呈现,不由 DevCodex 复制审批 | | 多批次进度、等待、阻断、恢复 | 必须 | | 最终结果与文件交付 | 必须 | | 仅内部状态写入且本轮无用户可见消息 | N/A + skipReason | ## TaskPhaseProjectionGate(PF-183 · 条件) 多 active 任务、用户说「继续/刚才/当前」、或投影实施/进度时,用户可见进度/最终回复须含: - `activeTask`(或等价任务名 + portable path) - `phaseKind` 或 CP1~CP3 状态 - `sourceDelivery=none|started|partial|complete` - 唯一 `nextAllowedAction` 禁止:把「04 已有 / CP3 候选」写成「已在实施」。仅 CP3 confirmed + 05 + source mutation 才可 `started`。 探针:`classifyTaskPhaseProjectionSample`(`scripts/lib/executable-absorption-gates.js`)。 ## 单向链路 1. `ArtifactDeliveryManifestV1`:记录本任务所有持久化 mutation、恢复证据和审计证据;planned、observed、internalDelivered 必须精确对账。 2. `ArtifactAnchorProjectionV1`:可选上下文锚点投影,只携带 canonical path、contentDigest、projectionDigest、truthSourceKind、stalePolicy 与 evidenceRefs,不复制正文。 3. `UserFacingArtifactSetV1`:只能由 manifest 纯函数投影,禁止模型临场挑“主要产物”。 4. `PostCompletionActionSetV1`:从已验证缺口、Profile 和用户授权边界投影“当前必做 / 唯一主动作 / 最多两个条件动作”;不得把产物文件当动作。 5. `DevCodexVisibleEnvelopeV2`:承载 message kind、稳定状态、checks、decision、visible set、action set、capability 和 semantic digest。 6. renderer:按已验证能力生成 `rich-markdown / portable-markdown / plain-text`;不得改变语义集合、顺序、状态或动作。 禁止 renderer、Prompt、Hook parser 或最终回复反向补写 manifest 状态。 ## ArtifactDeliveryManifestGate 每个 entry 必须包含: `artifactId / canonicalPath / previousPath / lifecycleOperation / origin / ownership / artifactClass / deliveryRequirement / visibility / displayName / purposeKey / purposeText / userAction / readingOrder / contentDigest / evidenceRefs[]`。 - `lifecycleOperation=create|update|rename|move|delete|unchanged-evidence`;rename/move/delete 必须保留 previousPath,delete 使用 tombstone 语义。 - `visibility=decision-required|result|evidence|optional-detail|internal-only`。 - `deliveryRequirement=required|supporting|internal`;required 不得隐藏,internal 必须为 internal-only。 - `reconciliation` 必须满足 planned=observed=entries=internalDelivered;missing/unexpected/conflicting 任一非空即 BLOCK。 - 同一 artifactId 或 canonicalPath 重复、`file://`、非语义 displayName、缺 digest/evidence 均为非法。 - 根 manifest 的序列化容器不登记为自身 entry,避免 self-hash 无限递归;其 storage path 与文件 SHA256 必须由上级 ECR/validation receipt 记录。其他批次 manifest 或 raw manifest 作为普通输入时仍属于 `raw-manifest/internal-only`,不得借此例外漏记。 ## ArtifactAnchorProjectionGate 当任务需要后续上下文续接、短投影或跨报告锚点时,必须从已验证的 `ArtifactDeliveryManifestV1` 纯函数生成 `ArtifactAnchorProjectionV1`,禁止手写锚点列表。 - `ArtifactAnchorV1` 必须包含 `artifactId / artifactKind / truthSourceKind / canonicalPath / contentDigest / projectionDigest / generatedAt / owner / status / stalePolicy / evidenceRefs[] / summaryLine / classification / anchorDigest`。 - `truthSourceKind=json-canonical|markdown-canonical|projection|external`,由 `classifyArtifactTruthSource` 按 artifactKind 决定;调用方显式覆盖时也必须落入枚举。 - JSON canonical 产物优先用于机器校验;Markdown canonical 产物可生成短 MD 投影,但短投影只能作为 `projectionDigest` 与 `summaryLine`,不能替代 canonical contentDigest。 - manifest 未对账、缺 contentDigest、非绝对 canonicalPath、`file://`、非法 status 或证据列表无效时,anchor projection 必须 invalid/BLOCK。 ## UserFacingArtifactProjectionGate 默认用户面只包含: - `decision-required`; - `result`; - `deliveryRequirement=required` 的 evidence。 session、daily、Agent/全局 SUMMARY、task state、checkpoint/runtime state、raw receipt、raw manifest、raw ledger 默认 `internal-only`,但仍必须写入、验证、进入 manifest 并参与 ECR。只有用户明确要求、resume/handoff、状态冲突、写入失败、治理调查、审计取证或文件本身就是审查对象时,才升级为可见。 投影 scope: | scope | 行为 | |---|---| | `default` | 最小必要用户交付 | | `all-deliverable` | 所有非 internal-only 项;用于用户要求完整交付清单 | | `internal-audit` | 包含 internal-only;仅审计、治理调查或用户明确要求内部留痕时 | 每次投影必须满足 `listed + remaining = total`,并按 `decision-required → result → evidence → optional-detail`、readingOrder、artifactId 稳定排序。 ## SemanticArtifactNameGate - 用户面名称必须是“内容与用途”,不能只是路径、文件名、CP 编号、版本或状态。 - 每项必须同时给出 `displayName + purposeText + userAction`。 - 动作标题仅允许:`需要你确认的文件 / 本批交付文件 / 完成交付文件 / 阻断证据`。 - 禁止当前消费者输出“主要产物”或“本次会话全部产物”;历史版本文档不回填。 ## ArtifactPathColumnGate(PF-175 / PI-155) 用户面交付表、CP 确认清单与 Envelope renderer **必须**为每项提供可定位路径,且与语义名分离: | 规则 | 要求 | |------|------| | 默认列 | 自由文本表:`语义名称 \| 用途 \| 路径 \| 操作`(操作可并入用途列,但**路径列不可省**) | | list 行 | 至少含 `displayName` + `purposeText` + `路径:…` + `操作:…` | | 路径默认值 | **workspace-relative portable**(`path.relative(workspaceRoot)` 风格,正斜杠) | | 绝对路径 | 仅当:用户明确要求、链接失败、`targetRelation=outside-workspace`、路径歧义、或 `absolutePathFallback` | | Rich 并存 | Rich clickable 允许 **语义链接 href=绝对路径(便于打开)** + **路径列=portable**;**禁止**再追加冗余 `绝对路径:…` 行(除非 fallback 激活) | | 禁止 | legacy「主要产物 / 核心文件 / 路径列表」+ 裸绝对路径且无语义名/用途/操作 | 机器分类(`classifyArtifactPathColumnSample`):`present` / `missing-path-column` / `legacy-bare-path` / `not-claimed`。生产消费者:`lifecycle-visible-reply.analyzeArtifactDelivery` 必须调用该分类器;`missing-path-column` / `legacy-bare-path` 不得 `verified-present`。 Owner:本 Skill + `hooks/_runtime/visible-output-contract.cjs` + `lifecycle-visible-reply.cjs`;**禁止**平行新 Gate 命名体系。 与 LinkCapabilityDecision 的关系:路径列是**定位字段**,链接 mode 是**打开能力**;二者同向,不得用「Rich 不重复绝对路径」删掉 portable 路径列。 ## LinkCapabilityDecisionGate `LinkCapabilityDecisionV1` 保留为持久化记忆/产物相对链接投影契约。用户可见最终回复使用 `HostLinkCapabilityDecisionV2`,必须把 `hostSurface` 与 `presentationSurface` 分开,并以 `rendererId + evidenceState` 选择打开方式,不能按客户端名称推定可点击: | openMode | 使用条件 | |---|---| | `native-action` | 当前宿主面原生打开动作已验证(如 Codex Desktop 文件面板) | | `markdown-link` | 当前呈现器的本地文件 Markdown 点击已验证 | | `terminal-command` | IDE/编辑器 CLI 命令已验证(VS Code、Zed、WebStorm) | | `portable-path` | 仅保证工作区相对定位 | | `absolute-copy` | CLI/Claude/未知或未验证 renderer 的可复制绝对路径降级 | | `unavailable` | 无法定位或打开失败,必须附 reason | V1 的 mode 兼容语义仍为: | mode | 使用条件 | |---|---| | `clickable` | 当前 surface 的点击能力已 direct/fixture 验证 | | `portable` | Markdown 可用,但点击能力未验证或未知 | | `plain` | 只保证纯文本可复制 | | `failed` | 链接已失败或宿主无法定位目标 | Rich clickable 只显示一个语义 Markdown 链接作为名称主表示,**不得**在路径列之外再重复明文绝对路径行。Portable/Plain 优先工作区相对或短路径。路径列规则见 `ArtifactPathColumnGate`。只有用户要求、链接失败、目标在工作区外、路径歧义或宿主无法定位时才强制路径列/ fallback 使用绝对路径,并记录 fallbackReason。 `evidenceState=verified` 必须携带非空 `evidenceRefs`;V2 `hostSurface` 与 Envelope context 必须一致,且 `presentationSurface / rendererId / openMode` 必须进入完整性与 semantic digest。mode、fallback、reason、target relation 或 decisionId 任一 sibling mutation 都必须 fail closed。`failed/unavailable` renderer 必须给出可复制的绝对定位与 fallbackReason,不能再次输出已知失败的相对链接。 ## VisibleEnvelopeGate `messageKind` 固定为: `entry-check / completion-check / confirmation / progress / final-result / error-block`。 状态固定为 `PASS / WARN / BLOCK / UNVERIFIED / N/A`,整体状态由 checks 严重度推导,禁止调用方覆盖;`PASS` 的 evidenceState 必须为 verified。`entry-check` 必须完整保留 PC0~PC7 及 ordinal 0~7。schema 无效、未知状态、缺必要 check、task/manifest/visible set/capability identity 不一致或 presentation 非法时,必须生成 `VISIBLE_ENVELOPE_INVALID` 的 BLOCK envelope,并强制 expanded portable 降级。 `semanticDigest` 对去展示后的 canonical semantic core 计算;presentation tier、图标、换行、点击形式和本地化 summary 不得改变 digest。 ### PostCompletionActionSetGate(V2) 实施或审查结束后,用户面可以提示真正适用的下一步,例如生成接口文档、补 `.http` 验证、提交、切换目标分支、按 commit id `cherry-pick` 或推送;但必须先生成 `PostCompletionActionSetV1`,不能用泛化话术罗列菜单。 | 字段 | 约束 | |---|---| | `requiredNow[]` | 当前交付不可缺的工作;一旦非空就禁止 `completion-check/final-result` 作完成声明 | | `primaryAction` | `null` 或唯一主动作;没有真实缺口时必须为 `null`,不得输出“继续当前动作”凑建议 | | `conditionalActions[]` | 最多 2 个,只在 reason 描述的前置条件成立后适用 | | action | 必须包含 `kind / label / reason / evidenceRefs / applicability / authorization` | | `authorization` | `requiredNow` 可在既有任务授权内使用 `not-required`;可选非 Git 下一步只能是 `suggest-only`;Git 写动作使用 `explicit-required`,`push` 永远不得由建议文字推定为已授权 | `kind` 至少覆盖 `api-docs / http-verification / commit / switch-target / cherry-pick / push / other`。同一个已知 kind 在一份 action set 中最多出现一次,避免用不同文案重复推荐同一动作;`other` 仍可表达两个真正不同的条件动作。如果接口文档或 `.http` 已被用户请求、Profile 或验收标准规定为本次必交付,它们属于 `requiredNow` 并须在完成前实施,不能挪到“下一步建议”。已完成、不适用或缺证据的动作不得推荐;用户交付文件只来自 `UserFacingArtifactSetV1`。 V1 兼容规则:parser/renderer 可读取 `DevCodexVisibleEnvelopeV1.recommendedAction`,但只能映射为 `legacy-v1-read-only + unverified + suggest-only` 的内存视图,不得据此推断 Git、文档类型、适用性或授权,也不得回写 V1。 ## Dialogue-Primary Closeout(对话内可读收口 / DPC) 完成态 `final-result` / 完成宣称,以及 analyze / audit **收敛交付**时,**阅读主入口是最终回复**(对话内已渲染 Markdown),报告文件是归档/深读/审计面,不是默认阅读路径。 ### 叙事最小包(强制,从宽) | 块 | 要求 | |----|------| | 结果一句话 | 做成了什么 / 结论是什么 | | 关键要点 | ≥1 条实质内容(单句含原因亦可);禁止为凑条灌水 | | 与 FVS | 解耦:有验证矩阵不能代替结论叙事 | | 与交付清单 | 路径列仍要(PF-175);**不得**用「打开 md 预览」作默认 userAction | 机器分类:`analyzeDialogueNarrativeSample` / `classifyDialogueNarrativeSample` / `hasReadableNarrativeSnippet`。 | classification | 含义 | |----------------|------| | `not-claimed` | 非完成/收敛语境 | | `present` | 有可读叙事 | | `narrative-missing` | 宣称完成/收敛但只有链接/详见报告/纯矩阵 | | `waived` | 用户显式 override(只要路径/不要摘要等) | 负向:仅报告链接、仅「详见报告」、仅验证矩阵字段。 正向:结果句 + 要点;analyze 须同时满足报告落盘(见 PF-169 / `link-only-thin`)。 **B1** classifier + Skill/单测;**B2** `lifecycle-visible-reply` 在 Stop/PreCompact **有正文时**写入 `dialogueNarrativeStatus` / `analysisDeliveryStatus`,dev+reportTouched 时进入 closure reminder;无正文仍 `unverified`(Grok 诚实上限)。 默认 userAction 写「深读时打开归档报告」;**禁止**「请用 Typora/浏览器打开预览」作为默认动作。 ## UserVisibleReplyLayoutV1(六宿主同源 · 人话优先) 对 **Copilot / Claude Code / Codex / Gemini / Grok / Cursor** 用户可见完成态与入口态使用同一布局;宿主只改变硬拦/注入,不改变语义字段。Cursor Cloud Agent 保持 Partial / UNVERIFIED,但不能据此省略入口布局。 推荐顺序: 1. `### DevCodex · 入口检查`(表格 PC0~PC7 人话;禁止进度缩写 / 折叠行)— **始终必出** 2. 正文结论(Dialogue-Primary) 3. 仅在需要时:`### 复审验证(白话)` / 完成检查 / FVS / 产物表(见 NoisePolicy) 禁止:入口检查写成施工日志;FVS 只有命令墙无白话;分析阶段失败证据冒充修复成功。 ## UserVisibleNoisePolicyV1(降噪 · 六宿主同源) | 原则 | 规则 | |------|------| | P1 入口常显 | 非 chat 实质轮次必须 PC0~PC7 | | P2 结果优先 | 正文结论是主阅读路径 | | P3 静默通过 | **未**宣称工作完成 → 用户面不贴完成检查/FVS/FC 全表/产物表/EnforcementHonesty | | P4 失败展开 | BLOCK/WARN/验证失败/流程 gap/用户要详情 → 展开相关块 | | P5 完成短证 | 宣称完成且全绿 → **短 FVS**(白话 + 命令 exitCode + 边界),不默认 FC1~T13 | | P6 双面证据 | 完整合规矩阵写入报告/记忆;对话默认不复读 | | 块 | 未宣称完成 | 宣称完成且全绿 | 宣称完成有缺口 | |----|:----------:|:--------------:|:--------------:| | 入口检查 | ✅ | ✅ | ✅ | | 正文 | ✅ | ✅ | ✅ | | 完成检查 FC 全表 | ❌ | 默认 ❌ | ✅ 只列失败项 | | FinalValidationSummary | ❌ | **短证** | 全量 | | 产物交付表 | ❌ | 有用户交付才一行/短表 | 有问题才展开 | **Stop 语义**:`workDoneClaimed`(已完成/任务完成/宣告完成…)才强制完成脚手架 + FVS;仅出现 `### 完成检查` 标题不等于工作完成。 ## FinalValidationSummaryGate(PF-186 / PI-164) dev / fix / self-fix 的 `completion-check` 或 dev 模式合规块宣告完成时,最终用户可见回复必须投影 `FinalValidationSummaryV1` 或等价短矩阵。报告可保留长日志,但最终回复不能只写“全绿 / 已通过 / 详见报告”。完成态还须满足上方 **Dialogue-Primary** 叙事最小包(与本 Gate 同时适用,不可互相抵消)。 **呈现顺序(强制)**:先 **白话 1~3 句**,再证据表/命令行(须含 `exitCode`)。共享模板:`content/shared/compliance/validation-summary.md`。 最小字段: | 字段 | 要求 | |---|---| | `plainSummary` | 白话结论(推荐以 `**白话**` / `白话:` 起笔) | | `commands` | 至少一条权威验证命令或明确 `skipped + reason`;执行过的命令必须列 `exitCode` | | `runId/keyCount` | `runId`、V 范围、关键计数或检查项数量至少一类 | | `postCommitReplay` | 出现 commit / 提交声明时必须列 post-commit replay;未提交时可写 `N/A + reason` | | `workspaceSyncStatus` | 写明 synced / skipped / blocked / **N/A 未触发** 及理由 | | `dirtyBoundary` | 写明 source-root / active-root dirty 边界;推荐含 `git status clean-tree` 等范围词 | | `releaseActionBoundary` | 明确 push / tag / release / publish 是否执行;未执行也必须写 | | `reportRefs` | 指向报告/清单等 required evidence,路径列仍受 `ArtifactPathColumnGate` 约束 | 机器分类:`analyzeFinalValidationSummarySample` / `classifyFinalValidationSummarySample`。负向包括:有 `completion-check` marker 但无命令、命令无 `exitCode`、只有“全绿/通过”、只链接报告、缺 workspace sync、缺 dirty boundary、缺 release boundary、提交任务缺 post-commit replay。 ## EvidenceFreshness Interop 当最终回复、完成检查或交付文件列表支撑“已验证 / 已完成 / 已推送 / 推荐采纳”等 strong claim 时,`ArtifactAnchorV1`、`ArtifactAnchorProjectionV1` 与 `FinalValidationSummaryV1` 的 digest 可作为 `EvidenceFreshnessReceiptV1.evidenceRefs` 和 `dependsOn` 输入。用户面不展示内部 receipt 全文,只展示 `StaleEvidenceLintDecisionV1.status/reuseDecision` 的短摘要;缺 fresh evidence 时必须降级为 `WARN/UNVERIFIED`,不能只靠报告链接或 SUMMARY 宣称通过。 ## FreeTextEntryCheckCompletenessGate(PF-087 · 自由文本入口完整性) 当用户可见回复以 **Markdown/自由文本** 输出入口检查(未走 Envelope API)时,Stop/`lifecycle-visible-reply` 不得仅因出现「入口检查 / PC0 上下文」字样判 `verified-present`: | 规则 | 说明 | |------|------| | 分列必齐 | 须能识别 **PC0…PC7 各自独立** 行/单元格(表格 `| PC0 | … |` 或列表 `- PC0 …`);缺任一 → incomplete | | 禁止折叠 | `PC2–PC7` / `PC2-7` / `PC2~PC7` 等合并范围 → `pc-folded-range`,precheck=`verified-missing` | | 禁止施工日志 | PC3/PC6 等单元格禁止「写报告 02 / 见下清单 / 只读+复现」等进度缩写冒充语义 | | PC0 上下文 | PC0 行须含上下文/计划/项目等实质内容,不得空壳;禁止仅「Profile 已加载」 | | PC4 | **dev** 下 `N/A` 必须带 skipReason/跳过理由;不得无理由伪 N/A | | 六宿主 | 模板同源;Grok 无 inject、Cursor Cloud 无用户级 Hook 时,仍须模型输出完整 PC0~PC7 | | Owner | 本 Skill + `hooks/_runtime/lifecycle-visible-reply.cjs`(`analyzeEntryCheckCompleteness`);**禁止**平行新 Gate 命名体系 | 机器分类:`complete` / `incomplete` / `not-claimed`。负向 fixture:折叠行、缺 PC、dev PC4 无 skipReason。 ## CompactPresentationGate 只有 `entry-check` 和无待确认的 `progress` 可 compact,且必须同时满足: - 同 project/task/contextEpoch/messageKind/semanticDigest; - 全部 checks 为 PASS/N/A; - 用户未要求详情。 compact 仍显示所有 check IDs、状态、整体状态、项目和“状态未变化”;不得省略计算、读取、意图判断或门禁。confirmation、error-block 永远 expanded。 ## HostCapabilityHonestyGate - 宿主未提供可解析 assistant payload 时,只能记录 `unverified`,不能断言 visible envelope 缺失。 - legacy “主要产物 + 绝对路径”文本最多识别为 `unverified-legacy`,不能升级 verified。 - direct replay 缺失时使用 portable/plain fallback,能力强度保持 unverified。 - Rich、portable、plain 的 check IDs、visible artifacts、顺序、状态、动作和 semanticDigest 必须一致。 - **Grok / passive-hook(PF-165)**:无 UserPromptSubmit 注入时仍必须输出完整 PC0~PC7;完成声明须满足 `GrokTurnChecklist`(见 `host-parity-scorecard` / `host-parity-grok.md`),不得把「无 inject」写成可省略入口或报告的理由;`full-capable` ≠ 已注入 PC0。 ## 消费者同步 变更本 Skill 或 runtime 时至少联查: - `instructions.md`、`instructions/01-common.instructions.md`、`instructions/02-output-paths.instructions.md`、`instructions/16-report.instructions.md`、`instructions/17-compliance.instructions.md`; - `compliance`、`report`、`memory`、`document-sync`、`host-contract-verification`、`test-router`、`execution-contract`; - precheck/compliance/progress/delivery/report prompts; - lifecycle visible reply、host/client tests、validation manifest、package files; - README、website、Profile、六宿主部署副本。 ## 验收 - manifest 正反向 reconciliation、rename/move/delete/tombstone、重复/漏项/非法 visibility mutation 全通过。 - default/all-deliverable/internal-audit 的集合与计数守恒。 - internal-only 默认 visible=0,required hidden=0。 - 三 renderer parity:语义集合/顺序/状态/动作/digest 一致;Rich 无冗余 `绝对路径:` 行(无 fallback 时);**三档均含 `路径:` portable 列**(PF-175)。 - 六 message kinds、PC0~PC7、compact↔expanded、unknown/invalid fail-closed 全通过。 - completion-check 正负向:`FinalValidationSummaryV1` 或等价短矩阵必须包含命令/exitCode、runId 或关键计数、workspace sync、dirty boundary、release action boundary;commit 声明必须包含 post-commit replay。 - evidence-freshness 互操作:artifact anchor / projection digest、final validation summary digest、summary-only 降级和缺命令证据负例由 `npm run test:evidence-freshness` 覆盖,并与 `npm run test:visible-output` 一起验证。 - Hook parser 对新 envelope 为 verified-present,对 legacy 为 unverified,对未观察 payload 为 unverified。 - `classifyArtifactPathColumnSample` 负向:缺路径列 / legacy 裸路径;正向:含 `路径:` 或表头路径列。