Keel
keel route
Independence cannot be manufactured, but it can be routed.
Every ungrounded verification edge in openai-python, paired — where a pairing exists — with an anchored producer already present in the same measurement. Nothing here invents an anchor, and nothing here has been applied.
| target | openai-python |
|---|---|
| revision | d4c151d92ba713e56518a4483d3b7918dd1be838 |
| source report | reports/openai-python.json |
| generated | 2026-07-25T05:17:57.179Z |
| status | proposed (all 3) |
anchored / (anchored + self_referential + unknown)
The second number is a projection: the ratio this target would carry if a human applied every route below and the applied routes measured as anchored on re-measurement. It is arithmetic on a hypothetical. It is not written to any report, it is not fed back into the grounding ratio, and no proposal on this page has been applied. Projected counts, for the same conditional: anchored 11 · self_referential 1 · unknown 1 · not_a_check 12. The delta is two different claims and is reported as two: 1 re-grounded — an existing check whose signal moves outside the write boundary, the proposition it asserts unchanged — and 0 constructed — a not_a_check node that becomes a check, entering the denominator as well as the numerator. Only the first repairs something that was already being claimed.
Scope. Keel measures the shape of verification, not its quality. A repo can be 100% anchored with terrible tests. Anchoring says the signal comes from outside; it does not say the signal is sufficient.
Routes — 1 routable · 2 unroutable
Existing checks whose signal could come from somewhere they cannot write. Cheapest effort on top. no route is a first-class answer: it means the fix needs a policy decision rather than a rewiring, and it is reported here rather than dropped.
| what's ungrounded | route to | why that's anchored | effort |
|---|---|---|---|
.github/workflows/python-version-review.yml#125-validate-and-package-the-assessment
self_referential |
.github/workflows/python-version-review.yml#58-snapshot-official-lifecycle-and-public-usage-data
anchored
|
The measured argument records that the one consequential output of this step is `action_required`, the sole condition gating the open_issue job at line 174, and that it is currently produced by matching the first line of a file the model wrote against two marker strings — the model decides whether its own finding is actionable. Step 58, in this same job, has already written `$PYTHON_RELEASE_CYCLE` from https://peps.python.org/api/release-cycle.json under `curl --fail`, and has already proven with `jq --exit-status` that every entry carries `status` and `end_of_life`. Those two fields decide the same proposition the marker is standing in for — whether a Python version this repo still declares support for has passed the point the release managers published for it. The producer of that fact is the CPython release-cycle publication: the openai-python maintainers have no write path to peps.python.org, and no prompt, permission profile, or model output can move an end_of_life date. The signal stops originating inside the run and starts originating at the body that sets the dates. Named limit: this re-grounds the lifecycle-date half of the trigger only. The usage-share judgement the model also makes from pypistats — how much adoption is low enough to drop a version — is a policy call, and after this change it lives in the advisory prose where a human weighs it, not in the gate. |
wiring |
.github/CODEOWNERS#codeowners
unknown |
no route | The proposition this edge would assert is that a change cannot merge without approval from someone outside its author's write boundary. Every anchored node in this report is a machine reading committed text or bytes on the wire — ruff, mypy, pyright, pytest, and one HTTP fetch of Python lifecycle data. Not one of them observes a human reviewing, or observes a merge being blocked. There is no candidate here that asserts the proposition, so any route would be a substitution of a different claim, and the measured verdict's own reason for `unknown` — that the requirement, if it exists, lives in GitHub settings this clone cannot read — is not something a rewiring can reach. |
— |
.github/workflows/python-version-review.yml#104-ask-codex-to-assess-the-policy
self_referential |
no route | This step's product is an assessment of whether the version-support policy is well judged. The only candidate whose subject matter is even adjacent, step 58, asserts something strictly narrower: that two third-party payloads were fetched and are well-shaped. Wiring the model invocation onto the fetch would say the assessment is grounded because its input arrived, which grounds nothing — the output is still a model's prose, produced by the same class of system that writes the code under review, and step 58's exit code is silent about its content. There is no rewiring that makes 'ask a language model for a recommendation' read from an exogenous producer; the producer IS the model. Note that the gate this step feeds IS routable and is proposed separately at line 125 — the trigger can be moved outside the boundary while the explanation stays a model's. |
— |
Construct — not yet.
A route makes a check read a signal from outside itself. It does not pair that check with a counter-metric, name who arbitrates when the pair disagrees, or set a cadence at which the route is re-audited. Those three fields are declared in schemas/route.ts and are filled by keel construct, which is not built. The columns are empty by construction, not by omission.
| route | pairedWith | arbitratedBy | auditEvery |
|---|---|---|---|
| .github/workflows/python-version-review.yml#125-validate-and-package-the-assessment | — | — | — |