Skip to content

fix(pr-pipeline): judge floor-file reflective references by position, not count #11048

Closed as not planned

Description

@kyle-sexton

Problem

#10966's floor-shrink judge counts reflective, dunder, import and frame references in the head against the base. The independent security review of 081662b showed that a PR can trade an existing reference for a new one, so the count does not rise:

  • Python: remove an existing getattr(...) in babysit_risk.py, then add getattr(lambda: 0, "__glob" "als__")["FLOOR_" "CLASSES"] = (). floor-ast.py exits 0, and FLOOR_CLASSES goes from 110 rows to 0 when the module loads.
  • JS: [].constructor.constructor("...")() passes JS_DYNAMIC, and so does a prototype patch with no token at all (Array.prototype.some = function () { return false; };).

None is HIGH: the owner's Q5 decision accepts that a logic edit to a lane-armed file merges on the two bound reviews plus the pr-merge/lane-armed attestation. These close defense-in-depth gaps on top of that residual.

Fix

  • floor-ast.py: compare a multiset of each reflective or dunder reference's source text, together with its enclosing function, instead of a count per name. Refuse a getattr/setattr/delattr whose name argument is not a literal identifier. Refuse string concatenation whose parts join into a dunder name or a floor table name.
  • lane-armed.mjs JS_DYNAMIC: add constructor, prototype, getPrototypeOf and setPrototypeOf.
  • Decide on evidence whether a logic judge (for example an independent model pass over floor-file diffs, bound to the head) is worth its cost, compared with the post-merge hub audit.

Acceptance

  • Each bypass above has a failing-then-passing test.
  • A pure logic edit with no new reflective use still passes.
  • An independent security review of the change finds no HIGH/CRITICAL.

Refs: #10966

Activity

  1. added
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 29, 2026
  2. github-actions commented on Oct 29, 2026

    @github-actions
    Contributor

    Proposed work class: work-class: scoped
    Basis: automated intake triage; the lanes App applied this class.

    Size: Medium
    Complexity: Medium
    Uncertainty: Knowable
    Flags: none
    Blocked by: none

    Understood: the floor-shrink judge from #10966 counts reflective and dunder references per name, so a PR can swap one reference for another without the count rising. The issue gives Python and JS bypasses. It proposes comparing a multiset of reference source text plus enclosing function in floor-ast.py, refusing non-literal getattr/setattr/delattr names, and extending JS_DYNAMIC in lane-armed.mjs. It also lists acceptance tests.

    The third Fix bullet, whether a logic judge is worth its cost, is an evidence-gathering step. The two concrete fixes don't depend on it. No duplicates found among the open issues.

    Automated triage, applied by the lanes App.

  3. added
    priority: mediumReal value, no hard deadline; normal backlog flow.
    and removed
    needs-triageNot yet classified. Floor until a type and one priority tier are set.
    on Oct 29, 2026
  4. added
    status: readyTriaged, unblocked, and fully specified; eligible to pick up.
    work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.
    admission-deferredAdmitted but waiting for WIP room; the hourly work-unblock sweep labels it agent-ready.
    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.
    and removed
    admission-deferredAdmitted but waiting for WIP room; the hourly work-unblock sweep labels it agent-ready.
    on Oct 29, 2026
  5. kyle-sexton commented on Oct 29, 2026

    @kyle-sexton
    MemberAuthor

    Closing as moot. The floor-shrink judge this hardens (floor-ast.py, lane-armed.mjs) lived in #10966, which the owner closed unmerged after decision Q15 ("We shouldn't really have any path restrictions at all"). #11058 replaces it with one switch, merge.diff-check.path-holds. Hardening returns as a config edit once open issues and PRs reach 0.

  6. changed the title [-]fix(pr-pipeline): judge floor-file reflective references by position, not count[/-] [+]fix(pr-pipeline): judge floor-file reflective references by position, not count (hardening deferred)[/+] on Oct 30, 2026
  7. changed the title [-]fix(pr-pipeline): judge floor-file reflective references by position, not count (hardening deferred)[/-] [+]fix(pr-pipeline): judge floor-file reflective references by position, not count[/+] on Oct 30, 2026
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

    agent-readyFully specified and briefed; eligible for autonomous pickup from the frontier.priority: mediumReal value, no hard deadline; normal backlog flow.status: readyTriaged, unblocked, and fully specified; eligible to pick up.work-class: scopedA briefed fix or small feature; blast radius bounded by the brief, tests exist.

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions