Skip to content

pv verify-bindings is one-directional: an equation can be declared and never bound, and no PR-time gate sees it #2797

Closed

Description

@noahgift

What is wrong

contracts/binding.yaml is checked in one direction only. pv verify-bindings <file>
answers "does every binding name a function that exists?" — it reported
53/55 binding functions verified in source plus 2 ghosts on main today. It does not ask
the mirror question: does every equation a contract declares have a binding?

So an equation can be declared and never registered, and nothing at PR time sees it:

  • pv validate contracts/<f>.yaml — exit 0. It validates the contract in isolation.
  • pv verify-bindings contracts/binding.yaml — exit 0 on the gap. Wrong direction.
  • pv lint contracts/ — Result: PASS.
  • dogfood.sh is not in ci.yml.

How it was found

contracts/pr-review-skill-v2.yaml declared five equations and binding.yaml bound
four. duplication_coverage_is_recorded_per_surface, added by PRREV-009 and enforced by
scripts/check_pr_review_receipt.sh with two committed discrimination fixtures
(row-23/row-24), had no entry. The gap survived from PRREV-009 to PRREV-013 and was found
by an adversarial review reading the two files side by side — not by any gate.

The under-reporting direction is the mirror of the over-reporting the #2644 audit found, and
the registry's own PRREV-001 comment already states the rule it violated:

a binding left at pending after its implementation ships is a registry that under-reports
its own coverage

An equation with no entry under-reports harder than one left at pending.

Remedy

pv verify-bindings (or a new pv coverage --equations) should also enumerate
contracts/*.yaml equations and fail on any that no binding names — the same shape as the
existing ghost-binding check, run the other way. Falsifier: delete one binding.yaml entry
for an equation that has one, and require RED.

Scope note: this is a contract-system hole, not a defect in one contract. PRREV-013
registered the missing equation; it did not and cannot close the class from inside
binding.yaml.

Activity

  1. noahgift commented on Sep 10, 2026

    @noahgift
    MemberAuthor

    Closed by paiml-implement — #2870

  2. noahgift commented on Sep 10, 2026

    @noahgift
    MemberAuthor

    Reopened by the PMAT-1100 triage orchestrator: this is a child of its epic (sub-issue), not a duplicate of it — the lane's close was wrong. Filed to a train below.

  3. added this to the 0.68.0 milestone on Sep 10, 2026
  4. added
    automationBot-maintained dashboard, not a defect — skip in triage
    P1High priority
    on Sep 11, 2026
  5. modified the milestones: 0.68.0, 0.69.0, 0.73.0, 0.70.0 on Sep 16, 2026
  6. noahgift commented on Sep 23, 2026

    @noahgift
    MemberAuthor

    triage 2026-09-23 (aprender-dd, standing triage owner): milestoned to 0.70.0, theme Fast Train (CI, gates, pv, release tooling, hygiene); it moved out of backlog (the 2026-09-17 overflow bucket, not a release).

  7. added
    kind:codeWork is a code change (derived rule, #4159)
    on Sep 24, 2026
  8. modified the milestones: 0.70.0, backlog on Sep 24, 2026
  9. noahgift commented on Sep 24, 2026

    @noahgift
    MemberAuthor

    Closed by paiml-implement — folded into epic #2556 (triage evidence/triage-1418.md)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1High priorityautomationBot-maintained dashboard, not a defect — skip in triagekind:codeWork is a code change (derived rule, #4159)

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions