Skip to content

[M12] Detect no-yield loops with bounded evidence classification #103

Description

@Teakowa

Parent: #99
Discovered by: wrightkit/agent-lab#68

Goal

Add a first-party M12 lint/stability rule that detects loops whose repeating paths do not yield, while distinguishing the static fact "no yield on a repeating path" from stronger runtime-risk claims such as unbounded execution.

Context

Wright v0.1.0 currently has min-wait-loop, which covers loops that yield at the Workshop minimum wait rate, but a loop whose body contains no yield at all can produce zero findings.

This gap was discovered through the first real agent-lab consumer integration rather than synthetic roadmap expansion, so it is valid corpus/consumer evidence for #99.

Repro

Fixture loop-waitless.opy:

globalvar loopCount

rule "waitless loop":
    @Condition getTotalTimeElapsed() > 5

    loopCount = 0
    while loopCount < 10:
        loopCount += 1

wright lint loop-waitless.opy -f json currently returns ok: true with zero findings. The existing Workshop Agent analyzer reports the construct as workshop.performance.waitless-loop.

Required analysis boundary

Do not mechanically copy the existing Workshop Agent severity semantics.

Wright should separate facts that can be proven statically from stronger risk classification:

  • Static fact: a repeating control-flow path contains no recognized yield/suspension point.
  • Boundedness/iteration evidence: whether the loop is statically bounded, obviously unbounded, or unknown.
  • Risk/severity: derived conservatively from the available evidence and documented limitations.

For example, a provably small bounded loop with no yield is not equivalent to while true with no yield, even though both share the no-yield property.

Scope

  • Define the Wright-owned rule ID and evidence classification for no-yield loop detection.
  • Detect no-yield repeating paths using existing semantic/CFG services where practical.
  • Distinguish clearly between:
    • no-yield + provably/obviously unbounded repetition;
    • no-yield + statically bounded repetition;
    • no-yield + boundedness unknown.
  • Choose default severity based on evidence rather than treating every no-yield loop as equally blocking.
  • Add positive/negative fixtures, including at minimum:
    • an obviously unbounded no-yield loop;
    • a bounded no-yield loop;
    • a loop containing a valid yield that must not fire as no-yield.
  • Include the agent-lab repro/evidence in rule documentation or acceptance evidence.
  • Preserve structured rule IDs, source spans, severity configuration, and machine-readable output through the M12 lint contract.

Non-goals

  • Claiming exact server CPU cost from static analysis.
  • Treating all no-yield loops as guaranteed crashes.
  • Automatically inserting waits or rewriting control flow.
  • Expanding unrelated OPY syntax merely to improve rule coverage.

Acceptance criteria

  • wright lint reports a structured no-yield finding for an obviously unbounded no-yield loop.
  • A loop with a recognized yield does not produce the no-yield finding.
  • A statically bounded no-yield loop is represented with evidence/severity that does not overstate it as equivalent to an unbounded loop.
  • Unknown boundedness is represented explicitly rather than guessed.
  • Positive/negative regression fixtures cover the rule and its evidence classes.
  • At least one agent-lab/real-consumer case is included as linked evidence.
  • [M12 acceptance] Verify tooling-first lint and stability platform #100 independently verifies the rule as part of M12 acceptance.

Relationships

Activity

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

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions