[Split Scope Migration](2) Remind agents to read split-scope on planning prompts - #465
Closed
EdbertChan wants to merge 4 commits into
Closed
Conversation
- A new catstack hook injects a reminder to read the PR-slicing skill on prompts that plan multi-PR or multi-slice work, for Claude, Codex, and Cursor. Review lane: - behavior Safety invariant: - Inject-only and fail-open; the hook never blocks a tool and prints nothing on prompts that do not match. Effectiveness measurement: - `python3 -m unittest discover -s engine/hooks/split-scope/tests -v` exits 0 with at least three firing prompts and three silent prompts. Slice rationale: - One hook with its detector, entrypoints, installers, and tests; the skill text it points at landed in workflow 1. Architectural effect: - Adds one prompt-time injector under engine/hooks/split-scope, registered by install.sh for Claude, Cursor, and Codex. Goal: - Make product/skills/split-scope load on planning prompts without relying on the model to choose it. Motivation: - The skill is only description-triggered today, so multi-PR plans get written without it. Alternative considerations: - Option A (chosen): a new hook shaped like build-the-lever (regex on the prompt, inject a reminder). - Option B: extend engine/hooks/playbook-router; rejected because it only fires on explicit "run <name>" prompts and its fixtures deliberately keep split-scope silent. - Option C: remind at PR-publish time via pr-schema-gate; rejected because the commits already exist by then. Implementation details: - Create the hook directory named in Files, shaped like engine/hooks/build-the-lever, and wire it into install.sh and tests/test_install.py the same way build-the-lever is wired. Non-goals: - No change to product/skills/split-scope, build-the-lever, playbook-router, or pr-schema-gate. - No edits to the repo-root README.md or docs/ecosystem.md tables. - No blocking behavior. Layer: domain Feature state: active Files: - engine/hooks/split-scope/detect.py - engine/hooks/split-scope/claude_prompt_submit.py - engine/hooks/split-scope/codex_prompt_submit.py - engine/hooks/split-scope/cursor_before_submit.py - engine/hooks/split-scope/cursor_post_tool_use.py - engine/hooks/split-scope/state.py - engine/hooks/split-scope/install_claude_hook.py - engine/hooks/split-scope/install_codex_hook.py - engine/hooks/split-scope/install_cursor_hook.py - engine/hooks/split-scope/claude.prompt.hook.json - engine/hooks/split-scope/codex.hook.json - engine/hooks/split-scope/README.md - engine/hooks/split-scope/tests/test_hooks.py - install.sh - tests/test_install.py Change types: - engine/hooks/split-scope/detect.py: create - engine/hooks/split-scope/claude_prompt_submit.py: create - engine/hooks/split-scope/codex_prompt_submit.py: create - engine/hooks/split-scope/cursor_before_submit.py: create - engine/hooks/split-scope/cursor_post_tool_use.py: create - engine/hooks/split-scope/state.py: create - engine/hooks/split-scope/install_claude_hook.py: create - engine/hooks/split-scope/install_codex_hook.py: create - engine/hooks/split-scope/install_cursor_hook.py: create - engine/hooks/split-scope/claude.prompt.hook.json: create - engine/hooks/split-scope/codex.hook.json: create - engine/hooks/split-scope/README.md: create - engine/hooks/split-scope/tests/test_hooks.py: create - install.sh: modify - tests/test_install.py: modify Acceptance criteria: - Pass condition: `python3 -m unittest discover -s engine/hooks/split-scope/tests -v` exits 0. - Pass condition: `python3 scripts/check_hook_test_coverage.py engine/hooks/split-scope` exits 0. - Pass condition: `python3 -m unittest discover -s tests -p "test_install.py"` exits 0. Exit code: 0 Invoker-Finalize-Id: 3f68b610-4787-4c58-ac16-2d7b57d64b71
- The hook's own tests, the hook-coverage gate, and the install tests all pass. Review lane: - proof Safety invariant: - Proof-only; this read-only check changes no files. Effectiveness measurement: - The command below exits 0. Slice rationale: - One proof step for the one hook added. Architectural effect: - None; verification only. Goal: - Prove the hook fires and stays silent as specified and installs cleanly. Motivation: - The tests run the real entrypoint, so a pass means the reminder really reaches the agent. Alternative considerations: - Option A (chosen): run the hook tests, the coverage gate, and the install tests together. Implementation details: - Run the three checks in order. Non-goals: - No product edits here. Layer: app_regression Feature state: active Exit code: 0 Invoker-Finalize-Id: 3c4cda3d-9ed5-4c1e-ad20-77eea6661f3a
- No ephemeral handoff files are left behind before the PR merge gate. Review lane: - proof Safety invariant: - This read-only check changes no files. Effectiveness measurement: - `bash scripts/scrub-handoff-artifacts.sh` exits 0. Slice rationale: - The scrub check runs last and stays separate from implementation. Architectural effect: - No architecture change. Goal: - Confirm no handoff artifacts remain. Motivation: - Uncommitted handoff files do not flow across worktrees. Alternative considerations: - Option A (chosen): a read-only absence check. Implementation details: - Run the handoff scrub script without --apply. Non-goals: - Do not modify source files. Layer: e2e_regression Feature state: active Exit code: 0 Invoker-Finalize-Id: 59c6c4c7-5d07-4094-873e-8b31032b2bb1
…91ba4f93-cae552d5 — Review claim: - No ephemeral handoff files are left behind before the PR merge gate. Review lane: - proof Safety invariant: - This read-only check changes no files. Effectiveness measurement: - `bash scripts/scrub-handoff-artifacts.sh` exits 0. Slice rationale: - The scrub check runs last and stays separate from implementation. Architectural effect: - No architecture change. Goal: - Confirm no handoff artifacts remain. Motivation: - Uncommitted handoff files do not flow across worktrees. Alternative considerations: - Option A (chosen): a read-only absence check. Implementation details: - Run the handoff scrub script without --apply. Non-goals: - Do not modify source files. Layer: e2e_regression Feature state: active
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_413c7c7e-6a6d-427e-bf15-2e79873b136c) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Today product/skills/split-scope only loads when the model decides to pick it
from its description. This workflow adds a catstack hook,
engine/hooks/split-scope/, that injects a short reminder to read the skill
whenever a prompt plans a PR stack, several PRs, a break-up into slices, or a
migration. It copies the shape of engine/hooks/build-the-lever/: a regex
detector, fail-open entrypoints for Claude, Codex, and Cursor, installers,
and tests that pin when it fires and when it stays silent.
Gated on workflow 1 (the split-scope section) merging.
Test Plan
Test Plan
python3 -m unittest discover -s engine/hooks/split-scope/tests -v && python3 scripts/check_hook_test_coverage.py engine/hooks/split-scope && python3 -m unittest discover -s tests -p "test_install.py"— Review claim:The hook's own tests, the hook-coverage gate, and the install tests all pass.
Review lane:
proof
Safety invariant:
Proof-only; this read-only check changes no files.
Effectiveness measurement:
The command below exits 0.
Slice rationale:
One proof step for the one hook added.
Architectural effect:
None; verification only.
Goal:
Prove the hook fires and stays silent as specified and installs cleanly.
Motivation:
The tests run the real entrypoint, so a pass means the reminder really reaches the agent.
Alternative considerations:
Option A (chosen): run the hook tests, the coverage gate, and the install tests together.
Implementation details:
Run the three checks in order.
Non-goals:
No product edits here.
Layer: app_regression
Feature state: active
bash scripts/scrub-handoff-artifacts.sh— Review claim:No ephemeral handoff files are left behind before the PR merge gate.
Review lane:
proof
Safety invariant:
This read-only check changes no files.
Effectiveness measurement:
bash scripts/scrub-handoff-artifacts.shexits 0.Slice rationale:
The scrub check runs last and stays separate from implementation.
Architectural effect:
No architecture change.
Goal:
Confirm no handoff artifacts remain.
Motivation:
Uncommitted handoff files do not flow across worktrees.
Alternative considerations:
Option A (chosen): a read-only absence check.
Implementation details:
Run the handoff scrub script without --apply.
Non-goals:
Do not modify source files.
Layer: e2e_regression
Feature state: active
Revert Plan
Revert Plan
git revert <sha>Note
Low Risk
Read-only, fail-open prompt injection with no auth, data, or product behavior changes; risk is limited to occasional extra context in agent sessions.
Overview
Adds a new split-scope catstack hook (
engine/hooks/split-scope/) that injects a short reminder to read the existingproduct/skills/split-scopeskill when a user prompt looks like multi-slice / multi-PR planning (PR stacks, “split this into…”, migration plans, etc.), instead of relying on the model to pick the skill from its description alone.The implementation mirrors build-the-lever: shared regex detection in
detect.py, fail-open Claude/Cursor/Codex prompt hooks (Cursor defers inject topostToolUse), installers, hook JSON fragments, and unit tests that pin fire vs. silent cases.install.shandtests/test_install.pywire the hook into Claude, Cursor, and Codex installs.Reviewed by Cursor Bugbot for commit fceccee. Bugbot is set up for automated code reviews on this repo. Configure here.