Cai
3 hours ago 4999a5259bae72b8433e313e387467610bb6f6e6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
 
$ProjectRoot = (Resolve-Path -LiteralPath ".").Path
$CaseId = "ANA-ROBOT-INDUSTRY-001"
$RunId = "RUN-ANA-ROBOT-THREEPIECE-OUTPUT-PREPASS-EVIDENCE-REVIEW-SYNC-001"
$BatchId = "BATCH-ANA-ROBOT-THREEPIECE-OUTPUT-PREPASS-EVIDENCE-REVIEW-SYNC-001"
$ReviewMessageId = "msg_20260705115832279_c8afb307"
$SourceMessageId = "msg_20260705114743635_423f7cfc"
$AuditId = "AUDIT-ANA-ROBOT-THREEPIECE-OUTPUT-PREPASS-EVIDENCE-001"
$NowStamp = "2026-07-05T12:02:00+08:00"
 
$CaseRoot = Join-Path $ProjectRoot "ana-data/cases/机器人案例/ANA-ROBOT-INDUSTRY-001"
$EvidenceDir = Join-Path $CaseRoot "evidence"
$ManifestDir = Join-Path $CaseRoot "manifest"
$OutputCoreDir = Join-Path $CaseRoot "outputs/核心文档"
$ResultDir = Join-Path $ProjectRoot "ana-data/result/机器人案例/ANA-ROBOT-INDUSTRY-001"
$AuditDocDir = Join-Path $ProjectRoot "ana-doc/机器人案例"
$Utf8NoBom = New-Object System.Text.UTF8Encoding($false)
 
function Read-Text($Path) {
    return [System.IO.File]::ReadAllText((Resolve-Path -LiteralPath $Path).Path, [System.Text.Encoding]::UTF8)
}
 
function Write-Text($Path, $Text) {
    [System.IO.File]::WriteAllText((Resolve-Path -LiteralPath $Path).Path, $Text, $Utf8NoBom)
}
 
function Rel-Path($Path) {
    $full = (Resolve-Path -LiteralPath $Path).Path
    $root = $ProjectRoot.TrimEnd("\")
    return $full.Substring($root.Length + 1).Replace("\", "/")
}
 
function Get-Meta($RelPath) {
    $full = Join-Path $ProjectRoot ($RelPath -replace "/", "\")
    if (-not (Test-Path -LiteralPath $full)) {
        throw "Missing artifact: $RelPath"
    }
    $file = Get-Item -LiteralPath $full
    [pscustomobject]@{
        sha256 = (Get-FileHash -LiteralPath $full -Algorithm SHA256).Hash.ToLowerInvariant()
        bytes = [string]$file.Length
        mtime = $file.LastWriteTime.ToString("yyyy-MM-dd HH:mm:ss") + "+08:00"
    }
}
 
function Csv-Text($Rows) {
    return ($Rows | ConvertTo-Csv -NoTypeInformation) -join "`r`n"
}
 
function Add-Section-IfMissing($Text, $Header, $Body) {
    if ($Text.Contains($Header)) {
        return $Text
    }
    return $Text.TrimEnd() + "`r`n`r`n" + $Header + "`r`n`r`n" + $Body.Trim() + "`r`n"
}
 
$nextPath = Join-Path $ManifestDir "next_action_list.csv"
$nextRows = @(Import-Csv -LiteralPath $nextPath)
foreach ($row in $nextRows) {
    if ($row.action_id -eq "NEXT-ROBOT-032B") {
        $row.output = "threepiece_ifr_html_fact_extract_20260705.csv; threepiece_032b_source_fetch_and_extract_status_20260705.csv; threepiece_output_prepass_gap_closure_20260705.csv; threepiece_output_prepass_evidence_package_20260705.csv; threepiece_output_prepass_evidence_summary_20260705.json; review_result $ReviewMessageId / $AuditId"
        $row.status = "CONDITIONALLY_PASSED_THREEPIECE_OUTPUT_PREPASS_EVIDENCE_READY_FOR_OUTPUT_REVIEW_PACKAGE_NOT_OUTPUT_PASS"
    }
    if ($row.action_id -eq "NEXT-ROBOT-032C") {
        $row.input = "$AuditId; threepiece_output_prepass_evidence_package_20260705.csv; threepiece_output_prepass_gap_closure_20260705.csv; case_evidence_map.csv; migration_manifest.csv"
        $row.output = "三件套输出通过审核包待准备;必须单独列出未闭环缺口和降读字段;不得自动视为输出通过"
        $row.status = "QUEUED_AFTER_032B_CONDITIONAL_PASS_PREPARE_OUTPUT_REVIEW_PACKAGE_NOT_OUTPUT_PASS"
    }
}
[System.IO.File]::WriteAllText($nextPath, (Csv-Text $nextRows) + "`r`n", $Utf8NoBom)
 
$reviewSyncPath = Join-Path $EvidenceDir "threepiece_output_prepass_evidence_review_sync_20260705.json"
$reviewSync = [ordered]@{
    case_id = $CaseId
    action_id = "NEXT-ROBOT-032B"
    run_id = $RunId
    source_review_message = $ReviewMessageId
    source_submission_message = $SourceMessageId
    source_audit_id = $AuditId
    synced_at = $NowStamp
    review_conclusion = "CONDITIONALLY_PASSED"
    allowed_next = @(
        "作为后续输出通过审核包输入",
        "将 NEXT-ROBOT-032C 从等待复审调整为可准备输出通过审核包",
        "后续输出包必须单独列出仍未闭环缺口和降读字段"
    )
    prohibited = @(
        "输出通过",
        "覆盖完整",
        "对外交付",
        "完成状态",
        "正式扩池",
        "正式公司池确认",
        "强字段升级"
    )
    retained_gates = @(
        "IFR PDF 后续如引用页码、表格或正文事实,必须补人工下载回执、替代官方 PDF 或其他官方可复核快照。",
        "MIR/Omdia/智元/AMR/ASP/BOM/公司强字段缺口不得因本轮补证包升级。",
        "NEXT-ROBOT-032C 可准备输出通过审核包,但不得自动视为输出通过。"
    )
}
[System.IO.File]::WriteAllText($reviewSyncPath, (($reviewSync | ConvertTo-Json -Depth 8) + "`r`n"), $Utf8NoBom)
 
$threepieceArtifacts = @(
    "ana-data/cases/机器人案例/ANA-ROBOT-INDUSTRY-001/outputs/核心文档/机器人报告索引.md",
    "ana-data/cases/机器人案例/ANA-ROBOT-INDUSTRY-001/outputs/核心文档/机器人的产业链总览.md",
    "ana-data/cases/机器人案例/ANA-ROBOT-INDUSTRY-001/outputs/核心文档/机器人的市场情况总览.md"
)
 
$evidenceMapPath = Join-Path $EvidenceDir "case_evidence_map.csv"
$evidenceRows = @(Import-Csv -LiteralPath $evidenceMapPath)
foreach ($row in $evidenceRows) {
    if ($threepieceArtifacts -contains $row.artifact) {
        $row.evidence_status = "THREEPIECE_OUTPUT_PREPASS_EVIDENCE_CONDITIONALLY_PASSED_READY_FOR_OUTPUT_REVIEW_PACKAGE_NOT_OUTPUT_PASS"
        $row.evidence_entry = "threepiece_ifr_html_fact_extract_20260705.csv; threepiece_032b_source_fetch_and_extract_status_20260705.csv; threepiece_output_prepass_gap_closure_20260705.csv; threepiece_output_prepass_evidence_package_20260705.csv; threepiece_output_prepass_evidence_summary_20260705.json; threepiece_output_prepass_evidence_review_sync_20260705.json"
        $row.review_status = "CONDITIONALLY_PASSED_NOT_OUTPUT_PASS"
    }
}
[System.IO.File]::WriteAllText($evidenceMapPath, (Csv-Text $evidenceRows) + "`r`n", $Utf8NoBom)
 
$migrationPath = Join-Path $ManifestDir "migration_manifest.csv"
$migrationRows = @(Import-Csv -LiteralPath $migrationPath)
foreach ($row in $migrationRows) {
    if ($threepieceArtifacts -contains $row.target) {
        $row.status = "FROZEN_FORMAL_DRAFT_THREEPIECE_OUTPUT_PREPASS_EVIDENCE_CONDITIONALLY_PASSED_READY_FOR_OUTPUT_REVIEW_PACKAGE"
        $row.conclusion_strength = "DRAFT_FOR_REVIEW_PENDING_OUTPUT_REVIEW_STRONG_FIELDS_RETAINED_AS_GAPS_NOT_OUTPUT_PASS"
        $row.next_action = "准备 NEXT-ROBOT-032C 三件套输出通过审核包;必须列出 IFR PDF、MIR/Omdia、AMR/ASP/BOM/公司强字段等未闭环缺口;不得自动视为输出通过、覆盖完整、对外交付或强字段升级。"
    }
}
[System.IO.File]::WriteAllText($migrationPath, (Csv-Text $migrationRows) + "`r`n", $Utf8NoBom)
 
$coreDocs = @(
    (Join-Path $OutputCoreDir "机器人报告索引.md"),
    (Join-Path $OutputCoreDir "机器人的产业链总览.md"),
    (Join-Path $OutputCoreDir "机器人的市场情况总览.md")
)
$coreHeader = "## 0.6 NEXT-ROBOT-032B 复审承接"
$coreBody = @"
reviewer 已在 $ReviewMessageId / $AuditId 对 NEXT-ROBOT-032B 三件套输出通过前补证包给出有条件通过。该补证包可作为后续输出通过审核包输入,并允许 NEXT-ROBOT-032C 从等待复审调整为可准备输出通过审核包。
 
本结论不批准输出通过、覆盖完整、对外交付、完成状态、正式扩池、正式公司池确认或强字段升级。后续如提交输出通过审核包,必须单独列出 IFR PDF 页码级抽取、MIR 原始报告、Omdia 原始报告、AMR/ASP/BOM/公司强字段等未闭环缺口,并说明仍降读的字段。
"@
foreach ($doc in $coreDocs) {
    $text = Read-Text $doc
    $text = $text.Replace("THREEPIECE_OUTPUT_PREPASS_EVIDENCE_PREPARED", "THREEPIECE_OUTPUT_PREPASS_EVIDENCE_CONDITIONALLY_PASSED")
    $text = $text.Replace("NEXT_ROBOT_032B_REVIEW_REQUEST_PREPARED", "NEXT_ROBOT_032B_CONDITIONALLY_PASSED")
    $text = Add-Section-IfMissing $text $coreHeader $coreBody
    Write-Text $doc $text
}
 
$resultPath = Join-Path $ResultDir "result_index.md"
$resultText = Read-Text $resultPath
$resultText = $resultText.Replace("THREEPIECE_OUTPUT_PREPASS_EVIDENCE_PREPARED", "THREEPIECE_OUTPUT_PREPASS_EVIDENCE_CONDITIONALLY_PASSED")
$resultText = $resultText.Replace("NEXT_ROBOT_032B_REVIEW_REQUEST_PREPARED", "NEXT_ROBOT_032B_CONDITIONALLY_PASSED")
$resultHeader = "## 2026-07-05 三件套输出通过前补证包复审承接"
$resultBody = @"
reviewer 已在 $ReviewMessageId / $AuditId 对 NEXT-ROBOT-032B 给出有条件通过。该结论只允许将三件套输出通过前补证包作为后续输出通过审核包输入;不批准输出通过、覆盖完整、对外交付、完成状态、正式扩池、正式公司池确认或强字段升级。
 
NEXT-ROBOT-032C 已调整为可准备输出通过审核包。该审核包必须单独列出仍未闭环的 IFR PDF 页码级抽取、MIR 原始报告、Omdia 原始报告、AMR/ASP/BOM/公司强字段缺口,并说明哪些字段继续降读。
"@
$resultText = Add-Section-IfMissing $resultText $resultHeader $resultBody
Write-Text $resultPath $resultText
 
$remainingPath = Join-Path $ManifestDir "remaining_work_plan_20260704.md"
$remainingText = Read-Text $remainingPath
$remainingText = $remainingText.Replace("| 6B | NEXT-ROBOT-032B | 三件套输出通过前补证包 | IFR HTML 行级抽取、PDF 完整性回执、MIR/Omdia/AMR/ASP/公司强字段补证缺口闭环 | REVIEW_REQUEST_PREPARED | 只申请补证包复审;不得申请输出通过或强字段升级 |", "| 6B | NEXT-ROBOT-032B | 三件套输出通过前补证包 | IFR HTML 行级抽取、PDF 完整性回执、MIR/Omdia/AMR/ASP/公司强字段补证缺口闭环 | CONDITIONALLY_PASSED | reviewer 已允许作为输出通过审核包输入;仍不批准输出通过或强字段升级 |")
if (-not $remainingText.Contains("| 6C | NEXT-ROBOT-032C |")) {
    $remainingText = $remainingText.Replace("| 7 | NEXT-ROBOT-033 | 英搏尔 + 12 个相邻候选 | 补资料复核、继续排除/降级/候选池决策 | QUEUED | 重新进入候选池需单独复审 |", "| 6C | NEXT-ROBOT-032C | 三件套输出通过审核包准备 | 汇总 032B 证据包、仍未闭环缺口和继续降读字段 | QUEUED | 可准备但不得自动视为输出通过;完成后必须另行送审 |`r`n| 7 | NEXT-ROBOT-033 | 英搏尔 + 12 个相邻候选 | 补资料复核、继续排除/降级/候选池决策 | QUEUED | 重新进入候选池需单独复审 |")
}
$remainingText = $remainingText.Replace("- 当前状态:THREEPIECE_OUTPUT_PREPASS_EVIDENCE_PREPARED_PENDING_REVIEW_NOT_OUTPUT_PASS;不申请输出通过、覆盖完整、对外交付、完成状态、正式扩池、正式公司池确认或强字段升级。", "- 当前状态:THREEPIECE_OUTPUT_PREPASS_EVIDENCE_CONDITIONALLY_PASSED_READY_FOR_OUTPUT_REVIEW_PACKAGE_NOT_OUTPUT_PASS;可作为后续输出通过审核包输入,但仍不批准输出通过、覆盖完整、对外交付、完成状态、正式扩池、正式公司池确认或强字段升级。")
$remainingHeader = "## 19. 复审状态更新(AUDIT-ANA-ROBOT-THREEPIECE-OUTPUT-PREPASS-EVIDENCE-001)"
$remainingBody = @"
- 来源消息:$ReviewMessageId。
- 复审结论:NEXT-ROBOT-032B 三件套输出通过前补证包有条件通过,可作为后续输出通过审核包输入。
- 动作同步:NEXT-ROBOT-032B 标记为有条件通过;NEXT-ROBOT-032C 从等待复审调整为可准备输出通过审核包。
- 继续禁止:输出通过、覆盖完整、对外交付、完成状态、正式扩池、正式公司池确认,以及 MIR/Omdia/智元/AMR/ASP/BOM/公司强字段升级。
- 下一步要求:若准备 032C,必须单独列出 IFR PDF 页码级抽取、MIR 原始报告、Omdia 原始报告、AMR/ASP/BOM/公司强字段等未闭环缺口和继续降读字段。
"@
$remainingText = Add-Section-IfMissing $remainingText $remainingHeader $remainingBody
Write-Text $remainingPath $remainingText
 
$execLogPath = Join-Path $AuditDocDir "案例执行日志.md"
$execText = Read-Text $execLogPath
$execHeader = "## 2026-07-05 AUDIT-ANA-ROBOT-THREEPIECE-OUTPUT-PREPASS-EVIDENCE-001 承接"
$execBody = @"
承接 reviewer 消息 $ReviewMessageId / $AuditId:NEXT-ROBOT-032B 三件套输出通过前补证包复审结论为有条件通过。
 
- 已同步:next_action_list、remaining_work_plan、result_index、机器人报告索引、三件套文档、case_evidence_map 和 migration_manifest。
- 新增:threepiece_output_prepass_evidence_review_sync_20260705.json,记录允许事项、禁止事项和保留门禁。
- 后续:NEXT-ROBOT-032C 可准备输出通过审核包;仍不得自动视为输出通过、覆盖完整、对外交付、完成状态、正式扩池、正式公司池确认或强字段升级。
"@
$execText = Add-Section-IfMissing $execText $execHeader $execBody
Write-Text $execLogPath $execText
 
$artifactManifestPath = Join-Path $ManifestDir "artifact_manifest.csv"
$artifactRows = @(Import-Csv -LiteralPath $artifactManifestPath)
$changedRel = @(
    (Rel-Path $nextPath),
    (Rel-Path $reviewSyncPath),
    (Rel-Path $evidenceMapPath),
    (Rel-Path $migrationPath),
    (Rel-Path $coreDocs[0]),
    (Rel-Path $coreDocs[1]),
    (Rel-Path $coreDocs[2]),
    (Rel-Path $resultPath),
    (Rel-Path $remainingPath),
    (Rel-Path $execLogPath)
)
$artifactRows = @($artifactRows | Where-Object { $_.run_id -ne $RunId })
foreach ($rel in $changedRel) {
    $meta = Get-Meta $rel
    $artifactRows += [pscustomobject]@{
        case_id = $CaseId
        run_id = $RunId
        batch_id = $BatchId
        artifact_path = $rel
        sha256 = $meta.sha256
        bytes = $meta.bytes
        mtime = $meta.mtime
    }
}
foreach ($row in $artifactRows) {
    if ([string]::IsNullOrWhiteSpace($row.artifact_path)) { continue }
    $full = Join-Path $ProjectRoot ($row.artifact_path -replace "/", "\")
    if (Test-Path -LiteralPath $full) {
        $meta = Get-Meta $row.artifact_path
        $row.sha256 = $meta.sha256
        $row.bytes = $meta.bytes
        $row.mtime = $meta.mtime
    }
}
[System.IO.File]::WriteAllText($artifactManifestPath, (Csv-Text $artifactRows) + "`r`n", $Utf8NoBom)
 
$manifestRows = @(Import-Csv -LiteralPath $artifactManifestPath)
$missing = 0
$emptySha = 0
$mismatch = 0
foreach ($row in $manifestRows) {
    if ([string]::IsNullOrWhiteSpace($row.sha256)) { $emptySha++ }
    $full = Join-Path $ProjectRoot ($row.artifact_path -replace "/", "\")
    if (-not (Test-Path -LiteralPath $full)) {
        $missing++
        continue
    }
    $actual = (Get-FileHash -LiteralPath $full -Algorithm SHA256).Hash.ToLowerInvariant()
    if ($actual -ne $row.sha256) { $mismatch++ }
}
$scanPatterns = '\$\(|\$extract|\$ReviewMessageId|\$AuditId|password|token|secret|123456|连接串|cookie'
$scanHits = 0
foreach ($rel in $changedRel) {
    $full = Join-Path $ProjectRoot ($rel -replace "/", "\")
    if (-not (Test-Path -LiteralPath $full)) { continue }
    $txt = Read-Text $full
    if ($txt -match $scanPatterns) { $scanHits++ }
}
[pscustomobject]@{
    run_id = $RunId
    next_032b_status = (@(Import-Csv -LiteralPath $nextPath) | Where-Object { $_.action_id -eq "NEXT-ROBOT-032B" }).status
    next_032c_status = (@(Import-Csv -LiteralPath $nextPath) | Where-Object { $_.action_id -eq "NEXT-ROBOT-032C" }).status
    manifest_rows = $manifestRows.Count
    manifest_missing = $missing
    manifest_empty_sha = $emptySha
    manifest_mismatch = $mismatch
    changed_artifacts = $changedRel.Count
    scan_hits = $scanHits
}