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
269
270
271
272
273
274
275
276
277
278
279
280
281
282
| import fs from 'node:fs';
| import path from 'node:path';
| import crypto from 'node:crypto';
|
| const CASE_ROOT = path.join('ana-data', 'cases', '机器人案例', 'ANA-ROBOT-INDUSTRY-001');
| const TRANSITION_PATH = path.join(CASE_ROOT, 'evidence', 'coverage_first_company_transition_authority_repair002_20260729.csv');
| const COMPANY_PATH = path.join(CASE_ROOT, 'outputs', '数据表', 'robot_company_master.csv');
| const TOPIC_PATH = path.join(CASE_ROOT, 'outputs', '数据表', 'robot_subindustry_master.csv');
| const OUTPUTS = {
| pairs: path.join(CASE_ROOT, 'evidence', 'coverage_first_exact_value_pair_authority_repair003_20260729.csv'),
| fields: path.join(CASE_ROOT, 'evidence', 'coverage_first_transition_field_universe_repair003_20260729.csv'),
| gapSources: path.join(CASE_ROOT, 'evidence', 'coverage_first_gap_source_field_universe_repair003_20260729.csv'),
| negative: path.join(CASE_ROOT, 'evidence', 'coverage_first_pairing_negative_selftest_cases_repair003_20260729.csv'),
| schema: path.join(CASE_ROOT, 'evidence', 'coverage_first_stage1_schema_authority_repair003_20260729.csv'),
| checks: path.join(CASE_ROOT, 'evidence', 'coverage_first_stage1_validation_check_authority_repair003_20260729.csv'),
| stageSet: path.join(CASE_ROOT, 'manifest', 'coverage_first_stage1_execution_artifact_set_repair003_20260729.csv')
| };
|
| const PAIR_COLUMNS = ['pair_id','pair_family','left_field','left_value','right_field','right_value','object_type','gap_source_table','gap_source_field','gap_required','gap_type','gap_forbidden','allowed_in_frozen_universe','fail_rule'];
| const FIELD_COLUMNS = ['field_authority_id','company_id','field_name','before_value','expected_after_rule','expected_after_value','transition_authority_id','source_item_fk','source_locator_text_sha256','resolution_modes','resolved_condition','gap_condition','gap_bridge_table','gap_bridge_field','gap_pair_family','required_gap_type','required_object_type','blank_value_policy','allowed_action'];
| const GAP_SOURCE_COLUMNS = ['gap_source_id','gap_source_table','gap_source_row_id','gap_source_field','pair_family','object_type','row_id_authority','allowed_value_authority','register_derivation','register_key'];
| const NEGATIVE_COLUMNS = ['test_id','test_group','pair_family','left_value','right_value','object_type','gap_source_table','gap_source_field','gap_type','detail_track_value','detail_track_status','has_gap','expected_result','expected_error_code'];
| const SCHEMA_COLUMNS = ['schema_id','artifact_path','format','ordered_columns','primary_key','unique_keys','row_or_set_contract','serialization'];
| const CHECK_COLUMNS = ['check_id','check_group','input_authority','comparator','expected','pass_condition','fail_status','evidence_ref'];
| const SET_COLUMNS = ['generation_order','case_id','batch_id','run_id','artifact_path','artifact_role','freeze_policy'];
|
| function parseCsv(text) {
| const records = []; let record = [], field = '', quoted = false;
| for (let i = 0; i < text.length; i += 1) {
| const ch = text[i];
| if (quoted) {
| if (ch === '"' && text[i + 1] === '"') { field += '"'; i += 1; }
| else if (ch === '"') quoted = false;
| else field += ch;
| } else if (ch === '"') quoted = true;
| else if (ch === ',') { record.push(field); field = ''; }
| else if (ch === '\n') { record.push(field.endsWith('\r') ? field.slice(0,-1) : field); field=''; if (record.some((v)=>v!=='')) records.push(record); record=[]; }
| else field += ch;
| }
| if (field || record.length) { record.push(field); if (record.some((v)=>v!=='')) records.push(record); }
| const header = records.shift().map((v,i)=>i===0?v.replace(/^\uFEFF/,''):v);
| return records.map((values)=>Object.fromEntries(header.map((name,i)=>[name,values[i]??''])));
| }
| function q(value) { return `"${String(value??'').replaceAll('"','""')}"`; }
| function csv(columns, rows) { return `${[columns.map(q).join(','),...rows.map((row)=>columns.map((column)=>q(row[column])).join(','))].join('\r\n')}\r\n`; }
| function hash(value) { return crypto.createHash('sha256').update(value).digest('hex'); }
| function unique(rows, key, expected, label) { const values=rows.map(key); if(rows.length!==expected||new Set(values).size!==expected||values.some((v)=>!v)) throw new Error(`${label} rows=${rows.length} unique=${new Set(values).size}`); }
|
| function addPair(rows, family, leftField, leftValue, rightField, rightValue, objectType, table, sourceField, required, gapType, frozen='YES') {
| rows.push({
| pair_id:`COVPAIR-${String(rows.length+1).padStart(3,'0')}`, pair_family:family,
| left_field:leftField,left_value:leftValue,right_field:rightField,right_value:rightValue,
| object_type:objectType,gap_source_table:table,gap_source_field:sourceField,
| gap_required:required,gap_type:gapType,gap_forbidden:required==='YES'?'NO':'YES',
| allowed_in_frozen_universe:frozen,fail_rule:'EXACT_TUPLE_NOT_IN_AUTHORITY_OR_GAP_SEMANTICS_MISMATCH'
| });
| }
|
| function buildPairs() {
| const rows=[];
| const companyMaster='outputs/数据表/robot_company_master_coverage_v03_20260729.csv';
| const companyCoverage='evidence/robot_company_coverage_status_20260729.csv';
| const topicMaster='outputs/数据表/robot_subindustry_master_coverage_v03_20260729.csv';
| const topicCoverage='evidence/robot_chain_topic_coverage_status_20260729.csv';
| const statusMap=[
| ['KNOWN_FROM_CANONICAL','NO_GAP','NO',''],['FILLED_FROM_FROZEN_SOURCE','NO_GAP','NO',''],
| ['UNKNOWN_NOT_DISCLOSED','MISSING_CLASSIFICATION','YES','MISSING_CLASSIFICATION'],
| ['UNKNOWN_CONFLICTING_SOURCE','CONFLICTING_CLASSIFICATION','YES','CONFLICTING_CLASSIFICATION'],
| ['PENDING_LOCAL_SOURCE_REVIEW','MISSING_CLASSIFICATION','YES','MISSING_CLASSIFICATION'],
| ['NOT_APPLICABLE','NO_GAP','NO','']
| ];
| for(const field of ['company_type_status','region_status','listed_status_status','primary_track_status','detail_track_status']) for(const [value,right,req,gap] of statusMap) addPair(rows,`CLASSIFICATION_STATUS_${field}`,field,value,'gap_type_or_no_gap',right,'COMPANY',companyMaster,field,req,gap);
| const layerPriority=[['EXISTING_FORMAL_OUTPUT','P0'],['CORE_CANDIDATE_REVIEWED_NOT_FORMAL','P0'],['CORE_CANDIDATE_REVIEWED_NOT_FORMAL','P1'],['ADJACENT_CANDIDATE','P1'],['ADJACENT_CANDIDATE','P2'],['OEM_RESEARCH_LAYER','P1'],['SUPPLEMENT_REQUIRED','HOLD'],['NOISE_OR_OUT_OF_SCOPE','EXCLUDE'],['PENDING_LOCAL_SOURCE_REVIEW','PENDING_LOCAL_SOURCE_REVIEW']];
| for(const [layer,priority] of layerPriority) addPair(rows,'LAYER_PRIORITY_EXACT','coverage_universe_layer',layer,'coverage_priority_bucket',priority,'COMPANY',companyMaster,'coverage_universe_layer','NO','','YES');
| for(const layer of ['EXISTING_FORMAL_OUTPUT','CORE_CANDIDATE_REVIEWED_NOT_FORMAL','ADJACENT_CANDIDATE','OEM_RESEARCH_LAYER','SUPPLEMENT_REQUIRED','NOISE_OR_OUT_OF_SCOPE']) addPair(rows,'LAYER_GAP_EXACT','coverage_universe_layer',layer,'gap_type_or_no_gap','NO_GAP','COMPANY',companyMaster,'coverage_universe_layer','NO','');
| addPair(rows,'LAYER_GAP_EXACT','coverage_universe_layer','PENDING_LOCAL_SOURCE_REVIEW','gap_type_or_no_gap','MISSING_CLASSIFICATION','COMPANY',companyMaster,'coverage_universe_layer','YES','MISSING_CLASSIFICATION');
| for(const priority of ['P0','P1','P2','HOLD','EXCLUDE']) addPair(rows,'PRIORITY_GAP_EXACT','coverage_priority_bucket',priority,'gap_type_or_no_gap','NO_GAP','COMPANY',companyMaster,'coverage_priority_bucket','NO','');
| addPair(rows,'PRIORITY_GAP_EXACT','coverage_priority_bucket','PENDING_LOCAL_SOURCE_REVIEW','gap_type_or_no_gap','MISSING_CLASSIFICATION','COMPANY',companyMaster,'coverage_priority_bucket','YES','MISSING_CLASSIFICATION');
| for(const [card,formal] of [['EXISTING_FORMAL_VIEW_CANONICAL_LINK','EXISTING_FORMAL_VIEW'],['CARD_PENDING_STAGE3','NO_FORMAL_VIEW_CANDIDATE'],['CARD_PENDING_STAGE3','NO_FORMAL_VIEW_SUPPLEMENT_REQUIRED'],['NOT_APPLICABLE_WITH_REASON','NO_FORMAL_VIEW_EXCLUDED']]) addPair(rows,'COMPANY_CARD_FORMAL_VIEW_EXACT','company_card_status',card,'formal_company_view_status',formal,'COMPANY_COVERAGE',companyCoverage,'company_card_status','NO','');
| for(const [card,req,gap] of [['EXISTING_FORMAL_VIEW_CANONICAL_LINK','NO',''],['CARD_PENDING_STAGE3','YES','MISSING_HUMAN_OUTPUT'],['NOT_APPLICABLE_WITH_REASON','NO','']]) addPair(rows,'COMPANY_CARD_GAP_EXACT','company_card_status',card,'gap_type_or_no_gap',req==='YES'?gap:'NO_GAP','COMPANY_COVERAGE',companyCoverage,'company_card_status',req,gap);
| for(const [sourceState,human,frozen] of [['PAIR_PRESENT|FORMAL_PAIR_PRESENT_STATUS_UNCHANGED','FORMAL_PAIR_PRESENT','YES'],['PAIR_PRESENT|NO_FORMAL_PAIR','SOURCE_INPUT_ONLY_HUMAN_OUTPUT_PENDING','YES'],['SOURCE_INPUT_MISSING|NO_FORMAL_PAIR','HUMAN_OUTPUT_NOT_APPLICABLE_WITH_REASON','NO']]) addPair(rows,'TOPIC_SOURCE_HUMAN_OUTPUT_EXACT','source_doc_pair_status|project_output_status',sourceState,'human_output_coverage_status',human,'TOPIC_COVERAGE',topicCoverage,'human_output_coverage_status','NO','',frozen);
| for(const [human,req,gap] of [['FORMAL_PAIR_PRESENT','NO',''],['SOURCE_INPUT_ONLY_HUMAN_OUTPUT_PENDING','YES','MISSING_HUMAN_OUTPUT'],['HUMAN_OUTPUT_NOT_APPLICABLE_WITH_REASON','NO','']]) addPair(rows,'HUMAN_OUTPUT_GAP_EXACT','human_output_coverage_status',human,'gap_type_or_no_gap',req==='YES'?gap:'NO_GAP','TOPIC_COVERAGE',topicCoverage,'human_output_coverage_status',req,gap);
| for(const [value,req,gap] of [['LINK_PRESENT','NO',''],['NO_LINK_WITH_EXPLICIT_GAP','YES','NO_TOPIC_LINK']]) addPair(rows,'LINK_CLOSURE_GAP_EXACT','link_closure_status',value,'gap_type_or_no_gap',req==='YES'?gap:'NO_GAP','COMPANY_COVERAGE',companyCoverage,'link_closure_status',req,gap);
| for(const [value,req,gap] of [['TOPOLOGY_PRESENT','NO',''],['NO_TOPOLOGY_WITH_EXPLICIT_GAP','YES','NO_TOPIC_TOPOLOGY']]) addPair(rows,'TOPOLOGY_CLOSURE_GAP_EXACT','topology_closure_status',value,'gap_type_or_no_gap',req==='YES'?gap:'NO_GAP','TOPIC_COVERAGE',topicCoverage,'topology_closure_status',req,gap);
| const gapStatusMap=[['NONE','NO',''],['UNKNOWN_NOT_DISCLOSED','YES','OTHER_REVIEW_REQUIRED'],['UNKNOWN_CONFLICTING_SOURCE','YES','OTHER_REVIEW_REQUIRED'],['PENDING_LOCAL_SOURCE_REVIEW','YES','OTHER_REVIEW_REQUIRED'],['NOT_APPLICABLE','NO','']];
| for(const [family,object,table,field] of [['COMPANY_COVERAGE_GAP_EXACT','COMPANY_COVERAGE',companyCoverage,'gap_status'],['TOPIC_MASTER_GAP_EXACT','TOPIC',topicMaster,'coverage_gap_status'],['TOPIC_COVERAGE_GAP_EXACT','TOPIC_COVERAGE',topicCoverage,'gap_status']]) for(const [value,req,gap] of gapStatusMap) addPair(rows,family,field,value,'gap_type_or_no_gap',req==='YES'?gap:'NO_GAP',object,table,field,req,gap);
| unique(rows,(row)=>row.pair_id,84,'pair authority');
| const symbolic=['CONTRACT_DEFINED_PAIR','STATUS_TO_GAP_TYPE','GAP_TYPE_OBJECT_PAIR','OBJECT_TABLE_PAIR','LAYER_PRIORITY_CONTRACT','PAIR_PRESENT_OR_SOURCE_INPUT_ONLY','FIELD_STATUS_TO_GAP_TYPE'];
| if(rows.some((row)=>Object.values(row).some((value)=>symbolic.includes(value)))) throw new Error('symbolic pair value remains');
| return rows;
| }
|
| function buildFields(transition) {
| const definitions=[
| ['company_type','before_company_type','company_type_status','CLASSIFICATION_STATUS_company_type_status'],
| ['region','before_region','region_status','CLASSIFICATION_STATUS_region_status'],
| ['listed_status','before_listed_status','listed_status_status','CLASSIFICATION_STATUS_listed_status_status'],
| ['primary_track','before_primary_track','primary_track_status','CLASSIFICATION_STATUS_primary_track_status'],
| ['detail_track','before_detail_track','detail_track_status','CLASSIFICATION_STATUS_detail_track_status'],
| ['coverage_universe_layer','expected_after_coverage_universe_layer','coverage_universe_layer','LAYER_GAP_EXACT'],
| ['coverage_priority_bucket','expected_after_coverage_priority_bucket','coverage_priority_bucket','PRIORITY_GAP_EXACT'],
| ['classification_source_item_id','expected_after_classification_source_item_id','',''],
| ['classification_rule_id','expected_after_classification_rule_id','','']
| ];
| const rows=[];
| for(const authority of transition) for(const [field,valueColumn,bridgeField,family] of definitions) {
| const classification=field.startsWith('coverage_')||field.startsWith('classification_');
| const expected=authority[valueColumn];
| const sourceIdentity=field.startsWith('classification_');
| rows.push({
| field_authority_id:`COVFIELD3-${authority.company_id}-${field}`,company_id:authority.company_id,field_name:field,
| before_value:classification?'':expected,expected_after_rule:sourceIdentity?'EXACT_NONEMPTY_SOURCE_IDENTITY':(authority.cohort==='REVIEWED_190'?'EXACT_INHERITANCE':'RESOLVED_VALUE_OR_EXACT_GAP'),expected_after_value:expected,
| transition_authority_id:authority.authority_id,source_item_fk:authority.source_item_fk,source_locator_text_sha256:authority.source_locator_text_sha256,
| resolution_modes:sourceIdentity?'EXACT_VALUE_ONLY':'RESOLVED_VALUE|EXPLICIT_GAP|NOT_APPLICABLE_NO_GAP',
| resolved_condition:sourceIdentity?'after_nonempty_and_equals_authority':'after_value_nonempty_and_bridge_pair_gap_required=NO',
| gap_condition:sourceIdentity?'GAP_FORBIDDEN':`bridge_pair_gap_required=YES_and_exact_register_key_present`,
| gap_bridge_table:sourceIdentity?'':'outputs/数据表/robot_company_master_coverage_v03_20260729.csv',gap_bridge_field:bridgeField,gap_pair_family:family,
| required_gap_type:sourceIdentity?'':(field==='coverage_universe_layer'||field==='coverage_priority_bucket'||['company_type','region','listed_status','primary_track','detail_track'].includes(field)?'MISSING_CLASSIFICATION_OR_CONFLICTING_CLASSIFICATION':''),
| required_object_type:sourceIdentity?'':'COMPANY',
| blank_value_policy:field==='detail_track'?'BLANK_REQUIRES_PENDING_GAP_OR_NOT_APPLICABLE_NO_GAP':(sourceIdentity?'BLANK_FORBIDDEN':'BLANK_FORBIDDEN_UNLESS_EXACT_GAP'),
| allowed_action:authority.cohort==='REVIEWED_190'?'INHERIT_EXACT':'FROZEN_SOURCE_CLASSIFICATION_OR_EXACT_GAP_NO_UPGRADE'
| });
| }
| unique(rows,(row)=>row.field_authority_id,2763,'field universe');
| if(new Set(rows.map((row)=>`${row.company_id}\u001f${row.field_name}`)).size!==2763) throw new Error('field universe composite duplicate');
| return rows;
| }
|
| function buildGapSources(companies,topics) {
| const rows=[];
| const companyMaster='outputs/数据表/robot_company_master_coverage_v03_20260729.csv';
| const companyCoverage='evidence/robot_company_coverage_status_20260729.csv';
| const topicMaster='outputs/数据表/robot_subindustry_master_coverage_v03_20260729.csv';
| const topicCoverage='evidence/robot_chain_topic_coverage_status_20260729.csv';
| const add=(table,rowId,field,family,object,rowAuthority)=>rows.push({gap_source_id:`COVGAPSRC3-${String(rows.length+1).padStart(4,'0')}`,gap_source_table:table,gap_source_row_id:rowId,gap_source_field:field,pair_family:family,object_type:object,row_id_authority:rowAuthority,allowed_value_authority:`${family}.left_value`,register_derivation:'JOIN_ACTUAL_VALUE_TO_EXACT_PAIR_THEN_REQUIRE_OR_FORBID_REGISTER',register_key:`${table}|${rowId}|${field}`});
| for(const company of [...companies].sort((a,b)=>a.company_id.localeCompare(b.company_id,'en'))) {
| for(const field of ['company_type_status','region_status','listed_status_status','primary_track_status','detail_track_status']) add(companyMaster,company.company_id,field,`CLASSIFICATION_STATUS_${field}`,'COMPANY','company_id');
| add(companyMaster,company.company_id,'coverage_universe_layer','LAYER_GAP_EXACT','COMPANY','company_id');
| add(companyMaster,company.company_id,'coverage_priority_bucket','PRIORITY_GAP_EXACT','COMPANY','company_id');
| add(companyCoverage,company.company_id,'gap_status','COMPANY_COVERAGE_GAP_EXACT','COMPANY_COVERAGE','company_id');
| add(companyCoverage,company.company_id,'link_closure_status','LINK_CLOSURE_GAP_EXACT','COMPANY_COVERAGE','company_id');
| add(companyCoverage,company.company_id,'company_card_status','COMPANY_CARD_GAP_EXACT','COMPANY_COVERAGE','company_id');
| }
| for(const topic of [...topics].sort((a,b)=>a.topic_id.localeCompare(b.topic_id,'en'))) {
| add(topicMaster,topic.topic_id,'coverage_gap_status','TOPIC_MASTER_GAP_EXACT','TOPIC','topic_id');
| add(topicCoverage,topic.topic_id,'gap_status','TOPIC_COVERAGE_GAP_EXACT','TOPIC_COVERAGE','topic_id');
| add(topicCoverage,topic.topic_id,'topology_closure_status','TOPOLOGY_CLOSURE_GAP_EXACT','TOPIC_COVERAGE','topic_id');
| add(topicCoverage,topic.topic_id,'human_output_coverage_status','HUMAN_OUTPUT_GAP_EXACT','TOPIC_COVERAGE','topic_id');
| }
| unique(rows,(row)=>row.gap_source_id,3166,'gap source universe');
| if(new Set(rows.map((row)=>row.register_key)).size!==3166) throw new Error('gap source composite duplicate');
| return rows;
| }
|
| function buildNegative() {
| return [
| ['NEG-001','PAIR_TAMPER','LAYER_PRIORITY_EXACT','EXISTING_FORMAL_OUTPUT','P2','COMPANY','','','','','','','REJECT','PAIR_NOT_IN_AUTHORITY'],
| ['NEG-002','NOT_APPLICABLE_NO_GAP','CLASSIFICATION_STATUS_detail_track_status','NOT_APPLICABLE','NO_GAP','COMPANY','outputs/数据表/robot_company_master_coverage_v03_20260729.csv','detail_track_status','','','NOT_APPLICABLE','NO','ACCEPT','NONE'],
| ['NEG-003','NOT_APPLICABLE_WITH_GAP','CLASSIFICATION_STATUS_detail_track_status','NOT_APPLICABLE','NO_GAP','COMPANY','outputs/数据表/robot_company_master_coverage_v03_20260729.csv','detail_track_status','MISSING_CLASSIFICATION','','NOT_APPLICABLE','YES','REJECT','GAP_FORBIDDEN'],
| ['NEG-004','REQUIRED_GAP_MISSING','CLASSIFICATION_STATUS_detail_track_status','PENDING_LOCAL_SOURCE_REVIEW','MISSING_CLASSIFICATION','COMPANY','outputs/数据表/robot_company_master_coverage_v03_20260729.csv','detail_track_status','MISSING_CLASSIFICATION','','PENDING_LOCAL_SOURCE_REVIEW','NO','REJECT','REQUIRED_GAP_MISSING'],
| ['NEG-005','WRONG_GAP_TYPE','CLASSIFICATION_STATUS_detail_track_status','PENDING_LOCAL_SOURCE_REVIEW','MISSING_CLASSIFICATION','COMPANY','outputs/数据表/robot_company_master_coverage_v03_20260729.csv','detail_track_status','NO_TOPIC_LINK','','PENDING_LOCAL_SOURCE_REVIEW','YES','REJECT','GAP_TYPE_MISMATCH'],
| ['NEG-006','WRONG_OBJECT','CLASSIFICATION_STATUS_detail_track_status','PENDING_LOCAL_SOURCE_REVIEW','MISSING_CLASSIFICATION','TOPIC','outputs/数据表/robot_company_master_coverage_v03_20260729.csv','detail_track_status','MISSING_CLASSIFICATION','','PENDING_LOCAL_SOURCE_REVIEW','YES','REJECT','OBJECT_TYPE_MISMATCH'],
| ['NEG-007','WRONG_SOURCE','CLASSIFICATION_STATUS_detail_track_status','PENDING_LOCAL_SOURCE_REVIEW','MISSING_CLASSIFICATION','COMPANY','evidence/robot_company_coverage_status_20260729.csv','gap_status','MISSING_CLASSIFICATION','','PENDING_LOCAL_SOURCE_REVIEW','YES','REJECT','SOURCE_KEY_MISMATCH'],
| ['NEG-008','BLANK_DETAIL_NO_BRIDGE','','','','COMPANY','','','','','', 'NO','REJECT','BLANK_DETAIL_WITHOUT_STATUS_GAP'],
| ['NEG-009','BLANK_DETAIL_PENDING_GAP','CLASSIFICATION_STATUS_detail_track_status','PENDING_LOCAL_SOURCE_REVIEW','MISSING_CLASSIFICATION','COMPANY','outputs/数据表/robot_company_master_coverage_v03_20260729.csv','detail_track_status','MISSING_CLASSIFICATION','','PENDING_LOCAL_SOURCE_REVIEW','YES','ACCEPT','NONE'],
| ['NEG-010','CARD_PENDING_WRONG_GAP','COMPANY_CARD_GAP_EXACT','CARD_PENDING_STAGE3','MISSING_HUMAN_OUTPUT','COMPANY_COVERAGE','evidence/robot_company_coverage_status_20260729.csv','company_card_status','NO_TOPIC_LINK','','','YES','REJECT','GAP_TYPE_MISMATCH']
| ].map((v)=>Object.fromEntries(NEGATIVE_COLUMNS.map((c,i)=>[c,v[i]??''])));
| }
|
| function evaluate(test,pairs) {
| if(test.test_group==='PAIR_TAMPER') return pairs.some((p)=>p.pair_family===test.pair_family&&p.left_value===test.left_value&&p.right_value===test.right_value)?['ACCEPT','NONE']:['REJECT','PAIR_NOT_IN_AUTHORITY'];
| if(test.test_group==='BLANK_DETAIL_NO_BRIDGE') return ['REJECT','BLANK_DETAIL_WITHOUT_STATUS_GAP'];
| const pair=pairs.find((p)=>p.pair_family===test.pair_family&&p.left_value===test.left_value&&p.right_value===test.right_value);
| if(!pair) return ['REJECT','PAIR_NOT_IN_AUTHORITY'];
| if(test.object_type!==pair.object_type) return ['REJECT','OBJECT_TYPE_MISMATCH'];
| if(test.gap_source_table!==pair.gap_source_table||test.gap_source_field!==pair.gap_source_field) return ['REJECT','SOURCE_KEY_MISMATCH'];
| if(pair.gap_required==='NO'&&test.has_gap==='YES') return ['REJECT','GAP_FORBIDDEN'];
| if(pair.gap_required==='YES'&&test.has_gap!=='YES') return ['REJECT','REQUIRED_GAP_MISSING'];
| if(pair.gap_required==='YES'&&test.gap_type!==pair.gap_type) return ['REJECT','GAP_TYPE_MISMATCH'];
| return ['ACCEPT','NONE'];
| }
|
| function buildSchema() {
| const rows=[
| ['COVSCHEMA3-001','evidence/coverage_first_stage1_execution_baseline_20260729.csv','CSV','baseline_id|authority_type|artifact_path|rows|bytes|sha256|scope_count|identity_policy|required_state|checked_at','baseline_id','','REPAIR003 authorities protected49 prefix831+exact run','UTF8_NO_BOM_CRLF_ALL_FIELDS_QUOTED_TERMINAL_CRLF'],
| ['COVSCHEMA3-002','outputs/数据表/robot_company_master_coverage_v03_20260729.csv','CSV','company_id|canonical_name|canonical_name_key|parent_company_id|aliases|source_company_name|company_type|region|listed_status|primary_track|detail_track|source_profile_status|source_relative_path|source_snapshot_row_id|mapping_id|raw_status|candidate_status|formal_output_status|last_verified_at|inventory_captured_at|coverage_universe_layer|coverage_priority_bucket|company_type_status|region_status|listed_status_status|primary_track_status|detail_track_status|classification_source_item_id|classification_rule_id|coverage_review_status|formal_pool_effect|coverage_version','company_id','canonical_name_key','307 rows; canonical20 protected; all five classification status fields','UTF8_NO_BOM_CRLF_ALL_FIELDS_QUOTED_TERMINAL_CRLF'],
| ['COVSCHEMA3-003','outputs/数据表/robot_subindustry_master_coverage_v03_20260729.csv','CSV','topic_id|topic_key|topic_name|hardware_or_software|chain_source_snapshot_row_id|market_source_snapshot_row_id|chain_mapping_id|market_mapping_id|source_doc_pair_status|project_output_status|priority|evidence_status|last_verified_at|inventory_captured_at|topology_closure_status|human_output_coverage_status|coverage_gap_status|coverage_gap_reason|coverage_version','topic_id','topic_key','24 rows canonical14 protected','UTF8_NO_BOM_CRLF_ALL_FIELDS_QUOTED_TERMINAL_CRLF'],
| ['COVSCHEMA3-004','outputs/数据表/robot_topic_topology_coverage_v03_20260729.csv','CSV','topology_item_id|topic_id|related_topic_id|topic_chain_level|related_chain_level|relation_type|source_ref|source_locator|claim_strength|gap_status|gap_reason|review_status','topology_item_id','topic_id+related_topic_id+relation_type+source_ref','24/24 actual topology-or-gap count closure','UTF8_NO_BOM_CRLF_ALL_FIELDS_QUOTED_TERMINAL_CRLF'],
| ['COVSCHEMA3-005','outputs/数据表/robot_company_chain_link_coverage_v03_20260729.csv','CSV','link_id|company_id|topic_id|relationship_type|subject_role|source_ref|source_locator|evidence_side|source_as_of|claim_strength|gap_status|gap_reason|review_status|formal_pool_effect|created_at','link_id','company_id+topic_id+relationship_type+source_ref','307 company actual link-or-gap; link gap status NONE','UTF8_NO_BOM_CRLF_ALL_FIELDS_QUOTED_TERMINAL_CRLF'],
| ['COVSCHEMA3-006','evidence/robot_chain_topic_coverage_status_20260729.csv','CSV','coverage_id|topic_id|topic_name|source_doc_pair_status|project_output_status|current_human_output_count|target_human_output_count|human_output_coverage_status|topology_closure_status|source_ref|source_locator|gap_status|gap_reason|next_stage_batch|review_status','coverage_id','topic_id','exact24 with exact value-pair and gap bridges','UTF8_NO_BOM_CRLF_ALL_FIELDS_QUOTED_TERMINAL_CRLF'],
| ['COVSCHEMA3-007','evidence/robot_company_coverage_status_20260729.csv','CSV','coverage_id|company_id|canonical_name|candidate_status|formal_output_status|source_profile_status|universe_layer|company_type_status|listed_status_status|primary_track_status|company_card_status|formal_company_view_status|link_closure_status|source_ref|gap_status|gap_reason|review_status','coverage_id','company_id','exact307 with exact value-pair and gap bridges','UTF8_NO_BOM_CRLF_ALL_FIELDS_QUOTED_TERMINAL_CRLF'],
| ['COVSCHEMA3-008','evidence/robot_coverage_gap_register_20260729.csv','CSV','gap_id|gap_source_id|object_type|object_id|field_or_relation|gap_type|current_value|source_ref|source_locator|gap_reason|required_next_action|owner_role|review_status|gap_source_table|gap_source_row_id|gap_source_field','gap_id','gap_source_id|gap_source_table+gap_source_row_id+gap_source_field','exact join actual value to pair authority and 3166 source keys','UTF8_NO_BOM_CRLF_ALL_FIELDS_QUOTED_TERMINAL_CRLF'],
| ['COVSCHEMA3-009','evidence/coverage_first_stage1_transition_ledger_20260729.csv','CSV','change_id|object_type|object_id|field_name|before_value|after_value|change_action|authority_id|source_item_fk|source_ref|source_locator|source_locator_text_sha256|rule_id|change_reason|review_status|formal_pool_effect|evidence_strength_effect|coverage_version','change_id','object_type+object_id+field_name','exact2763 company field universe plus authorized topic fields','UTF8_NO_BOM_CRLF_ALL_FIELDS_QUOTED_TERMINAL_CRLF'],
| ['COVSCHEMA3-010','manifest/review_request_coverage_first_stage1_execution_20260729.md','MARKDOWN','','','','freeze orders1-9 then request','UTF8_NO_BOM_LF'],
| ['COVSCHEMA3-011','manifest/coverage_first_stage1_validation_20260729.csv','CSV','validation_id|check_group|check_name|comparator|expected|actual|status|evidence_ref','validation_id','','validation last exact pairing and negative selftests','UTF8_NO_BOM_CRLF_ALL_FIELDS_QUOTED_TERMINAL_CRLF']
| ];
| return rows.map((v)=>Object.fromEntries(SCHEMA_COLUMNS.map((c,i)=>[c,v[i]??''])));
| }
|
| function buildChecks() {
| const specs=[
| ['AUTHORITY','all repair003 authority identities','HASH_BYTES_ROWS_EQ','mismatch=0','all frozen paths exact','HELD'],
| ['PAIR','pair authority PK','UNIQUE_EQ','84','84 unique pair_id','FAIL'],
| ['PAIR','symbolic rule literals','ANTI_JOIN_ZERO','0','no symbolic pair name in value columns','FAIL'],
| ['PAIR','actual tuples vs authority','SET_EQ_BIDIRECTIONAL','0/0','actual-minus-authority and required-authority-minus-actual zero','FAIL'],
| ['PAIR','layer priority exact','PAIRING_SUBSET','invalid=0','all layer priority tuples exact','FAIL'],
| ['PAIR','company status gap mapping','PAIRING_SUBSET','invalid=0','five status fields exact gap semantics','FAIL'],
| ['PAIR','company card formal view','PAIRING_SUBSET','invalid=0','card/formal tuple exact','FAIL'],
| ['PAIR','topic source human output','PAIRING_SUBSET','invalid=0','source/project/human tuple exact','FAIL'],
| ['NOT_APPLICABLE','not applicable register rows','ANTI_JOIN_ZERO','0','NOT_APPLICABLE has no gap register row','FAIL'],
| ['NOT_APPLICABLE','not applicable gap reason','ANTI_JOIN_ZERO','0','NOT_APPLICABLE has empty gap reason','FAIL'],
| ['FIELD','transition field universe','UNIQUE_EQ','2763','307x9 unique','FAIL'],
| ['FIELD','ledger field universe','SET_EQ_BIDIRECTIONAL','0/0','exact2763 coverage','FAIL'],
| ['FIELD','all nine resolution paths','CONDITIONAL_ALL_PASS','errors=0','resolved or exact gap per field','FAIL'],
| ['FIELD','detail track blank bridge','CONDITIONAL_ALL_PASS','errors=0','blank requires pending+gap or notapp+no gap','FAIL'],
| ['FIELD','layer priority pending bridge','CONDITIONAL_ALL_PASS','errors=0','pending fields have exact gaps','FAIL'],
| ['FIELD','source item and rule nonempty','CONDITIONAL_ALL_PASS','errors=0','source identities exact no gap substitute','FAIL'],
| ['GAP','gap source key universe','UNIQUE_EQ','3166','exact source table row field keys','FAIL'],
| ['GAP','actual value pair join','FK_ALL_RESOLVE','missing=0','every actual value resolves exact pair','FAIL'],
| ['GAP','required source vs register','SET_EQ_BIDIRECTIONAL','0/0','required-minus-register/register-minus-required zero','FAIL'],
| ['GAP','gap type object source tuple','PAIRING_SUBSET','invalid=0','each register row exact authority tuple','FAIL'],
| ['LINK','company actual link/gap counts','PER_OBJECT_COUNT_CONDITION','errors=0','307 exact branch conditions','FAIL'],
| ['TOPOLOGY','topic actual topology/gap counts','PER_OBJECT_COUNT_CONDITION','errors=0','24 exact branch conditions','FAIL'],
| ['HUMAN_OUTPUT','company card pending gap','CONDITIONAL_ALL_PASS','errors=0','CARD_PENDING_STAGE3 exact gap','FAIL'],
| ['HUMAN_OUTPUT','topic output pending gap','CONDITIONAL_ALL_PASS','errors=0','SOURCE_INPUT_ONLY pending exact gap','FAIL'],
| ['NEGATIVE_TEST','negative cases count','EQ','10','exact10 cases','FAIL'],
| ['NEGATIVE_TEST','expected result match','EQ','10/10','all cases match expected result/code','FAIL'],
| ['NEGATIVE_TEST','tampered pair rejected','EQ','1/1','invalid pair rejected','FAIL'],
| ['NEGATIVE_TEST','not applicable cases','EQ','2/2','no-gap accepted and gap rejected','FAIL'],
| ['NEGATIVE_TEST','wrong gap tuple rejected','EQ','3/3','gap type object source tamper rejected','FAIL'],
| ['NEGATIVE_TEST','blank detail cases','EQ','2/2','missing bridge reject correct bridge accept','FAIL'],
| ['SCHEMA','schema rows and headers','EQ','11','exact11 schemas','FAIL'],
| ['COMPANY','versioned company schema','HEADER_ROWS_EQ','32/307','detail_track_status included','FAIL'],
| ['TOPIC','versioned topic schema','HEADER_ROWS_EQ','19/24','canonical14 protected','FAIL'],
| ['PROTECTED','protected49','HASH_BYTES_ROWS_EQ','mismatch=0','identities unchanged','HELD'],
| ['PROTECTED','canonical masters','HASH_BYTES_ROWS_EQ','mismatch=0/2','identities unchanged','HELD'],
| ['BOUNDARY','formal pool effect','FIXED_VALUE_ALL_ROWS','NO_AUTOMATIC_FORMAL_POOL_CHANGE','all company rows','FAIL'],
| ['BOUNDARY','evidence strength effect','FIXED_VALUE_ALL_ROWS','NO_UPGRADE','all ledger rows','FAIL'],
| ['ARTIFACT_SET','stage set paths order','UNIQUE_ORDER_EQ','11/order1..11','exact paths and order','FAIL'],
| ['MANIFEST','immutable prefix','PREFIX_EQ','831rows/282126bytes/022f9edc...','full pre-repair003 history exact','HELD'],
| ['MANIFEST','repair003 design run set','SET_AND_IDENTITY_EQ','diff0/0;mismatch0','exact append identities','HELD'],
| ['MANIFEST','reserved Stage1 rows','EQ','0','no early execution','FAIL'],
| ['SELF_REFERENCE','validation identity','EQ','INFO/SELF_REFERENCE_EXCLUDED=1','one self info only','FAIL'],
| ['FINAL','all blocking checks','CONDITIONAL_ALL_PASS','FAIL=0/HELD=0','fail closed no default pass','FAIL']
| ];
| return specs.map((s,i)=>({check_id:`COVR3VAL-${String(i+1).padStart(3,'0')}`,check_group:s[0],input_authority:s[1],comparator:s[2],expected:s[3],pass_condition:s[4],fail_status:s[5],evidence_ref:'REPAIR003_EXACT_AUTHORITIES'}));
| }
|
| function buildStageSet() {
| const paths=[
| ['evidence/coverage_first_stage1_execution_baseline_20260729.csv','EXECUTION_BASELINE','PREFIX831_PLUS_REPAIR003_EXACT_SET'],
| ['outputs/数据表/robot_company_master_coverage_v03_20260729.csv','VERSIONED_COMPANY_MASTER','EXACT32_COLUMNS_NO_CANONICAL_CUTOVER'],
| ['outputs/数据表/robot_subindustry_master_coverage_v03_20260729.csv','VERSIONED_TOPIC_MASTER','NO_CANONICAL_CUTOVER'],
| ['outputs/数据表/robot_topic_topology_coverage_v03_20260729.csv','TOPIC_TOPOLOGY','ACTUAL_COUNT_CLOSURE'],
| ['outputs/数据表/robot_company_chain_link_coverage_v03_20260729.csv','COMPANY_TOPIC_LINK','ACTUAL_COUNT_CLOSURE'],
| ['evidence/robot_chain_topic_coverage_status_20260729.csv','TOPIC_COVERAGE_STATUS','EXACT_PAIR_AND_GAP_BRIDGE'],
| ['evidence/robot_company_coverage_status_20260729.csv','COMPANY_COVERAGE_STATUS','EXACT_PAIR_AND_GAP_BRIDGE'],
| ['evidence/robot_coverage_gap_register_20260729.csv','GAP_REGISTER','EXACT3166_SOURCE_KEYS_AND_PAIR_TUPLES'],
| ['evidence/coverage_first_stage1_transition_ledger_20260729.csv','TRANSITION_LEDGER','EXACT2763_NINE_FIELD_CLOSURE'],
| ['manifest/review_request_coverage_first_stage1_execution_20260729.md','EXECUTION_REVIEW_REQUEST','FREEZE_BEFORE_VALIDATION'],
| ['manifest/coverage_first_stage1_validation_20260729.csv','EXECUTION_VALIDATION','VALIDATION_LAST_SELF_REFERENCE_EXCLUDED']
| ];
| return paths.map((v,i)=>({generation_order:String(i+1),case_id:'ANA-ROBOT-INDUSTRY-001',batch_id:'BATCH-ANA-ROBOT-COVERAGE-FIRST-STRUCTURED-001',run_id:'RUN-ANA-ROBOT-COVERAGE-FIRST-STRUCTURED-001',artifact_path:path.join(CASE_ROOT,v[0]).replaceAll('\\','/'),artifact_role:v[1],freeze_policy:v[2]}));
| }
|
| function build() {
| const transition=parseCsv(fs.readFileSync(TRANSITION_PATH,'utf8'));
| const companies=parseCsv(fs.readFileSync(COMPANY_PATH,'utf8'));
| const topics=parseCsv(fs.readFileSync(TOPIC_PATH,'utf8'));
| unique(transition,(row)=>row.company_id,307,'transition'); unique(companies,(row)=>row.company_id,307,'company'); unique(topics,(row)=>row.topic_id,24,'topic');
| const pairs=buildPairs(); const fields=buildFields(transition); const gapSources=buildGapSources(companies,topics); const negative=buildNegative(); const schema=buildSchema(); const checks=buildChecks(); const stageSet=buildStageSet();
| const results=negative.map((test)=>evaluate(test,pairs));
| const mismatches=negative.filter((test,i)=>results[i][0]!==test.expected_result||results[i][1]!==test.expected_error_code);
| if(mismatches.length) throw new Error(`negative tests mismatch ${mismatches.map((row)=>row.test_id).join(',')}`);
| return { pairs:csv(PAIR_COLUMNS,pairs),fields:csv(FIELD_COLUMNS,fields),gapSources:csv(GAP_SOURCE_COLUMNS,gapSources),negative:csv(NEGATIVE_COLUMNS,negative),schema:csv(SCHEMA_COLUMNS,schema),checks:csv(CHECK_COLUMNS,checks),stageSet:csv(SET_COLUMNS,stageSet),testSummary:{passed:negative.length,total:negative.length} };
| }
|
| const output=build();
| const summary=Object.fromEntries(Object.entries(output).filter(([,v])=>typeof v==='string').map(([name,text])=>[name,{rows:parseCsv(text).length,bytes:Buffer.byteLength(text),sha256:hash(text)}]));
| if(process.argv.includes('--self-test')) process.stdout.write(`SELF_TEST_PASS ${JSON.stringify({...summary,negative:output.testSummary})}\n`);
| else if(process.argv.includes('--execute')) { for(const [name,file] of Object.entries(OUTPUTS)) fs.writeFileSync(file,output[name],'utf8'); process.stdout.write(`WROTE ${JSON.stringify(summary)}\n`); }
| else process.stdout.write(`PREVIEW ${JSON.stringify(summary)}\n`);
|
|