Scope Freeze
Purpose
Prevent uncontrolled changes by defining a narrow, enforceable boundary. This freezes write scope, not discovery.
When to use
Immediately before editing files or running state-changing commands.
Inputs
- SPEC.md / PLAN.md / TODO.md
- Selected task
- Current repo state
- Git base used to judge the implementation diff
Workflow
Name the exact task.
List allowed files/folders as exact paths, directory prefixes, or globs.
Do not use repo-wide catch-all patterns (
*,**,**/*) inAllowed writes. If the task genuinely spans multiple areas, enumerate the narrowest relevant prefixes and set a changed-file budget.List read-only files/folders.
List forbidden paths and operations.
Set max files changed and rename/deletion rules when helpful.
List allowed commands.
List compatibility seams and test-integrity triggers before editing.
Define clear stop condition.
Note that reads/searches are allowed unless explicitly forbidden.
Persist the canonical block as
SCOPE.mdbefore the first implementation write when the route invokesscope-freezeandscripts/scope_gate.pyis available.After the implementation diff is complete, run:
python scripts/scope_gate.py --base <frozen-base>Treat scope-gate
FAILas a hard stop: revert the violating write or renegotiate scope before continuing. TreatREVIEW_REQUIREDas unresolved review, not implicit permission.
Do not widen SCOPE.md after an out-of-scope change merely to make the gate pass. A legitimate scope expansion must be surfaced and agreed before the newly allowed write.
Outputs
Canonical output block:
SCOPE FREEZE
Task: ...
Allowed writes: ...
Read-only: ...
Forbidden: ...
Compatibility seams to preserve:
- Public imports / APIs: ...
- CLI behavior: ...
- Output schema: ...
- Fixture/data meaning: ...
- Existing tests that must remain meaningful: ...
Test integrity:
- Existing tests may be added to: yes/no
- Existing tests may be changed only if: ...
Review required if:
- tests changed
- dependencies changed
- protected paths touched
- compatibility seams changed
Max files changed: ...
Renames allowed: yes/no
Deletions allowed: yes/no
Allowed commands: ...
Stop when: ...
Invalid if: ...
Use path/glob entries for the machine-enforceable portions of Allowed writes, Read-only, and Forbidden. Allowed writes must remain meaningfully narrower than the repository root; repo-wide catch-all globs are invalid scope-freeze output. Non-path forbidden operations remain part of the human contract but cannot be proven by a file-diff gate.
See Deterministic Scope Gate for status semantics and supported review triggers.
Success looks like
- The canonical block above exists before implementation writes.
Allowed writesnames a real blast-radius boundary rather than a repo-wide catch-all.- The final live diff receives scope-gate
PASS, or an explicit human resolves everyREVIEW_REQUIREDtrigger. - No violating write is justified retroactively by silently widening the scope artifact.
Stop conditions
- Scope is narrow enough for safe implementation.
- Task requires changes outside boundary → pause and renegotiate before the write.
- Scope gate returns
FAIL→ stop, revert, or renegotiate. - Scope gate returns
REVIEW_REQUIRED→ obtain the named review before claiming completion.
Anti-patterns
- Roaming the entire repo for a small fix.
- Using
*,**, or**/*asAllowed writesand calling the result scoped. - Expanding scope because "nearby code looked easy."
- Running write commands before boundary is agreed.
- Editing
SCOPE.mdafter a violation to manufacture compliance. - Treating an allowed path as proof that all behavior inside it is authorized.
- Forbidding necessary discovery reads.