9.4 KiB
V43 给 Luna 的编码指令(整改版)
实施状态:实现完成,独立代码复验与真实 MySQL/Docker 验收通过,待 Git 检查点。
本轮四项阻断的可执行证据
FairnessMonitoringPersistenceIntegrationTest.realServiceJdbcBudgetAt30_300_3000WithEightDimensionsAndMultipleAppeals:Spring 管理的真实 Service 事务代理、真实 Repository/权限仓库和@PrimaryJDBC 计数数据源;30/300/3000 人、每人八维和两份合法回滚申诉。业务查询分别为 overview=2、dimensions=2、appeals=1、drift/ranking-stability=0;权限查询逐接口单列为2。夹具与验证查询不在计数区间。每个版本仅返回一个同分频数,申诉返回最终汇总。FairnessMonitoringHttpIntegrationTest.realHttpAppealsHidesSmallComparableChangeGroup:60 人各一份非法分数回滚,其中一人在 GROWTH 另有合法回滚;真实 SQL 断言61份申诉、60人、60人非法分数、1条/1人可比、重复申诉人数0,再通过真实 HTTP 检查变分统计全部隐藏。- 同一非空申诉夹具中,五个接口各自独立比较调用前后完整表内容(包含 version),涉及评分、申诉、申诉历史、回滚历史、非空回滚限流、审计和四张风险治理表。原全局99/1测试亦在两个接口之间分别比较。
FairnessMonitoringPersistenceIntegrationTest.sqlOverallMatchesPureFunctionForPartialRepeatingHalfUpAndPendingVersions:1/2/3个有效维度、空分PENDING、10.005的HALF_UP、10.003333…及10.006666…;SQL结果逐例与既有评分纯函数对账。仅修改PENDING行版本即判MIXED,仍保留有效覆盖人数。
以上为 H2 自动化证据,不代表真实 MySQL EXPLAIN、运行时 OpenAPI 或性能验收通过。
2026-09-09 最终复验:V43专项60/60;全量 mvn test 与 mvn clean verify 均1535项,Failures=0、Errors=0、Skipped=0,构建成功。OpenAPI静态及运行时均为172 paths / 210 operations。真实MySQL完成权限、隐私、只读性、查询预算与30/300/3000人规模验收;未提交或推送。
文档类型:执行指南。先完整阅读同目录v43-candidate-scoring-fairness-design.md修订版;不要沿用旧版“calculated_at可恢复历史漂移”的结论。
1. 任务与基线
项目C:/Users/15642/Desktop/zhilai,实现V43候选评分公平性与稳定性监测。 先读取项目适用AGENTS.md,执行git status --short、git diff --cached --name-only、git log -5 --oneline;核查最新迁移和OpenAPI。已知维护提交498512d、最新业务V42、Flyway V40、OpenAPI167/205,均须实测而非假设。 保护现有暂存与未跟踪文件。禁止reset/restore/checkout、git add -A、commit、push、删除移动历史文件。若已有V43实现,先评审差异,不覆盖他人修改。
本任务授权代码、自动化、正式文档;实现完成后需停止在本版本,不启动/停止Docker,不执行真实MySQL黑盒,不结束未知Java进程,不进入V44。当前实现结果须以自动化验证报告为准,真实黑盒仍待负责人另行安排。
2. 实现边界
无新增Flyway、数据库表、后台任务、feature flag、公共错误码,不改V1–V40迁移。 只允许ADMIN聚合查询,无学生/企业入口,无写入、自动调分/排名/权重/封禁/申诉处理。 不读答案、题目、测评详情、sub_scores_json、audit details,不接AI。 不得调用CandidateScoringEngineService.getOverview、computeAll、upsertSnapshots等可能写快照入口。只读纯函数可以复用。 学校/城市/姓名不得作为敏感属性代理。
3. 接口范围
新增五个GET:
- /admin/scoring/fairness/overview:period必填。
- /admin/scoring/fairness/dimensions:period必填,dimension可选八维白名单。
- /admin/scoring/fairness/drift:无业务参数,固定UNAVAILABLE。
- /admin/scoring/fairness/ranking-stability:无业务参数,固定UNAVAILABLE。
- /admin/scoring/fairness/appeals:成对可选from/to日期,默认最近30个完整业务日,最大90日。
drift原因IMMUTABLE_SCORE_HISTORY_NOT_AVAILABLE;排名原因RANKING_SNAPSHOT_HISTORY_NOT_AVAILABLE。 无数据、不可计算、小样本是不同状态,不全部返回0或NORMAL。 匿名401,其他角色403/2002;参数400/1001。拒绝jobId/companyId/rulesVersion/granularity及其他未知业务参数。 如果实际基线167/205,最终172/210;不得通过删路径满足数字。
4. 必须先落实的统计规则
以设计第4–6节为唯一口径,写测试后实现:
- period指定一个月份。快照是“当前所存版本”,calculated_at会被覆盖,不支持历史窗口恢复。
- N是该period至少一行快照的独立学生数。无快照全体学生不在范围,响应明确scope。
- 每维缺行、空分、有效分、状态分别统计,分母和去重按设计,不把八维行数当人数。
- 分布有效分为OK/ESTIMATED且0–100。统计sampleSize是独立人数。
- 同候选所有现存维度跨规则版本即MIXED,排除V43综合分分布;单一未知版本归UNKNOWN。其计数受小样本保护。
- 同版本综合分对有效维度等权平均,2位HALF_UP,与现有overallScoreFromSnapshots测试对账,不改V32。
- 分位数线性插值、总体标准差、十个连续小数分桶、零分母null;内部DECIMAL128,输出2位HALF_UP。
- 风险先用未舍入值比较。只启用分桶集中70/85%运营提示。旧版缺失率差、均值差、纠正率阈值本版不启用。
- 不足30独立人抑制明细;30–99 LOW_CONFIDENCE,100以上NORMAL_CONFIDENCE。
- 1–29的桶/状态/版本/异常计数抑制整组,防止补集反推。被抑制桶的关联均值/极值/分位数/集中风险也隐藏。
- 分别使用availability/confidence/riskLevel,不把UNAVAILABLE放入风险等级。
- 维度DTO必须独立返回
inconsistentRecordCount、unknownStatusCount和outOfRangeScoreCount;分布一旦触发桶/补集抑制,sampleSize与所有统计字段、分桶及风险均置空,只保留availability/reason。
5. 申诉与回滚
按created_at选[from,to)创建队列,展示截至capturedAt的当前状态,不叫历史日终状态。 APPROVED+ROLLED_BACK才是审核通过数。分别实现通过率、回滚执行率、实际变分率,严禁三者互换。 申诉主表先统计,历史先按appeal_id聚合后关联,不因JOIN重复计数。 仅唯一ROLLBACK历史、前后分非空有效、前后同一已知规则版本的申诉进入可比变分分母;重复历史只排除该申诉,不排除同一候选人的其他合法申诉。变分率包括0差的分母;规则升级不算纠错。 每个比率同时校验该分母人群>=30独立人。重复申诉按同人同维同period的窗口内记录判断。真实曝光申诉率UNAVAILABLE。 不读原文、管理员身份;不提供申诉自由切片。
6. 组件与性能
建议新建独立scoringmonitoring包:Controller、Service、只读查询组件、纯统计计算器及白名单DTO;命名遵循仓库惯例。
SQL参数绑定;GROUP BY聚合、score频数而非全量个人实体;固定查询次数,不能逐维或逐候选findById。
总览<=4、维度<=3、申诉<=5条业务查询为目标预算,角色查询单计;UNAVAILABLE接口0条业务查询。同一请求capturedNow、同一只读事务。
实现可解释超时处理,不能截断样本返回成功。真实EXPLAIN在后续黑盒验证;不擅自补索引或迁移。
小样本统计数值不得绕过统一抑制组件从另一个 DTO 字段泄露。
整改实现要求由独立、可测试的 FairnessDisclosureGuard 统一执行小样本与互补抑制;有效集合或其补集为 1–29 人时,相关整组统计字段必须一并隐藏。
不回任何个人/申诉/答卷/结果ID、联系方式、学校、性别、简历、答案或内部JSON。完整序列化测试,不能只检查toString。
7. 自动化
必须完整实现设计第10节测试。尤其:
- 多行同一人不能绕过30人门槛;
- 9.5/100分桶、手算分位数和标准差、69.995%风险边界;
- 混合版本与未知版本;
- 同月覆盖不能生成历史漂移;
- APPROVED未回滚、回滚0差、跨版本、空分、重复历史和JOIN放大;
- 多次申诉不足30独立人;
- 互补抑制、非法筛选、权限和完整JSON脱敏;
- 快照和申诉表内容/版本不变,而非只测行数;
- 无N+1及既有V25/V32/V37/V38/V39/V41/V42回归。
8. 文档、验证与停止
更新本设计实施状态、路线图、frontend-integration.md;新增docs/candidate-scoring-fairness-api.md。编码完成后才更新openapi-rc.json和verify_openapi.py: 五个GET恰好5path/5operation;全部200响应有真实schema;查询参数准确;schema不含个人敏感字段;两个不可用接口契约准确。
执行:
mvn -Dtest="*Fairness*Test,*ScoringMonitoring*Test" test
mvn test
mvn clean verify
python docs/verify_openapi.py
测试通配符必须匹配实际新增类,不得以0测试成功。clean verify若被运行JAR阻塞,报告已核实PID和原因,不擅自停止。 报告真实测试总数、Failures/Errors/Skipped、精确文件清单、无新增迁移、OpenAPI计数、统计口径及数据限制、小样本保护、无写入和查询预算证据、Git状态。 真实MySQL/Docker未执行必须写待验收,运行时OpenAPI未启动核验不得声称通过。 完成后停止,保持所有本轮变更未暂存,未提交未推送。