I2114 — A task's scope admits what its derive writes
Stop the pre-push scope check from refusing a branch for the projections its own derive wrote, and give a task one supported command to widen its scope.
READY wave 0 · p2 · implementation profile · parallel safe
Part of development-runtime — The runtime has a development surface.
Ready. Every dependency is done, so majordomus plan start I2114 will be accepted.
Objective
Stop the pre-push scope check from refusing a branch for the projections its own derive wrote, and give a task one supported command to widen its scope.
Why
A derive writes a known set of files: docs/generated/*, site/data/*, site/content/* and, on a version bump, apps/majordomus-cli design tokens, share/version.txt, share/schemas/*, share/sections/* and site/static/*. A task's scope names what the worker means to change, and those projections are almost never in it. On 2026-10-09 the pre-push `finish --check` refused the 0.19.0 release branch (#852) on 30 scope findings, every one a projection of the bump. It refused f7's I2106 the same way, for docs, site/content and site/data. The only route was `handover --close` followed by a new `start` with a wider scope, done three times in one day on two branches. That route is supported but costs a new task id and a handover record each time, and nobody finds it without being told.
Current state
`check` and `finish --check` judge every changed path against the active task's declared scope, the derive's projections included. A task's scope cannot change; it can only be closed and a new task started with another.
Desired state
A path the derive wrote is admitted when the branch also changes one of that projection's canonical inputs. The set is the one already declared: docs/generated/artifacts.json and the site generator's publish block, which is what scripts/gitattributes reads. A path outside both the scope and that set is still refused. `majordomus scope widen <paths>` adds paths to the active task's scope, records who widened it and why, and leaves the task's id unchanged.
Scope
- lib/start.sh
- lib/check.sh
- scripts/gitattributes
- apps/majordomus-cli/src/capability/builtin/scope.rs
- apps/majordomus-cli/src/capability/builtin/devtask.rs
- docs/CLI.md
- test/cases
Dependencies
None. This issue is a root of the graph.
Acceptance criteria
- A branch whose task scope names only the canonical input it changed passes `finish --check` with the derive's projections of that input committed beside it
- A projection committed without any change to its canonical inputs is still refused as outside the scope
- `majordomus scope widen <paths> --because \"<reason>\"` adds the paths to the active task, keeps its id, and the task record says who widened it, when, and why
- A path outside both the scope and the declared projection set is refused exactly as before
Validation
- bin/majordomus plan validate
- MJ_TEST_JOBS=4 bash test/run.sh <the cases this issue adds>
Evidence required
- projection_admitted_case
- scope_widen_case
Evidence
None recorded. Every token above needs a command or an artifact behind it before this issue can be completed; narrative is refused.
Timeline
- started
- —
- verified
- —
- completed
- —
Those three fields, the evidence above and the state of the dependencies are all the status is made of. There is no status field to disagree with them.
Canonical record: .ai/repo/project/issues/I2114.yaml. Read it back with majordomus plan show I2114.