Skip to content

test(admission): restore the dropped commitments assertion — as the one it was protecting - #67

Merged
stranske merged 5 commits into
mainfrom
claude/eager-nightingale-22ae5f
Aug 23, 2026
Merged

test(admission): restore the dropped commitments assertion — as the one it was protecting#67
stranske merged 5 commits into
mainfrom
claude/eager-nightingale-22ae5f

Conversation

@stranske

Copy link
Copy Markdown
Owner

Workflow Source

Started from:

  • GitHub issue: #
  • Direct PR / remote GitHub work
  • Local Codex/user request
  • Automation run
  • Review follow-up from PR #
  • Sync / maintenance campaign
  • Dependabot or dependency update
  • Do not automate

Automation intent:

  • Verifier should review this
  • Keepalive may manage this PR
  • Human-only unless checks fail

Notes:
Follow-up to the ruff pass in claude/ci-conform-format-lint (14ccb6d), which correctly removed a
dead binding but deliberately left the missing assertion uninvented. This is that assertion.

Summary

capability_admission._selftest computed

cited = {d["record"] for d in com["dangling_citations"]}

and asserted nothing on it — under a section header claiming "the real historical failure must be
detected, not hypothetically detectable"
and a comment saying the assertion "must never be quietly
dropped"
. A value computed for a check that no longer checks is this repo's founding defect in
miniature, so the binding was right to go; but the header's claim went unenforced with it.

What the assertion should be — not the one that was there

Two findings settle it:

  • assert "2026-07-15-range-lane-trial-review.md" in cited cannot be restored. That record has
    since been written, so the live dangling set is empty wherever the audit ledger exists. This is
    exactly the "if someone fixes that line" branch the old comment anticipated.
  • assert not cited is not worth restoring. test_dated_promises_left_an_artifact already
    asserts the strongest available claim on the live set — that both lists are empty. A weaker copy
    in the selftest adds nothing.

…and the synthetic-file check below it is not sufficient

That is the real hole. _probe_commitments always passes an explicit root=, so nothing in the
suite exercises root or HERE
. A default that stopped resolving to the checkout — module
relocated, SCAN_SUFFIXES narrowed, SKIP_NAMES widened, iterdir over the wrong directory —
returns clean: True over zero files, and both the selftest's isinstance(com["clean"], bool)
and the pytest emptiness assertion stay green. That is verify.py's vacuous zero-exit one level up:
the check runs, reads green, and looks at nothing.

The change

New _probe_live_root, called from the same synthetic-empty-AUDITS harness that already makes
_probe_commitments machine-independent (with no records in existence every dated citation dangles,
so the verdict is identical on the owner's machine and on a bare CI runner):

Assertion What it catches
Non-vacuity the default-root scan must surface the tree's own dated citations — 4 today: CLAUDE.md, README.md, completion_event_adapter.py, and orchestrate.sh:109, the motivating line
Provenance each report's file:line must actually contain the record it names. The probe only ever checks record, so a right-record/wrong-line report passes it — and "go look here" is this gate's entire output
The skip this file must never appear in its own report. It cites two dated records in its own docstring because it documents the detector; a finding clearable only by deleting that documentation is a permanently-red gate, and a permanently-red gate gets switched off
No ledger, no verdict the fail-open branch must return "nothing found", never a verdict it could not compute. Pointed at a nonexistent path so it runs on the ledger machine too, not only where the ledger happens to be missing

Testing

python3 verify.py (not a per-file loop): 387 passed, 0 failed, 0/26 skipped, 83/83 selftests,
43/43 can-fire, 5/5 gates, commitments clean.

Floor and ceilings untouched — no new pytest test and no new skip, so nothing moved.
ruff check --select E4,E7,E9,F and black --check --line-length 100 clean, so this does not
re-introduce the F841 that removed the binding. Adds 0.13s to the selftest.

Deliberate-break → revert, all four reverted clean

  1. root or HEREroot or (HERE / "config") — non-vacuity fires. Under the same break,
    _probe_commitments passes and test_dated_promises_left_an_artifact passes (1 passed)

    that is the proof the hole was real and unguarded.
  2. enumerate(splitlines(), 1), 0) — provenance fires, naming CLAUDE.md:143.
  3. SKIP_NAMES emptied — the self-report check fires. The first draft did not. It asserted
    not reported & SKIP_NAMES, comparing the report against the very set whose failure it was meant
    to catch, so emptying the set made it vacuously true. Caught only by the break test, and rewritten
    as a literal. Recorded in the comment: the first attempt at the fix reproduced the defect.
  4. the skipped key removed from the no-ledger return — the fail-open check fires.

For the reviewer

  • Dedup (CLAUDE.md §0), recorded in the capability-admission-gate ledger notes rather than only
    here: grepped by concept for scan-reaches-the-tree / vacuity / provenance coverage. The only three
    things that assert on commitments() are _probe_commitments (synthetic root), the selftest shape
    check, and the pytest emptiness test. Not present; extended the existing gate rather than adding
    one. No new capability and no rail/role change, so ARCHITECTURE.md and the diagram are unaffected.
  • Non-vacuity depends on the tree citing ≥1 dated record. All four anchor files are tracked, so
    this holds in a CI checkout. Should the tree ever legitimately stop citing dated records, the live
    check has genuinely become vacuous and the assertion fails loudly saying so — that is the intended
    failure, not a false alarm.
  • Merge conflict expected with claude/ci-conform-format-lint (14ccb6d). This branch is cut from
    af6654d, so the cited line still existed here; both sides remove it.
  • The exec mirror is deliberately NOT synced. That manual gap is the circuit breaker between an
    agent's change and the dispatcher — run orch-sync-mirror.sh only after this merges.

🤖 Generated with Claude Code

…ne it was protecting

`capability_admission._selftest` computed `cited = {d["record"] for d in
com["dangling_citations"]}` and asserted nothing on it, under a section header claiming "the real
historical failure must be detected, not hypothetically detectable" and a comment saying the
assertion "must never be quietly dropped". A value computed for a check that no longer checks is
this repo's founding defect in miniature, so the binding was right to go — but the header's claim
went unenforced with it.

WHAT THE ASSERTION SHOULD BE. Not the one that was there. Two findings settle it:

  * `assert "2026-07-15-range-lane-trial-review.md" in cited` cannot be restored: the record has
    since been WRITTEN, so the live dangling set is empty wherever the ledger exists. This is
    exactly the "if someone fixes that line" branch the old comment anticipated.
  * `assert not cited` is not worth restoring either: `test_dated_promises_left_an_artifact` already
    asserts the strongest available claim on the live set — that BOTH lists are empty. A weaker copy
    in the selftest adds nothing.

...and the synthetic-file check below it is NOT sufficient, which is the real hole.
`_probe_commitments` always passes an explicit `root=`, so NOTHING in the suite exercises
`root or HERE`. A default that stopped resolving to the checkout returns `clean: True` over ZERO
files — and the selftest's `isinstance(com["clean"], bool)` and the pytest emptiness assertion BOTH
stay green on a scan that examined nothing. That is verify.py's vacuous zero-exit one level up.

So `_probe_live_root` asserts what the binding was reaching for, on the real tree, off the same
synthetic-empty-`AUDITS` harness that already makes `_probe_commitments` machine-independent (with
no records in existence, every dated citation dangles, so the verdict is identical on the owner's
machine and a bare runner):
  * NON-VACUITY — the default-root scan must surface the tree's own dated citations (4 today:
    CLAUDE.md, README.md, completion_event_adapter.py, and orchestrate.sh:109, the motivating line).
  * PROVENANCE — each report's file:line must actually contain the record it names. The probe only
    ever checks `record`, so a right-record/wrong-line report passes it, and "go look here" is this
    gate's entire output.
  * THE SKIP — this file must never appear in its own report. It cites two dated records in its own
    docstring because it documents the detector; a finding clearable only by deleting that
    documentation is a permanently-red gate, and a permanently-red gate gets switched off.
  * NO LEDGER, NO VERDICT — the fail-open branch must return "nothing found", never a verdict it
    could not compute. Pointed at a nonexistent path so it runs on the ledger machine too.

DELIBERATE-BREAK -> REVERT, all four reverted clean:
  1. `root or HERE` -> `root or (HERE / "config")`: non-vacuity fires. Under the SAME break,
     `_probe_commitments` PASSES and `test_dated_promises_left_an_artifact` PASSES (1 passed) —
     which is the proof the hole was real and unguarded.
  2. `enumerate(splitlines(), 1)` -> `, 0)`: provenance fires, naming CLAUDE.md:143.
  3. `SKIP_NAMES` emptied: the self-report check fires. FIRST DRAFT DID NOT — it asserted
     `not reported & SKIP_NAMES`, comparing the report against the very set whose failure it was
     meant to catch, so emptying the set made it vacuously true. Caught only by the break test, and
     rewritten as a literal. Worth recording: the first attempt at the fix reproduced the defect.
  4. the `skipped` key removed from the no-ledger return: the fail-open check fires.

Dedup (CLAUDE.md 0), recorded in the `capability-admission-gate` ledger notes: grepped by concept
for scan-reaches-the-tree / vacuity / provenance coverage. The only three things that assert on
`commitments()` are `_probe_commitments` (synthetic root), the selftest shape check, and the pytest
emptiness test. Not present; extended the existing gate rather than adding one. No new capability,
no rail/role change, so ARCHITECTURE.md and the diagram are unaffected.

Verified with `python3 verify.py`: 387 passed, 0 failed, 0/26 skipped, 83/83 selftests, 43/43
can-fire, 5/5 gates, commitments clean. Floor and ceilings untouched — no new pytest test and no new
skip, so nothing moved. Adds 0.13s to the selftest. `ruff check --select E4,E7,E9,F` and
`black --check --line-length 100` clean, so this does not re-introduce the F841 that removed the
binding.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Aug 23, 2026

Copy link
Copy Markdown

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your current included review allowance is based on your included PR review attempts over the past 7 days.

Next review available in: 18 minutes

Limit details: You’ve used the included review currently available. Your 74 included PR review attempts over the past 7 days set your current allowance at 1 review per hour.

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6dcf0d41-2449-48be-b361-78950a2d5d00

📥 Commits

Reviewing files that changed from the base of the PR and between 0d661e3 and 4e694b9.

📒 Files selected for processing (1)
  • capability_admission.py

Comment @coderabbitai help to get the list of available commands.

@agents-workflows-bot

agents-workflows-bot Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Automated Status Summary

Head SHA: d04b554
Latest Runs: ⏳ pending — Gate
Required: core tests (3.12): ⏳ pending, core tests (3.13): ⏳ pending, docker smoke: ⏳ pending, gate: ⏳ pending

Workflow / Job Result Logs
(no jobs reported) ⏳ pending

Coverage Overview

  • Coverage history entries: 1

Coverage Trend

Metric Value
Current 48.08%
Baseline 0.00%
Delta +48.08%
Minimum 70.00%
Status ❌ Below minimum

Top Coverage Hotspots (lowest coverage)

File Coverage Missing
outcomes.py 9.0% 243
watch.py 9.6% 431
capability_recurrence_check.py 10.4% 421
durability_sweep.py 12.2% 339
keepalive_shadow.py 13.0% 282
capability_outcome_bridge.py 13.5% 295
keepalive_outcomes.py 14.0% 339
adversarial.py 14.1% 164
langsmith_fetch.py 14.3% 409
gh_capacity.py 14.6% 228
runtime_ac_panel.py 14.7% 290
capability_advisor.py 14.8% 807
redirect_shadow.py 16.9% 476
cross_repo_lane.py 17.3% 268
experiment_recovery.py 18.4% 164

Low Coverage Files (<50.0%)

File Coverage Missing
outcomes.py 9.0% 243
watch.py 9.6% 431
capability_recurrence_check.py 10.4% 421
durability_sweep.py 12.2% 339
keepalive_shadow.py 13.0% 282
capability_outcome_bridge.py 13.5% 295
keepalive_outcomes.py 14.0% 339
adversarial.py 14.1% 164
langsmith_fetch.py 14.3% 409
gh_capacity.py 14.6% 228
runtime_ac_panel.py 14.7% 290
capability_advisor.py 14.8% 807
redirect_shadow.py 16.9% 476
cross_repo_lane.py 17.3% 268
experiment_recovery.py 18.4% 164

Updated automatically; will refresh on subsequent CI/Docker completions.


Keepalive checklist

Scope

No scope information available

Tasks

  • No tasks defined

Acceptance criteria

  • No acceptance criteria defined

@stranske

Copy link
Copy Markdown
Owner Author

Runner dispatch state for codex on PR #67. Do not edit.

@stranske

stranske commented Aug 23, 2026

Copy link
Copy Markdown
Owner Author

Runner dispatch state for autofix on PR #67. Do not edit.

@github-actions

github-actions Bot commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

Workflow state fingerprint for Agents Gate Followups. Do not edit.

@github-actions

Copy link
Copy Markdown
Contributor

Workflow state fingerprint for Keepalive Loop Reporter. Do not edit.

@github-actions github-actions Bot added the autofix Let bots format/lint automatically label Aug 23, 2026
@stranske

Copy link
Copy Markdown
Owner Author

CI red here is #60's blocker, not this PR — do not fix it here

All five failing jobs (lint-ruff, lint-format, typecheck-mypy, python 3.12, python 3.13)
died at the shared install step, before any tool ran:

Error: .../.github/workflows/autofix-versions.env is required; refusing to install unpinned tooling.

That file is absent from this branch and from main. pr-00-gate.yml:187 pins
reusable-10-ci-python.yml@main — a floating ref — and upstream now hard-requires the pin file at
four call sites (lint / format / typecheck / test), which is exactly the five jobs. PRs #63 and #65
fail identically
, so this is repo-wide.

#60 is already the fix (fix(ci): the Gate was failing on a missing pin file, not on 915 lint findings) — it adds autofix-versions.env, ruff.toml, mypy.ini and drains the tree. Nothing to
duplicate here.

Verified: this PR is green once #60 lands

Non-destructive test merge of this branch against #60's branch — no conflict, even though both
sides delete the same cited line (git merge-tree --write-tree exits 0). Materialised that merged
tree and ran the real gate on it:

pytest:     402 passed, 0 failed, 0/26 max skipped (402 collected; floor 402)
selftests:  84 of 84 modules ran, 0/7 max skipped
5 of 5 gates green — admission: commitments clean
ruff check .            (#60's config, E4/E7/E9/F/I)  All checks passed
black --check -l 100 .                                196 files unchanged

So _probe_live_root also passes #60's wider ruff selection (it adds I), and #60's floor of
402 already accommodates this PR — I add no pytest test and no skip, so no floor edit is needed from
either side.

Merge order

Either order works since the merge is clean, but #60 first is preferable: this PR then arrives on a
base where CI can actually execute, rather than re-running red for a reason it does not own.

🤖 Addressed by Claude Code

Brings in #60 (`autofix-versions.env`, `ruff.toml`, `mypy.ini`, the tree drain), which is what every
red check on this PR was actually waiting for — all five python-ci jobs were dying at the shared
install step before any tool ran.

`capability_admission.py` auto-merged: #60 deletes the bare `cited` binding, this branch deletes it
and adds `_probe_live_root` in its place, so the two agree on the deletion and differ only in what
replaces it. Verified afterwards that the only remaining `cited = {d["record"]...}` in the file is
the docstring quoting it as the thing that was dropped.

ONE conflict, `langsmith-fleet-worker-attempt.json` (add/add): a generated worker-attempt telemetry
snapshot that each CI run rewrites. Resolved to main's copy verbatim, so this PR's diff against main
stays exactly one file. It is a single-object "last attempt" snapshot rather than a log, so taking
either side discards the other by design — not something to repair in a merge.

Net change vs main after the merge: capability_admission.py only, +84/-4.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@stranske

Copy link
Copy Markdown
Owner Author

Conflict resolved, main merged — #60 landed, so the Gate can now actually run

Update to my earlier comment:
#60 has merged (bd6da2e), which is what all five python-ci jobs were waiting for. Merged main
in at df011d4.

capability_admission.py auto-merged. #60 deletes the bare cited binding; this branch deletes
it and puts _probe_live_root in its place — so the two sides agree on the deletion and differ
only in what replaces it. Checked afterwards: the sole remaining cited = {d["record"]...} in the
file is the docstring quoting it as the thing that was dropped.

One conflict, and it was not code: langsmith-fleet-worker-attempt.json (add/add) — the
generated worker-attempt telemetry snapshot each CI run rewrites. Both sides had one (this branch's
recorded PR #67, main's recorded PR #61). Resolved to main's copy verbatim, so this PR's diff
against main stays exactly one file. It is a single-object "last attempt" snapshot rather than an
append log, so taking either side discards the other by design — not something to repair inside a
merge.

Verified on the merged branch, not on a simulation

pytest:     402 passed, 0 failed, 0/26 max skipped (402 collected; floor 402)
selftests:  84 of 84 modules ran, 0/7 max skipped
5 of 5 gates green — admission: commitments clean
ruff check capability_admission.py   (now under #60's ruff.toml)   All checks passed

Net change vs main: capability_admission.py only, +84/−4. #60's floor of 402 needs no edit
from this PR — it adds no pytest test and no skip.

Note for whoever reads the bot trail above: the three "review comments" flagged on this PR were the
gate-summary and two Workflow state fingerprint ... Do not edit. markers. There are zero inline
review threads (/pulls/67/comments → 0), so there was nothing to reply to or resolve.

🤖 Addressed by Claude Code

…ssertion branch

One conflict, in `capability_admission.py`: the selftest's closing summary. #68 added
"per-requirement cutoffs are in the past" and "findability is declarable pre-build"; this
branch added "live-tree scan proven non-vacuous and correctly attributed". Resolved as the
UNION rather than by taking a side — both sides' assertion code is present in the merge, so
dropping either claim would make the summary understate what the selftest proves.

Verified by RUNNING it rather than by reading: `python3 capability_admission.py --selftest`
prints all six claims and exits 0. `.verify-floor.json` did not conflict and needs no edit —
the merge result collects 407, exactly the floor main already records, because this branch
restores an assertion inside an existing selftest rather than adding a collected test.

Ruff and black -l 100 clean across all 196 files.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@stranske
stranske merged commit 4122a07 into main Aug 23, 2026
54 checks passed
@stranske
stranske deleted the claude/eager-nightingale-22ae5f branch August 23, 2026 22:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

autofix Let bots format/lint automatically

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant