rein-aharness/docs/repository-grant.md
tegwick 20e6f381f6 feat(runtime): enforce governed mutation boundaries
Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a06ba0-10aa-7ea0-b20a-4f3fac39efe9
2026-09-04 11:25:07 +02:00

68 lines
2.9 KiB
Markdown

# Repository grant contract
Status: **v1 enabled for local `TaskSpec` files; queued/profiled carriage is
not yet available**.
`repository_grant` is the explicit authority envelope for a bounded local Git
mutation. It is separate from task prose, labels, organizational attribution,
tool profiles, and repository path resolution. None of those inputs may be
interpreted as repository authority.
## Version 1
```json
{
"repository_grant": {
"version": "1",
"allowed_paths": ["docs/", "README.md"],
"commit_count": {"min": 1, "max": 1},
"publish": false
}
}
```
All four fields are required and unknown fields are rejected.
- `version` is the string `"1"`.
- `allowed_paths` is a non-empty array of unique, repository-relative POSIX
patterns. An exact path grants that path; a trailing `/` grants that directory
subtree; `*` is confined to one path segment; and `**` may span segments.
Absolute paths, parent traversal, backslashes, and `.git` grants are rejected.
- `commit_count.min` and `.max` are positive integers satisfying
`1 <= min <= max <= 32`.
- `publish` must be `false`. Version 1 grants local commits only. Publication
needs a future separately reviewed contract with remote/ref and outcome
evidence; it cannot be enabled by a label or tool profile.
The parser canonicalizes path order and exposes a stable grant id plus bounded
evidence containing only the path count and digest, not the raw grant patterns.
The repository acceptance validator converts the grant into the policy used to
check descendant commits, changed paths, clean post-state, protected Git
metadata, and local remote-tracking refs.
## Current execution posture
`TaskSpec.from_file` parses this contract and `run_task` executes it under the
canonical repository transaction. A successful adapter result is accepted only
when the commit ancestry/count, changed paths, clean post-state, protected Git
metadata, and remote-tracking refs satisfy the exact grant. The result carries
bounded grant, baseline, policy, commit, and path evidence without raw grant
paths, prompts, or provider output.
Granted runs require durable external metrics and refuse `--no-metrics`. Their
metrics are written outside the checkout only after acceptance, so a successful
run remains clean. See [external-metrics.md](external-metrics.md).
Activity Core and issue-core adapters do not populate `repository_grant`.
Queued/profiled runs therefore cannot claim repository acceptance under this
contract. Existing grant-absent direct and compatibility runs retain their
legacy `HEAD`-changed behavior during migration.
Queued/profiled execution may use this contract only after:
1. an authoritative Activity Core/profile field carries the reviewed grant;
2. required close evidence durably records the grant, transaction, and accepted
result identities.
Task descriptions, labels, `execution_refs`, consuming-repo defaults, and
profile absence must never synthesize a grant.