@@ -8,7 +8,7 @@ const source = await readFile(new URL("./experiment-notes.ts", import.meta.url),
88const { outputText } = ts . transpileModule ( source , {
99 compilerOptions : { module : ts . ModuleKind . ESNext , target : ts . ScriptTarget . ES2022 } ,
1010} ) ;
11- const { describeRobustness, formatMetricValue } = await import (
11+ const { describeReview , describeRobustness, formatMetricValue } = await import (
1212 `data:text/javascript;charset=utf-8,${ encodeURIComponent ( outputText ) } `
1313) ;
1414
@@ -95,6 +95,87 @@ test("absent field (runs before sandboxing / sim nodes) renders nothing about th
9595 assert . deepEqual ( describeRobustness ( undefined ) , { kind : "absent" } ) ;
9696} ) ;
9797
98+ // ── 独立审稿(契约 review / robustness.review,fixture experiment-summary.5) ──
99+
100+ /** fixture.5 的实验代码审稿:一轮通过,一条 minor 意见,复跑一致。 */
101+ function acceptedReview ( ) {
102+ return {
103+ executed : true ,
104+ verdict : "accept" ,
105+ rounds : 1 ,
106+ findings : [
107+ { id : "R1" , severity : "minor" , location : "experiment.py:12" , issue : "随机种子写死在脚本里,建议改为常量集中管理" , fix_hint : "抽成 SEED 常量" } ,
108+ ] ,
109+ blockers : 0 ,
110+ summary : "实现忠实于方案 A,指标口径与方案一致,可复现" ,
111+ stalemate : false ,
112+ rerun_consistent : true ,
113+ reason : "" ,
114+ } ;
115+ }
116+
117+ /** fixture.5 的检验脚本审稿:两轮后僵持,一条 blocker + 一条 minor。 */
118+ function stalemateReview ( ) {
119+ return {
120+ executed : true ,
121+ verdict : "reject" ,
122+ rounds : 2 ,
123+ findings : [
124+ { id : "R1" , severity : "blocker" , location : "robustness.py:perturb()" , issue : "扰动只作用在训练集,评估集未同步扰动,敏感性数值偏乐观" , fix_hint : "扰动后重新切分并同时评估" } ,
125+ { id : "R2" , severity : "minor" , location : "" , issue : "阈值 0.2 未说明来源" , fix_hint : "" } ,
126+ ] ,
127+ blockers : 1 ,
128+ summary : "扰动实现有缺陷,敏感性结论不能采信" ,
129+ stalemate : true ,
130+ rerun_consistent : true ,
131+ reason : "审稿 2 轮后仍有阻断性意见未解决" ,
132+ } ;
133+ }
134+
135+ test ( "accepted review: rounds, every finding (location-prefixed), rerun state, reviewer summary" , ( ) => {
136+ assert . deepEqual ( describeReview ( acceptedReview ( ) ) , {
137+ kind : "accepted" ,
138+ rounds : 1 ,
139+ findings : [
140+ { severity : "minor" , severityLabel : "次要" , text : "experiment.py:12:随机种子写死在脚本里,建议改为常量集中管理" } ,
141+ ] ,
142+ summary : "实现忠实于方案 A,指标口径与方案一致,可复现" ,
143+ rerun : "consistent" ,
144+ } ) ;
145+ } ) ;
146+
147+ test ( "stalemate review: only blockers are listed (they are what G3 and the paper must carry)" , ( ) => {
148+ assert . deepEqual ( describeReview ( stalemateReview ( ) ) , {
149+ kind : "stalemate" ,
150+ rounds : 2 ,
151+ blockers : 1 ,
152+ findings : [
153+ { severity : "blocker" , severityLabel : "阻断" , text : "robustness.py:perturb():扰动只作用在训练集,评估集未同步扰动,敏感性数值偏乐观" } ,
154+ ] ,
155+ summary : "扰动实现有缺陷,敏感性结论不能采信" ,
156+ reason : "审稿 2 轮后仍有阻断性意见未解决" ,
157+ rerun : "consistent" ,
158+ } ) ;
159+ } ) ;
160+
161+ test ( "rerun state: null → not_run, false → inconsistent; blank location keeps the bare issue" , ( ) => {
162+ const noRerun = describeReview ( { ...acceptedReview ( ) , rerun_consistent : null , findings : [
163+ { id : "R1" , severity : "major" , location : " " , issue : "只报了 rmse" , fix_hint : "" } ,
164+ ] } ) ;
165+ assert . equal ( noRerun . rerun , "not_run" ) ;
166+ assert . deepEqual ( noRerun . findings , [ { severity : "major" , severityLabel : "主要" , text : "只报了 rmse" } ] ) ;
167+ assert . equal ( describeReview ( { ...stalemateReview ( ) , rerun_consistent : false } ) . rerun , "inconsistent" ) ;
168+ } ) ;
169+
170+ test ( "skipped review surfaces the node's reason; absent field renders nothing" , ( ) => {
171+ assert . deepEqual (
172+ describeReview ( { executed : false , verdict : null , rounds : 0 , findings : [ ] , blockers : 0 , summary : "" , stalemate : false , rerun_consistent : null , reason : "未配置子代理监督者,跳过独立审稿" } ) ,
173+ { kind : "skipped" , reason : "未配置子代理监督者,跳过独立审稿" } ,
174+ ) ;
175+ assert . deepEqual ( describeReview ( null ) , { kind : "absent" } ) ;
176+ assert . deepEqual ( describeReview ( undefined ) , { kind : "absent" } ) ;
177+ } ) ;
178+
98179test ( "formatMetricValue: thousands separators, bounded decimals, non-numbers untouched" , ( ) => {
99180 assert . equal ( formatMetricValue ( 0.123456 ) , "0.1235" ) ;
100181 assert . equal ( formatMetricValue ( 1234.5678 ) , "1,234.57" ) ;
0 commit comments