autorate 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- autorate-0.1.0/.gitignore +13 -0
- autorate-0.1.0/LICENSE +202 -0
- autorate-0.1.0/PKG-INFO +417 -0
- autorate-0.1.0/README.md +404 -0
- autorate-0.1.0/data/cert_jev.json +625 -0
- autorate-0.1.0/data/cert_laya.json +626 -0
- autorate-0.1.0/data/cert_massive_de_laya.json +3335 -0
- autorate-0.1.0/data/cert_massive_en_laya.json +3382 -0
- autorate-0.1.0/data/cert_massive_km_laya.json +3395 -0
- autorate-0.1.0/data/cert_massive_sw_laya.json +3369 -0
- autorate-0.1.0/data/cert_severity_ordinal.json +1258 -0
- autorate-0.1.0/data/contamination_probe.json +144 -0
- autorate-0.1.0/data/g1_feasibility.json +358 -0
- autorate-0.1.0/data/inventory.md +63 -0
- autorate-0.1.0/data/inventory.md.json +216 -0
- autorate-0.1.0/data/massive_provenance.json +386 -0
- autorate-0.1.0/data/pin_app_benchmark.json +274 -0
- autorate-0.1.0/data/resplit_200.json +18324 -0
- autorate-0.1.0/data/slices_language.json +42725 -0
- autorate-0.1.0/protocol.json +206 -0
- autorate-0.1.0/pyproject.toml +47 -0
- autorate-0.1.0/src/autorate/__init__.py +33 -0
- autorate-0.1.0/src/autorate/audit.py +1076 -0
- autorate-0.1.0/src/autorate/case_count.py +141 -0
- autorate-0.1.0/src/autorate/certificate.py +444 -0
- autorate-0.1.0/src/autorate/certify_choice.py +677 -0
- autorate-0.1.0/src/autorate/certify_score.py +377 -0
- autorate-0.1.0/src/autorate/certify_threshold.py +435 -0
- autorate-0.1.0/src/autorate/cli.py +1299 -0
- autorate-0.1.0/src/autorate/conformal.py +53 -0
- autorate-0.1.0/src/autorate/contamination.py +585 -0
- autorate-0.1.0/src/autorate/correction.py +500 -0
- autorate-0.1.0/src/autorate/drift.py +535 -0
- autorate-0.1.0/src/autorate/gate.py +99 -0
- autorate-0.1.0/src/autorate/groups.py +229 -0
- autorate-0.1.0/src/autorate/inventory.py +783 -0
- autorate-0.1.0/src/autorate/nonconformity.py +23 -0
- autorate-0.1.0/src/autorate/ordinal.py +188 -0
- autorate-0.1.0/src/autorate/protocol.py +771 -0
- autorate-0.1.0/src/autorate/readers/__init__.py +1 -0
- autorate-0.1.0/src/autorate/readers/feishu_zh.py +387 -0
- autorate-0.1.0/src/autorate/records.py +238 -0
- autorate-0.1.0/src/autorate/report.py +2246 -0
- autorate-0.1.0/src/autorate/scales.py +207 -0
- autorate-0.1.0/src/autorate/severity.py +969 -0
- autorate-0.1.0/src/autorate/tails.py +102 -0
- autorate-0.1.0/src/autorate/techreport.py +739 -0
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
.venv/
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.egg-info/
|
|
4
|
+
.pytest_cache/
|
|
5
|
+
.ruff_cache/
|
|
6
|
+
cert.json
|
|
7
|
+
|
|
8
|
+
# The composite action's badge output. The *committed* badge lives in `.github/badges/`; this is the
|
|
9
|
+
# per-run copy a workflow uploads as an artefact.
|
|
10
|
+
.autorate/
|
|
11
|
+
|
|
12
|
+
# SDD implementation worktrees (isolated lanes); never part of the published tree.
|
|
13
|
+
.worktrees/
|
autorate-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright 2026 the autorate authors
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|
autorate-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,417 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: autorate
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Certified automation rates for decision models: confidence is not permission.
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
License-File: LICENSE
|
|
7
|
+
Requires-Python: >=3.10
|
|
8
|
+
Requires-Dist: numpy>=1.24
|
|
9
|
+
Provides-Extra: dev
|
|
10
|
+
Requires-Dist: pytest>=8; extra == 'dev'
|
|
11
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
|
|
14
|
+
# autorate
|
|
15
|
+
|
|
16
|
+
[](.github/badges/autorate-badge.json)
|
|
17
|
+
|
|
18
|
+
Certified automation rates for decision models: confidence is not permission.
|
|
19
|
+
|
|
20
|
+
A benchmark answers "how good is the model". A certificate answers a question an
|
|
21
|
+
operator can actually be held to: "what share of this model's decisions may run
|
|
22
|
+
unattended while keeping the probability that an automated decision is wrong at most
|
|
23
|
+
`beta`, given the held-out data we really have". When the data cannot support that
|
|
24
|
+
claim, `autorate` prints `NOT_CERTIFIABLE` with a reason code, the observation at the
|
|
25
|
+
requested coverage that caused it, and a diagnostic sweep of the neighbouring coverage
|
|
26
|
+
levels -- evidence for the refusal, not a certificate. It exits 3 and does not publish a
|
|
27
|
+
number about nothing.
|
|
28
|
+
|
|
29
|
+
## Verification-first navigation
|
|
30
|
+
|
|
31
|
+
- [Verification status](docs/VERIFICATION.md) · [Known errata](docs/ERRATA.md) · [Results](docs/RESULTS.md)
|
|
32
|
+
- The present implementation covers the decision-certification primitives described below; planned certificate families and guarantees are **not** implemented claims.
|
|
33
|
+
- This is a public repository. No public licensing or release rights are implied.
|
|
34
|
+
|
|
35
|
+
## What a certificate carries
|
|
36
|
+
|
|
37
|
+
Stored: `feasible`, `reason`, `backend`, `method`, `alpha`, `beta`, `delta`, `autorate`,
|
|
38
|
+
`autorate_ci`, `conditional_error_bound`, `marginal_error_bound`, `mean_set_size`,
|
|
39
|
+
`qhat`, `n_cal`, `n_eval`, `envelope`, `meta`.
|
|
40
|
+
|
|
41
|
+
Derived, never stored, because each is a pure function of a stored field -- storing them
|
|
42
|
+
gave one number two owners and a guard that could not see the disagreement: `refusal_rate`
|
|
43
|
+
= `1 - autorate` (every evaluated case is empty, singleton, or multi-label) and `level`
|
|
44
|
+
= `1 - N_CLAIMS * delta` (three bounds are published per certificate).
|
|
45
|
+
|
|
46
|
+
Two of those rows carry the whole argument:
|
|
47
|
+
|
|
48
|
+
- `conditional_error_bound` is `P(wrong | automated) <= beta`. `marginal_error_bound`
|
|
49
|
+
is `P(wrong AND automated)`. They are different quantities, and a paper or a dashboard
|
|
50
|
+
that quotes one while meaning the other is the failure mode this tool exists to stop.
|
|
51
|
+
- Both are over **cases**, not archive rows. Repeats of one case are one observation, and on this
|
|
52
|
+
corpus they are not even evenly counted: laya's archived choice slice is 64 cases x 3 rows (192
|
|
53
|
+
rows), while jev's is 191 rows over the same 64 cases -- one case carries two rows, not three -- and
|
|
54
|
+
a jev case carries between one and three *distinct* probability vectors. What a repeat shares is the
|
|
55
|
+
measurement, not the row: laya's three repeats per case carry byte-identical probability vectors,
|
|
56
|
+
scores and gold labels (not identical rows: the repeat counter and its own elapsed time differ),
|
|
57
|
+
while jev's repeats need not carry the same vector at all -- so the `n` in every bound counts cases
|
|
58
|
+
and the record counts are published beside it instead of standing in for it.
|
|
59
|
+
- `envelope` is the machine-readable statement of what the bound assumed -- coverage
|
|
60
|
+
level, group conditioning, drift, and how empty sets were counted. A certificate read
|
|
61
|
+
without its envelope is invalid output, so `certify`, `compare` and `gate` all print it.
|
|
62
|
+
- `alpha` is the coverage floor the certificate is held to, not a label on it. An earlier version
|
|
63
|
+
swept a grid of coverage levels for the largest automation rate and tested the winner on
|
|
64
|
+
the same evaluation half, then printed "at alpha=0.050" while operating at 0.89
|
|
65
|
+
coverage (fixed in `241e395`). The pre-fix quantity is still checkable rather than asserted:
|
|
66
|
+
`data/cert_*.json` carries `meta.diagnostic_curve`, the sweep of coverage levels the old code
|
|
67
|
+
maximised over, and `meta.closest_attempt`, the point that came closest to the budget.
|
|
68
|
+
Selecting on the test half is snooping, so the set size now comes from the
|
|
69
|
+
calibration half at exactly the requested `alpha`; the grid survives only as diagnostic
|
|
70
|
+
evidence attached to a refusal.
|
|
71
|
+
|
|
72
|
+
`refusal_rate` and `mean_set_size` exist because an empty certified set is a refusal,
|
|
73
|
+
not a free correct answer: counting it as automation would inflate the rate.
|
|
74
|
+
|
|
75
|
+
## Installing the wheel, and what it cannot do
|
|
76
|
+
|
|
77
|
+
`pip install autorate` installs the library and the console script. It does **not** install this
|
|
78
|
+
repository's evidence bundle. `autorate verify` re-derives *this* tree's published numbers, so it
|
|
79
|
+
needs `protocol.json` and the committed `data/` set and refuses with exit `4` when an artefact the
|
|
80
|
+
tables declare is absent -- by design, because the six `data/records_*.jsonl` files carry dataset
|
|
81
|
+
rows (labels, per-option probabilities, gold answers) and are not put in a package that any index
|
|
82
|
+
can host. For the evidence, take the repository, not the wheel:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
uv add "autorate @ git+https://github.com/Jackxiaozhiren/autorate"
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
## Commands
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
uv sync --frozen --extra dev
|
|
92
|
+
|
|
93
|
+
uv run --frozen autorate snapshot --out data/inventory.md # corpus -> committed inventory
|
|
94
|
+
uv run --frozen autorate export-feishu --out data/records_feishu.jsonl
|
|
95
|
+
uv run --frozen autorate certify data/records_feishu.jsonl --backend laya --out cert.json
|
|
96
|
+
uv run --frozen autorate compare data/cert_laya.json data/cert_jev.json
|
|
97
|
+
uv run --frozen autorate gate data/records_feishu.jsonl --cert data/cert_jev.json --limit 5
|
|
98
|
+
uv run --frozen autorate report --out docs/RESULTS.md # write the published numbers
|
|
99
|
+
uv run --frozen autorate report --full # write docs/REPORT.md, one document for a reviewer
|
|
100
|
+
uv run --frozen autorate verify # re-derive them, fail on drift
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
The `uv run --frozen` prefix is not decoration: the console script is not on `PATH`
|
|
104
|
+
after `uv sync`, and a bare `pytest` on this machine resolves to a different
|
|
105
|
+
interpreter entirely.
|
|
106
|
+
|
|
107
|
+
Exit codes: `0` certified, `3` `NOT_CERTIFIABLE`, `2` usage error -- an input this
|
|
108
|
+
command was handed is wrong, whether you named its path or a default supplied it --
|
|
109
|
+
`4` the committed state cannot reproduce what it publishes: a number that disagrees,
|
|
110
|
+
or a published artefact this repository's own tables declare that this run cannot
|
|
111
|
+
read -- because nothing is at its path, because the path itself refuses the open, or
|
|
112
|
+
because what is there is not the artefact that table publishes: a corrupt certificate,
|
|
113
|
+
a records line that is not a record, a document that is not text, a certificate stored
|
|
114
|
+
in a shape this build does not read, a committed inventory snapshot that will not load
|
|
115
|
+
or is not the mapping its renderers index.
|
|
116
|
+
One table-declared path stays `2` by ruling rather than oversight:
|
|
117
|
+
`data/records_feishu.jsonl` is the default every command reads -- `verify` and `report`
|
|
118
|
+
with no flag, `audit --records` with one -- absent or unreadable alike, and a default is
|
|
119
|
+
something its operator can name and repair.
|
|
120
|
+
A missing `data/inventory.md.json` alongside no corpus is `2` for a reason the refusal
|
|
121
|
+
does not cover -- there is nothing to verify against, which is a different statement
|
|
122
|
+
from a published artefact that cannot be read -- while a snapshot that is present and
|
|
123
|
+
will not load is `4` like any other published artefact.
|
|
124
|
+
|
|
125
|
+
`snapshot` and `export-feishu` read the corpus: pass `--root`, set
|
|
126
|
+
`AUTORATE_FEISHU_ROOT`, or place the checkout as a sibling of this repo
|
|
127
|
+
(`<workspace>/laya*/research/benchmarks/feishu_zh`). No source file carries an absolute
|
|
128
|
+
machine path, and `tests/test_cli.py` fails the build if one reappears -- a literal like
|
|
129
|
+
that passes every local gate and only breaks in the environment nobody can see.
|
|
130
|
+
|
|
131
|
+
Everything else runs offline on committed files; no command reaches the network.
|
|
132
|
+
|
|
133
|
+
## GitHub Action and badge
|
|
134
|
+
|
|
135
|
+
[`action.yml`](action.yml) is a composite action. It shells out to the CLI and implements **no**
|
|
136
|
+
statistics: no bound, rate or aggregate is computed in the action or in
|
|
137
|
+
[`tools/action_report.py`](tools/action_report.py), which only maps the CLI's own exit code to a state and
|
|
138
|
+
formats what the CLI printed. The one number it parses is the denominator out of the tool's
|
|
139
|
+
`re-derived N /M values` line, so the badge can carry it instead of standing alone.
|
|
140
|
+
|
|
141
|
+
| input | default | meaning |
|
|
142
|
+
|---|---|---|
|
|
143
|
+
| `version` | empty | run `autorate==<version>` from PyPI through `uvx` |
|
|
144
|
+
| `ref` | empty | run the CLI from a detached worktree at that ref of this repository (needs full history) |
|
|
145
|
+
| `alpha`, `beta` | empty | passed to `certify`; empty means "use the frozen protocol's rubric" |
|
|
146
|
+
| `path` | `protocol.json` | read from the **working tree**, never `git show <rev>:protocol.json` |
|
|
147
|
+
| `records` | empty | when set, `certify` runs too, and its exit 3 is the verdict |
|
|
148
|
+
| `fail_on` | `drift,not-run` | states that fail the job |
|
|
149
|
+
| `badge_dir` | `.autorate` | where the `.svg` and its `.json` record are written |
|
|
150
|
+
| `comment` | `true` | post a PR comment quoting `autorate compare` verbatim (both denominators, no bound diff) |
|
|
151
|
+
|
|
152
|
+
The states are a closed vocabulary, and none of them is a boolean:
|
|
153
|
+
|
|
154
|
+
| state | when | what it does **not** mean |
|
|
155
|
+
|---|---|---|
|
|
156
|
+
| `certified` | `verify` exited 0 (and `certify` exited 0, if a records file was given) | not "the model is certified": `protocol.json`'s `claims[]` is where a certificate claim is made or refused |
|
|
157
|
+
| `not-certifiable` | `certify` exited 3 | not a broken pipeline -- a refusal is a result, and the badge says so |
|
|
158
|
+
| `drift` | `verify` exited 4 | not "the numbers moved slightly": the tree cannot reproduce what it publishes |
|
|
159
|
+
| `not-run` | no verdict was produced -- no CLI, no network, a usage error, a shallow checkout for `ref`, or a missing denominator line | never a pass |
|
|
160
|
+
|
|
161
|
+
`fail_on` defaults to `drift,not-run`: exit 4 fails the job, exit 3 is reported rather than red, and a run
|
|
162
|
+
that produced no verdict is never green. Add `not-certifiable` to make a refusal fail the job as well.
|
|
163
|
+
|
|
164
|
+
**What the PR comment is, and is not.** F8 rule 4 asks for a bound-versus-previous-bound diff with both
|
|
165
|
+
denominators. The shipped `autorate compare` prints each side's own `n_cal` / `n_eval` but states in its
|
|
166
|
+
own source that it "has no authority to pair anything", and returns a usage error rather than a
|
|
167
|
+
before/after table when the two certificates were frozen under different protocols. The comment therefore
|
|
168
|
+
quotes the command's output verbatim, carries both denominators as the tool printed them, and says plainly
|
|
169
|
+
that it computes no bound; claiming a bound diff would assert a capability the tool does not have
|
|
170
|
+
(PRD §13.3 item 4). When no certificate under `data/` changed — the usual case here — the comment says
|
|
171
|
+
`not-run`, and a comment that cannot be delivered is a named `not-run` in the job summary rather than a
|
|
172
|
+
silent stderr line. The literal rule 4 wording is recorded as a deviation in the milestone report.
|
|
173
|
+
|
|
174
|
+
Two things about checkouts, because both have already broken this repository's CI once:
|
|
175
|
+
|
|
176
|
+
- Every checkout in a workflow that uses the action sets `fetch-depth: 0`
|
|
177
|
+
([`.github/workflows/action-gate.yml`](.github/workflows/action-gate.yml)). A shallow runner keeps one
|
|
178
|
+
commit in its object database, so `git show <rev>:<path>` fails there while passing in every real clone.
|
|
179
|
+
The action reads `protocol.json` from the working tree and states, in the job summary, which store it
|
|
180
|
+
read the *base revision* from: `history source: object-db` (full history), `shallow`, or `no-object-db`.
|
|
181
|
+
`tests/test_action_f8.py` refuses both a workflow that drops the flag and a summary that stops saying it.
|
|
182
|
+
- The committed badge in `.github/badges/` is produced by the same code path the action runs, and it
|
|
183
|
+
records the protocol digest it was minted under. A re-freeze makes it stale and the test that reads it
|
|
184
|
+
goes red rather than leaving a green pill describing a superseded protocol.
|
|
185
|
+
|
|
186
|
+
It is minted in the **corpus-absent** lane, because that is the lane a clone and the runner see: the
|
|
187
|
+
corpus is not in the repository, so a stranger reproduces `re-derived 612 /612 values`, and the badge
|
|
188
|
+
carries that number and `corpus absent` in its tooltip and in `autorate-badge.json`. On a machine that
|
|
189
|
+
also holds the corpus the same command prints `re-derived 649 /649 values` and writes a badge saying
|
|
190
|
+
`corpus present`; both are the tool's own labels, and the badge never carries one lane's number under
|
|
191
|
+
the other lane's name. Re-mint the committed one from an export:
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
exp=$(mktemp -d) && git archive HEAD | tar -x -C "$exp"
|
|
195
|
+
(cd "$exp" && uv run --frozen python3 tools/action_report.py --path protocol.json --badge-dir badges)
|
|
196
|
+
cp "$exp"/badges/autorate-badge.svg "$exp"/badges/autorate-badge.json .github/badges/
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
## Reproduction
|
|
200
|
+
|
|
201
|
+
`docs/RESULTS.md` is generated, never typed: `autorate report` emits it and `autorate
|
|
202
|
+
verify` re-derives every value in it and prints `re-derived N /N values`. It carries no
|
|
203
|
+
timestamp, so a re-run is byte-comparable, and it quotes no path or machine name, so a
|
|
204
|
+
machine without the corpus reproduces the same bytes -- which is what lets CI run the
|
|
205
|
+
gate at all.
|
|
206
|
+
|
|
207
|
+
`docs/REPORT.md` is the same kind of file for a reader who wants one document instead of
|
|
208
|
+
seven: `autorate report --full` emits it, `verify` re-derives it byte for byte under the same
|
|
209
|
+
rule, and every figure in it is read out of an artefact rather than typed into a sentence --
|
|
210
|
+
the certificate shape from `certificate.py`, the five gates from `protocol.json`'s `claims`
|
|
211
|
+
array, each refusal from the artefact that refused, the related work from the rows of
|
|
212
|
+
`docs/VERIFICATION.md` that are `verified`. The flag is additive on purpose: `autorate report`
|
|
213
|
+
with no flag still writes `docs/RESULTS.md`, byte for byte the file this gate has always
|
|
214
|
+
compared.
|
|
215
|
+
|
|
216
|
+
That fallback has a stated limit, and `verify` prints it: with the corpus absent, the
|
|
217
|
+
upstream `SOURCE.json` digests and the inventory snapshot are transcribed from
|
|
218
|
+
`data/inventory.md.json`, not recomputed. The snapshot is policed from the environment
|
|
219
|
+
that can see the corpus, where a stale key goes red.
|
|
220
|
+
|
|
221
|
+
Those two environments are not two speeds of the same gate, and the denominators `verify`
|
|
222
|
+
prints say so: `re-derived 612 /612 values` where the corpus is absent, `re-derived 649 /649
|
|
223
|
+
values` where it is present. Both exit 0, both are green, and they are not the same claim.
|
|
224
|
+
|
|
225
|
+
The corpus is not a committed file. It is the sibling `laya*/research/benchmarks/feishu_zh`
|
|
226
|
+
checkout, which lives outside this repository, so a runner that checks out this repository
|
|
227
|
+
alone can never reach the 649: every CI run is a 612 run, on both of its arms. Green CI is
|
|
228
|
+
therefore evidence about the transcribed lane and nothing else.
|
|
229
|
+
|
|
230
|
+
A 612 run proves a lot inside that lane. Every published number that is a function of a
|
|
231
|
+
committed input re-derives there -- all seven published certificates, each from the committed
|
|
232
|
+
records it was actually made from, G4's slice run from the four committed MASSIVE record files
|
|
233
|
+
it names inside itself, the whole
|
|
234
|
+
of `docs/RESULTS.md` byte for byte, `data/inventory.md` byte for byte, `docs/AUDIT.md` byte
|
|
235
|
+
for byte, `docs/SEVERITY.md` byte for byte, `docs/RESPLIT.md` byte for byte, `docs/SLICES.md` byte
|
|
236
|
+
for byte, `docs/CONTAMINATION.md` byte for byte, `docs/REPORT.md` byte for byte, and the MASSIVE rows
|
|
237
|
+
from their committed pin. What a 612 run
|
|
238
|
+
cannot prove is what its own disclosure says in so many words --
|
|
239
|
+
`this run cannot see whether that snapshot went stale`. The gap is exactly 37
|
|
240
|
+
checks: the 9 upstream `SOURCE.json` digests, the 26 snapshot keys a corpus-present run
|
|
241
|
+
recomputes instead of reading back. On a machine without the archive those 35 do not run at
|
|
242
|
+
all; the figures they would test exist there only as the transcription, so a snapshot that
|
|
243
|
+
had drifted from the corpus would agree with itself and report 612 /612.
|
|
244
|
+
|
|
245
|
+
So the corpus-present run is not a slower, fussier version of the CI job; it is the only one
|
|
246
|
+
in which the transcription has an owner, and it is a local obligation, run before a push,
|
|
247
|
+
because no runner can run it for you.
|
|
248
|
+
|
|
249
|
+
## The five criteria, and what this tree can show for each
|
|
250
|
+
|
|
251
|
+
v1 is defined by five criteria, G1–G5. `autorate verify` prints one line per criterion with a status that
|
|
252
|
+
can say no -- `not_certifiable`, `measured_not_bounded`, `not_measured` -- read from `protocol.json`, the
|
|
253
|
+
frozen protocol document, which is emitted by a command and never typed. The statuses below are what that
|
|
254
|
+
command prints at this revision; the document is their owner, so this section is a reading of it and not a
|
|
255
|
+
second place to keep them.
|
|
256
|
+
|
|
257
|
+
- **G1, at least three decision tasks certified at `autorate(α = 0.05)` with a 200-resplit empirical
|
|
258
|
+
violation rate: `not_certifiable`.** Six decision tasks have been scored and their records committed;
|
|
259
|
+
zero of the six yield a certificate, and the refusals are published as artefacts rather than rounded
|
|
260
|
+
away. The binding quantity is the evaluation half's case count: the exact one-sided bound on a small
|
|
261
|
+
number of automated cases sits above a 5% budget no matter how few are wrong. The criterion's second
|
|
262
|
+
column is now measured and published rather than promised: `tools/resplit_experiment.py` re-splits every
|
|
263
|
+
scored task 200 times at the rubric this freeze owns, and `data/resplit_200.json` with `docs/RESPLIT.md`
|
|
264
|
+
carries what came out. All six published tasks certify in **0 of 200** splits, so their empirical violation
|
|
265
|
+
rate is recorded as undefined with a zero denominator instead of being imputed as `0.000`; the one row that
|
|
266
|
+
does produce a rate is the synthetic control (200 of 200 splits certify, rate 0.000 over 200 certificates),
|
|
267
|
+
which tests the machinery and is labelled as nothing else. `verify` compares the artefact's own arithmetic —
|
|
268
|
+
certificates plus refusals per task, the rate against its denominator, the rows against the splits — and the
|
|
269
|
+
rubric it recorded against the freeze's, in both lanes. The row is still not close to met: the second column
|
|
270
|
+
exists, the first is zero. What replaces the missing certificate is the ceiling, published rather than
|
|
271
|
+
asserted: `tools/g1_feasibility.py` computes, for each pool size this checkout can actually build, how wide
|
|
272
|
+
the exact one-sided bound is and what error rate would therefore be certifiable at `α = 0.05`, and
|
|
273
|
+
`verify` recomputes every figure in both lanes from `src/autorate/tails.py` and the published certificates.
|
|
274
|
+
So `not_certifiable` is now a measured claim about n and bound width, not an absence of an answer -- which
|
|
275
|
+
is the outcome spec §14 names as a result ("bound width is a first-class output; 'the bound is useless
|
|
276
|
+
here' *is* a certification result"). §14's kill criterion for this row is not evaluable rather than
|
|
277
|
+
fired: its condition compares a worst-group certified `autorate` with 0.30, and with nothing certified there
|
|
278
|
+
is no certified `autorate` to put in that comparison -- the same refusal that keeps the violation rate
|
|
279
|
+
undefined. Both halves of the pivot are published now: the audit multiple G2 measures, and the
|
|
280
|
+
contamination gap section 9 defines, frozen as `data/contamination_probe.json` with its interval and its
|
|
281
|
+
`claim = False` (see the G4 bullet). So the headline this project ships is the audit multiple G2
|
|
282
|
+
measures and the worst-slice refusal G4 names. Read the G1 row as unmet; that is what it says.
|
|
283
|
+
- **G2, the reference README's gate demonstrably violating its implied error rate: `measured_not_bounded`.**
|
|
284
|
+
`autorate audit` measures the gate upstream instructs and `docs/AUDIT.md` publishes the multiplier, but the
|
|
285
|
+
sample cannot bound the claim: on the 2 cases one backend automates, one is wrong, and the exact one-sided
|
|
286
|
+
bound is 0.975. The point estimate misses upward; what the corpus says is that it cannot carry the claim.
|
|
287
|
+
- **G3, at least one ordinal guarantee multiclass conformal prediction cannot express: `not_measured`.** The
|
|
288
|
+
one-sided severity certificate (`P(Y > â(X)) ≤ α`, three canonical bounds, its own refusal reasons) is a
|
|
289
|
+
command, an artefact and a gate row now: `autorate severity` writes `data/cert_severity_ordinal.json` from
|
|
290
|
+
the committed ordinal population, `docs/SEVERITY.md` renders it from those bytes, and `verify` re-derives
|
|
291
|
+
every published quantity of it in both lanes. The status does not move, because the criterion is a contrast
|
|
292
|
+
and not a certificate. A first measured contrast is committed (`tests/test_g3_contrast.py`): on the published
|
|
293
|
+
ordinal population, at the rubric this freeze owns, this repository's ordinal set gate refuses --
|
|
294
|
+
`empty_feasible_set`, publishing no `qhat`, no automation rate and no error bound of any kind -- while the
|
|
295
|
+
severity gate certifies the one-sided bound, reports its measured held-out violation rate and states the
|
|
296
|
+
rule's price; the set gate refuses on all four population variants that file walks. That is silence in a
|
|
297
|
+
named direction, and it is not the criterion -- because the criterion's own wording lost. On the corner of
|
|
298
|
+
the generator where the set gate does certify (`shift = 0`, `error_rate = 0`; 4 of the 64 knob cells
|
|
299
|
+
searched), its interval's top endpoint sits above the gold level in none of the 600 evaluated records
|
|
300
|
+
(200 cases), so
|
|
301
|
+
`P(Y > hi(X)) = 0` lies inside that certificate's own marginal bound of 0.014867 -- computed by
|
|
302
|
+
`tests/test_g3_contrast.py`'s builder in memory and written to no artefact, which is why the digit names its
|
|
303
|
+
producer instead of calling itself published: a coverage claim
|
|
304
|
+
over ordered intervals *does* yield a one-sided bound, and "multiclass conformal prediction cannot express
|
|
305
|
+
one" is false for that construction. The difference that survives is narrower, and it is measured rather
|
|
306
|
+
than asserted: taking that rule costs reporting above the model's own modal level on a large share of cases
|
|
307
|
+
and leaves 36 evaluated records with an empty certified set and so with no top endpoint at all, while the set
|
|
308
|
+
certificate publishes no price, no override rate and no named rule -- the severity artefact certifies a rule
|
|
309
|
+
and states both quantities beside its bound, at the same `delta`. The status stays `not_measured` because the
|
|
310
|
+
criterion is the wider sentence, and the narrowing lives in the frozen document that carries it
|
|
311
|
+
(`protocol.json`'s G3 note, at this digest) rather than in a re-worded criterion: retiring the wider wording
|
|
312
|
+
is a decision with a new freeze, and this section reads its statuses off that document instead of keeping a
|
|
313
|
+
second copy of them.
|
|
314
|
+
- **G4, worst-slice certification refusing rather than averaging: `not_met`.** The behaviour is published now
|
|
315
|
+
rather than printed and discarded: `tools/language_slices.py` certifies the four committed MASSIVE record
|
|
316
|
+
files (11,896 cases) as slices of `slices.language` -- the key the producer declares, not a key invented for
|
|
317
|
+
the run -- and `verify` recomputes that run from the same bytes, 92 field comparisons plus 5 rubric
|
|
318
|
+
rows, in
|
|
319
|
+
both lanes. What it publishes is a refusal: 4 slices, 0 certified, each slice refused at
|
|
320
|
+
the corrected budget (alpha and delta 0.05 / 4 = 0.0125, joint level 0.85), and `n_min_violations` empty --
|
|
321
|
+
so this is a bound failure, not the size floor. The pooled marginal certificate over the same records is
|
|
322
|
+
published beside the slices and refuses too, which is the "rather than averaging" half: nothing in the
|
|
323
|
+
artefact lets the pooled number stand in for the worst slice. Two things keep the row short of met: it is
|
|
324
|
+
per-language only, because `option_count` is 20 for every committed MASSIVE row -- Khmer included, measured
|
|
325
|
+
across all 11,896 rows -- so the (language x option-count) cross the criterion names would be the same four
|
|
326
|
+
slices; and the ranking the criterion's word `worst` asks for cannot be published from a run where
|
|
327
|
+
nothing certifies: `run.worst_claim.worst.group` is `de`, but that is a tie-break, not a measurement -- its
|
|
328
|
+
`run.worst_claim.metric` is `autorate`, and `autorate` is null in all four rows, so the artefact names a
|
|
329
|
+
slice without demonstrating that it is the worst one. The slice the criterion names by example, Khmer, is no longer a gap:
|
|
330
|
+
`data/records_massive_km.jsonl` commits 2,974 per-case rows and this tree measures it, refusing like the
|
|
331
|
+
other three at the same rubric. Upstream's `accuracy 0.000 at mean confidence 0.952` remains upstream's own
|
|
332
|
+
100-case read, which these 1,487 evaluated Khmer cases neither replicate nor contradict. What the run does
|
|
333
|
+
say is the criterion's own word:
|
|
334
|
+
every refused slice's summary carries `NOT_CERTIFIABLE: reason=empty_feasible_set`, and the command over
|
|
335
|
+
these records exits 3, `EXIT_NOT_CERTIFIABLE`. The criterion's second named output is published beside
|
|
336
|
+
that run: `tools/contamination_probe.py` pools `data/pin_app_benchmark.json` -- upstream's own per-suite
|
|
337
|
+
`in_training` declarations, 27 usable rows and 3 excluded by name because their rounded rate is not a whole
|
|
338
|
+
number of cases -- and publishes `delta_hat` = -0.235208 over [-0.262646, -0.207502], so the in-training
|
|
339
|
+
stratum errs less and the interval is clear of zero. `verify` re-pools it (29 quantities plus 4 budget
|
|
340
|
+
values in both lanes, and re-digests the upstream file where the corpus is visible), and the artefact's
|
|
341
|
+
`claim` is false: the strata are different suites, so task difficulty is confounded with the flag and a gap
|
|
342
|
+
between aggregate rates is a diagnostic, not a proof of leakage. The four marginal certificates, read from their own `detail`, are the at-a-glance version of
|
|
343
|
+
the same evidence: `de` automates 0 of 1,487 cases (no singleton at that coverage, so nothing to bound);
|
|
344
|
+
`en` automates 709 with 43 wrong, upper bound 0.078; `km` 11 with 5 wrong, 0.729; `sw` 39 with 13 wrong,
|
|
345
|
+
0.477. Every non-empty slice is above the 0.050 budget, and none of the four certifies.
|
|
346
|
+
- **G5, reproducible from a commit with no GPU, no network, no model: `certified`, and the proof is a
|
|
347
|
+
committed transcript.**
|
|
348
|
+
`docs/G5.md` is the record: `tools/g5_export.sh` unpacks a `git archive` of commit `9e6363a` into a scratch
|
|
349
|
+
directory with its own HOME and runs `autorate verify --protocol protocol.json` there --
|
|
350
|
+
`249/249` values with the corpus absent at rc=0 and `284/284` with
|
|
351
|
+
it present at rc=0, and four planted defects that each come back inside the documented
|
|
352
|
+
exit-code contract (rc=2, 4, 4, 4) and are restored byte-identically with the restore
|
|
353
|
+
checked. `tests/test_g5_transcript.py` refuses the file if a recorded code escapes the contract, if a
|
|
354
|
+
lane's two halves disagree, if the digest printed is not the digest of the commit the transcript names,
|
|
355
|
+
if the sentence counting the plants disagrees with the number of plant blocks, or if a single line still
|
|
356
|
+
names a machine path. Both CI jobs run the `--protocol` form on every push, so each tip gets its own
|
|
357
|
+
platform witness of the frozen comparison; `docs/G5.md` states that workflow fact without quoting a run
|
|
358
|
+
id, because a run belongs to the push that produced it and the transcript names a commit instead.
|
|
359
|
+
Three limits stay stated: the archive lane is a local obligation, the
|
|
360
|
+
no-network claim covers the gate steps and not the dependency install, and the drift and contamination
|
|
361
|
+
figures are unpublished, so they are absent from both denominators instead of re-derived.
|
|
362
|
+
|
|
363
|
+
The honest summary is that the gate's reproduction story is the strongest part of this tree today. G4's
|
|
364
|
+
slice criterion now has published evidence and is short of its own wording, not short of an artefact; the
|
|
365
|
+
ordinal criterion is the one whose engine, evidence and wording disagree in a measured way; and G1 remains
|
|
366
|
+
the criterion this corpus cannot meet at all.
|
|
367
|
+
|
|
368
|
+
## What is here, and what is not
|
|
369
|
+
|
|
370
|
+
The first paired certificate pair is published in `docs/RESULTS.md`: on the archived
|
|
371
|
+
Chinese workplace corpus **both backends refuse** at alpha = beta = 0.05, for different
|
|
372
|
+
reasons. One automates 2 of its 32 evaluation cases and one of those is wrong, so its case
|
|
373
|
+
bound is 0.975. The other automates all 32 with one wrong, and the exact case bound is 0.140
|
|
374
|
+
-- above a 0.05 budget. Even had that one request been right, a zero-error run over n=32
|
|
375
|
+
would have bounded at 0.089, so the corpus cannot support a 5% claim at any error count.
|
|
376
|
+
|
|
377
|
+
That is the result, not a shortfall: the corpus holds 64 independent cases, and the
|
|
378
|
+
project's own feasibility table -- computed as a scratch probe before any certificate was written, and now a
|
|
379
|
+
published artefact, `tools/g1_feasibility.py` writing `data/g1_feasibility.json` and `docs/FEASIBILITY.md`
|
|
380
|
+
with every figure recomputed by `verify` in both lanes -- said a 5% claim was out of reach here.
|
|
381
|
+
A tool that certified anyway would have been selling the exact thing this one
|
|
382
|
+
refuses to sell. Both evaluation halves cover the same 32 cases, so the pair is compared
|
|
383
|
+
case by case on identical inputs.
|
|
384
|
+
|
|
385
|
+
Covered by code and by tests: the `choice` primitive, marginal two-sided control, APS and LAC set sizes,
|
|
386
|
+
Clopper-Pearson one-sided bounds, and the gate that turns a certificate into
|
|
387
|
+
`auto` / `escalate` / `abstain`.
|
|
388
|
+
|
|
389
|
+
Written and tested, but not yet published as evidence: the threshold certifier (`certify_threshold.py`),
|
|
390
|
+
drift-adaptive conformal (`drift.py`), and the contamination stratification (`contamination.py`). Each of
|
|
391
|
+
them is a library with unit tests and no committed artefact that `verify` re-derives, which is the
|
|
392
|
+
difference between "implemented" and "certified" in this project -- see the criteria above. The
|
|
393
|
+
group-conditional (Mondrian) surface and its simultaneous per-slice correction
|
|
394
|
+
(`certify_choice.certify_groups`, `correction.py`) left that list when `tools/language_slices.py` published
|
|
395
|
+
`data/slices_language.json` and `docs/SLICES.md`: those are the artefacts the G4 row above is about, and
|
|
396
|
+
`verify` recomputes the run from the committed records field by field.
|
|
397
|
+
|
|
398
|
+
Published, re-derived, and still not the evidence its criterion asks for: the ordinal one-sided severity
|
|
399
|
+
certificate (`severity.py`), reachable as `autorate severity`, committed as `data/cert_severity_ordinal.json`
|
|
400
|
+
over `data/records_ordinal_synthetic.jsonl`, rendered into `docs/SEVERITY.md` and re-derived by `verify` in
|
|
401
|
+
both lanes. `claim G3` prints `not_measured` beside an artefact that exists, because the criterion is the
|
|
402
|
+
wider sentence -- "multiclass conformal prediction *cannot express* a one-sided ordinal guarantee" -- and the
|
|
403
|
+
control that would establish the contrast has now been run and did not go that way: at the corner of the
|
|
404
|
+
generator where the set gate certifies at all, its interval already yields the bound. What survives is
|
|
405
|
+
narrower and measured, and the narrowing lives in the frozen G3 note rather than in a re-worded criterion. Its
|
|
406
|
+
population is synthetic ordinal data with known answers: no committed records file in this checkout carries a
|
|
407
|
+
`qtype="score"` record, and the artefact's own envelope says so, so nothing here is a measurement of a shipped
|
|
408
|
+
model's ordinal risk.
|
|
409
|
+
|
|
410
|
+
Not implemented at all: per-ask `noul` budgets. The `noul` question type is read, counted and quarantined
|
|
411
|
+
by the same loaders as the others, and there is no certifier for it.
|
|
412
|
+
|
|
413
|
+
`docs/superpowers/specs/` states the design; `docs/superpowers/plans/` states the order.
|
|
414
|
+
|
|
415
|
+
Read `docs/ERRATA.md` before quoting any number from this project's history, and
|
|
416
|
+
`docs/VERIFICATION.md` for which external claims were checked against sources and which
|
|
417
|
+
were withdrawn.
|