Skip to main content
Version: MVP

Scope Control

5 min readFor operatorsUpdated 2026-05-19

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:

A task with explicit scope
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:

Read what got accepted
craik intent show task_review_docs

The six knobs

Flag
Type
Purpose
--accepted-interpretation
text
The runtime's plain-language understanding of the task. Where ambiguity gets named.
--in-scope
item (repeatable)
Concrete work the run is allowed to perform.
--out-of-scope
item (repeatable)
Explicit forbidden actions. The runner must stop or ask before crossing one.
--allowed-autonomy
text
How far the runner may go without checking in.
--stop-condition
condition (repeatable)
Conditions that should halt the run pending review.
--scope-change-rule
text
How the runner should request a scope update if the lock doesn't fit.

Conservative 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:

  1. accepted_interpretation matches reality. If the runtime understood something different from what you meant, fix it now.

  2. in_scope is concrete and narrow. Vague items like "improve docs" invite drift; "update docs/architecture.md to reflect runtime state" doesn't.

  3. out_of_scope names obvious traps. ADR edits, schema migrations, secret rotations — call them out by name.

  4. allowed_autonomy matches your trust. Inspection-only runs should not declare "execute shell commands" as allowed.

  5. stop_conditions cover known risk. Anything you'd want to pause for should be a stop condition, not a hope.

  6. scope_change_rules tell 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.

What's next