From 0f921c1a8d50b57dd0e68d3506dc9ed148d2b8ac Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Tue, 8 Sep 2026 01:33:58 +0000 Subject: [PATCH] Stop agent factory loops: one PR per request, no recursive hunts The 2ccd run opened PRs #73-#149 over ~22 hours by hunting the next YAML key after each micro-PR. Add a session contract so agents finish the user's list on one PR, do not ask to merge, and stop when the work is done. Co-authored-by: jmjava --- .cursor/rules/no-factory-loop.mdc | 59 +++++++++++++++++++++++++++++++ AGENTS.md | 28 +++++++++++++++ milestones/README.md | 12 +++++-- 3 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 .cursor/rules/no-factory-loop.mdc diff --git a/.cursor/rules/no-factory-loop.mdc b/.cursor/rules/no-factory-loop.mdc new file mode 100644 index 0000000..b6b89e4 --- /dev/null +++ b/.cursor/rules/no-factory-loop.mdc @@ -0,0 +1,59 @@ +--- +description: Finish the user's task list on one PR. Do not hunt remaining YAML keys, ask for merges, or open isomorphic micro-PRs. +alwaysApply: true +--- + +# Finish the list. Do not run a factory loop. + +**Incident:** Cloud agent `bc-fd13dd23-…2ccd` (2026-09-07 → 2026-09-08) +ran ~22 hours, opened PRs **#73–#149**, spawned recursive “hunt remaining +bugs / next milestone / fail-closed holes” children, and treated every +leftover YAML key / `or default` coerce as a new milestone + new PR. +That is a **failed run**, not a workflow to copy. + +## Session contract (this repo) + +1. **Finish the user's list.** If they gave numbered or bulleted tasks, do + all of them in this run. Do not pause after item 1 to ask for a merge, + rebase, review, or “should I continue?” +2. **Do not ask the user to merge.** Continue on the same branch. Update + the same PR. They merge when they want. Mentioning a PR link in passing + is fine; blocking on merge is not. +3. **One user request → one branch → one PR** unless they explicitly asked + for separate PRs. “Create or update the PR each turn” means **update + that PR**, not open a new one per file. +4. **Batch isomorphic holes.** Many leftover YAML scalars, `or 0.0` + coerces, or the same fail-closed helper on the next config key belong + in **one** PR (or a stop-and-report list). Not one PR per key. +5. **After the assigned work is done: STOP.** Report what shipped and any + leftover ideas in bullets. Do **not** hunt “remaining bugs”, “next + milestone”, or “fail-closed holes”. Do **not** spawn Cloud / background + agents to continue hunting unless the user asked for those agents. +6. **Isomorphic-patch detector (hard stop).** If the next change is the + same shape as the last — new `milestones/.md`, same + helper, different key name — you are in the factory. Stop. List the + remaining keys for a human. Do not open another PR. +7. **Do not invent a milestone file** unless the user asked for one, or + the work is a real product behavior change (CLI, Manim clock, pipeline, + wizard UX a consumer would notice). Typed YAML on yet another key is + not a product milestone. + +## Caps + +- **Max 1 PR** per user message unless they asked for more than one. +- **Max 1 hunt pass** per run, and only if they asked to hunt. After that + pass ships or reports “nothing product-visible”, stop. +- Do not launch sibling agents named hunt / remaining / next-milestone / + fail-closed-holes unless the user asked. + +## What counts as progress + +Product-visible: CLI behavior, render/sync, wizard UX, a bug a consumer +would hit. + +Not progress: another typed YAML key, another `or default` coerce, another +`milestones/*.md` for one config field, another draft PR that looks like +the last one. + +If you cannot name the consumer-visible bug in one sentence, do not start +the patch. Ask is not required — **stop and report**. diff --git a/AGENTS.md b/AGENTS.md index 4332583..7099b42 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,5 +1,28 @@ # Agent context — documentation-generator (`docgen`) +## Session contract (non-negotiable) + +Cloud agent `bc-fd13dd23-…2ccd` ran ~22 hours (2026-09-07 → 2026-09-08), +opened PRs **#73–#149**, and spawned recursive “hunt remaining bugs” +children. That loop is **forbidden**. Details: +**`.cursor/rules/no-factory-loop.mdc`**. + +- **Finish the user's list** in this run. Do not stop after the first item + to ask for a merge, rebase, review, or permission to continue. +- **Do not ask the user to merge.** Keep working on the same branch and + the same PR. They merge when they want. +- **One request → one branch → one PR** unless they explicitly asked for + separate PRs. Update that PR each turn; do not open a new PR per file + or per YAML key. +- **Batch isomorphic holes** (typed config keys, `or default` coerces, + the same fail-closed helper on the next field) into that one PR — or + stop and list leftovers. Never one-key-per-PR. +- **When the list is done, STOP.** Do not hunt the next milestone, spawn + “hunt remaining / fail-closed holes” agents, or invent + `milestones/.md` as the next task. +- **If the next patch is the same shape as the last** (new milestone file, + same helper, different key): hard stop. Report. Do not open another PR. + ## North star Stable goals for this repository: @@ -90,6 +113,11 @@ Tests should cover **CLI-visible behavior** and contracts that adopters rely on: ## Cursor Cloud specific instructions +- **Session contract first:** see the top of this file and + **`.cursor/rules/no-factory-loop.mdc`**. Finish the assigned list on + **one** PR. Do not ask to merge. Do not start a YAML-key factory or + recursive hunt. `milestones/README.md` **Active** is human-assigned + only; an empty Active line means stop, not “pick the next config key”. - **Virtualenv:** the project is installed editable into **`/workspace/.venv`** (created by the startup update script). Shells do **not** auto-activate it — run `. /workspace/.venv/bin/activate` (or prefix the venv path) before `docgen`, `pytest`, or `ruff`. The `docgen` console script lives at `/workspace/.venv/bin/docgen`. - **System deps are pre-baked in the VM snapshot** (not the update script): `ffmpeg` + `tesseract-ocr` (validation/compose/OCR), plus `build-essential`, `python3-dev`, `libcairo2-dev`, `libpango1.0-dev`, `pkg-config` (needed to build the `manim` extra's `manimpango`/`pycairo` wheels). If a fresh VM ever lacks these, reinstall via apt before `pip install`. - **Standard commands** are in `README.md` / `pyproject.toml` / `.github/workflows/ci.yml`: lint `ruff check src/ tests/`; tests `pytest tests/ -v --tb=short`; **required** `docgen benchmark` (CI job `benchmark`). The CI unit job also exports `PYTHONPATH=src` (not needed locally because of the editable install, but harmless). diff --git a/milestones/README.md b/milestones/README.md index 084a0e3..68b679b 100644 --- a/milestones/README.md +++ b/milestones/README.md @@ -5,10 +5,18 @@ repositories that install `docgen` and maintain their own demo bundle. The library no longer ships an in-repo dogfood; consumers are the integration test of record. -**Active:** **[scene-spec-layout-gaps.md](scene-spec-layout-gaps.md)** — -scene-spec layout gaps must not coerce YAML bools to 1.0. +**Agent stop:** The YAML-key / fail-closed-key hunting program (PRs +**#73–#149**, agent `…2ccd`) is **closed**. Shipping one typed-config +milestone does **not** authorize opening the next key as a new PR. Batch +isomorphic leftovers or stop. See the session contract in `AGENTS.md` and +**`.cursor/rules/no-factory-loop.mdc`**. + +**Active:** none (human-assigned only). Do not invent the next +`milestones/*.md` or PR because this line is empty. **Shipped:** +- **[scene-spec-layout-gaps.md](scene-spec-layout-gaps.md)** — + scene-spec layout gaps must not coerce YAML bools to 1.0 (#148). - **[scene-spec-bool-numerics.md](scene-spec-bool-numerics.md)** — scene-spec `wait_word` / `run_time` / sizes must not coerce YAML bools (#147).