Scope Control
What you'll do
Configure explicit scope controls on a task so the runtime's intent lock keeps execution aligned with the accepted request. By the end you'll know how to set in-scope and out-of-scope items, allowed autonomy, stop conditions, and scope-change rules — and when to refresh them mid-run.
The pattern
Craik uses intent locks to keep task execution honest. Scope control is how you configure the lock at task creation time:
craik task create \
--project Example \
--title "Review docs" \
--objective "Review docs against implementation." \
--accepted-interpretation "Review documentation only." \
--in-scope "README.md" \
--in-scope "docs/" \
--out-of-scope "ADR edits" \
--allowed-autonomy "Inspect repository files" \
--stop-condition "The task requires changing immutable docs" \
--scope-change-rule "Ask before expanding beyond documentation review"
Then inspect the lock the runtime accepted:
craik intent show task_review_docs
The six knobs
--accepted-interpretation--in-scope--out-of-scope--allowed-autonomy--stop-condition--scope-change-ruleConservative defaults
If you skip the scope flags, Craik creates conservative defaults from the task request:
Title becomes the original request
The verbatim user input is preserved as the lock's original_request.
Objective becomes the accepted interpretation
If you didn't name a separate interpretation, the objective stands in.
Expected outputs become in-scope work
What the task said it would produce defines what's allowed.
Constraints become out-of-scope work
Any declared constraint flips to a forbidden action.
Stop conditions are non-empty by default
Default stops fire when project context is missing, policy conflicts arise, or the objective materially changes.
Defaults are a floor, not a ceiling. Explicit flags always win when present.
Review before authorizing
Before letting a run proceed, read the lock and confirm:
accepted_interpretationmatches reality. If the runtime understood something different from what you meant, fix it now.in_scopeis concrete and narrow. Vague items like "improve docs" invite drift; "update docs/architecture.md to reflect runtime state" doesn't.out_of_scopenames obvious traps. ADR edits, schema migrations, secret rotations — call them out by name.allowed_autonomymatches your trust. Inspection-only runs should not declare "execute shell commands" as allowed.stop_conditionscover known risk. Anything you'd want to pause for should be a stop condition, not a hope.scope_change_rulestell the runner how to ask. When the lock doesn't fit, the runner needs a documented escape hatch.
When to update mid-run
If the runner finds work that crosses the lock, it should pause and ask — not silently widen scope. To update the intent lock mid-run:
craik intent update task_review_docs --in-scope "docs/architecture.md edits"Updates the lock with a new in-scope item. The change is recorded for audit.
The original accepted_interpretation stays preserved. Updates are
additive history, not replacements — you can audit the full trajectory of
how the lock evolved during a task.
What to do when stop conditions fire
A stop condition firing is not a failure — it's the runtime working as designed. The right responses, in order:
Stop, review, decide
- Inspect what the runner produced up to the stop point.
- Decide: widen the lock, change the policy envelope, or end the task.
- Record the decision in the next handoff's
policy_exceptions.
Don't ignore
- Don't disable a stop condition without writing down why.
- Don't restart the run hoping it won't trip the condition again — fix the underlying issue.
- Don't widen autonomy as a workaround for a recurring stop.