# content-missing-stop-condition Detect open-ended loop instructions (keep monitoring, poll, retry) without a stopping condition | | | |---|---| | **Severity** | warning (disabled) | | **Autofix** | - | | **Since** | v0.17.0 | | **Category** | [Content Intelligence](content-intelligence.md) | ## Why Agents follow instructions literally. "Keep monitoring the PR for feedback" with no bound tells an agent to loop forever — burning tokens, holding a session open, or polling an API until something external kills it. Frontier-model prompting guidance (e.g. OpenAI's GPT-5.6 prompting guide) lists stopping conditions and success criteria among the few things a prompt should always keep: define the destination, not just the activity. The rule finds open-ended loop instructions — "keep monitoring", "keep checking", "poll for", "continuously check", "retry when" — and flags them when the surrounding paragraph contains no stopping condition: no "until", no "stop after N minutes", no "at most N attempts", no count, timeout, or exit criteria. Loop adverbs must sit next to a base-form activity verb in imperative position, so descriptive prose never fires: "the daemon continuously reconnects", "in-cluster pollers continuously check", and "the tool is run repeatedly" all describe behavior rather than order it. Also skipped: table rows ("Watch for crypto errors" is a matrix entry), headings ("### Poll for Bot Response" names a section), colon-terminated captions directly above a code fence — when the loop is operationalized in the code block below, that code is where the bound lives — and prohibitions ("Avoid polling the status endpoint", "Never poll the API", "use webhooks instead of polling" forbid the loop, they don't start one). The word "once" only counts as a stopping condition in bounding positions — "only once", "retry once", "at most once", or clause-final ("rerun the drain job once."). As a subordinating conjunction it *starts* a loop rather than bounding it: "Once the PR is open, keep monitoring CI" is still flagged as open-ended. This rule is **opt-in** (`enabled: false` by default): monitoring language is common in prose that never reaches an agent verbatim. Enable it for repositories whose instruction files drive autonomous agents. ## Examples **Bad (unbounded loop):** ```markdown After opening a PR, keep monitoring for reviewer feedback and address comments as they arrive. ``` **Good (bounded — same activity, explicit stop):** ```markdown After opening a PR, keep monitoring for reviewer feedback and address comments as they arrive. You may stop monitoring 20 minutes after the last push. ``` **Good (bounded retry):** ```markdown Retry when the smoke-test job fails with a registry pull error; give up after 3 attempts and page the infra channel instead. ``` ## How to fix Add the bound in the same paragraph as the loop instruction. Any of these forms count: - a condition: "until CI passes", "stop once the PR merges" - a count: "at most 3 retries", "up to 5 times" - a time budget: "for 20 minutes", "stop after 1 hour", "with a 10-minute timeout" Tune the rule in `.skillsaw.yaml`: ```yaml rules: content-missing-stop-condition: enabled: true severity: warning extra-loop-patterns: # project phrasing that starts a loop - '\bbabysit\b' extra-terminator-patterns: # project phrasing that bounds one - '\bend\s+of\s+shift\b' ``` ## Configuration ```yaml rules: content-missing-stop-condition: enabled: false # true | false | auto severity: warning ``` | Parameter | Description | Default | |-----------|-------------|---------| | `extra-loop-patterns` | Additional regex patterns that indicate open-ended looping activity (e.g. project-specific phrasing like 'babysit') | `[]` | | `extra-terminator-patterns` | Additional regex patterns that count as a stopping condition when found in the same paragraph as a loop instruction | `[]` | *Run `skillsaw explain content-missing-stop-condition` to see this documentation and the rule's effective configuration in your terminal.*