Define repository grant contract

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b6f-7db1-7222-918b-e813a6bda38d
This commit is contained in:
tegwick 2026-08-23 13:23:50 +02:00
parent ce8f56afea
commit 8cb004a558
8 changed files with 581 additions and 4 deletions

59
docs/repository-grant.md Normal file
View file

@ -0,0 +1,59 @@
# Repository grant contract
Status: **v1 parsed, validation-ready, not execution-enabled**.
`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 fail-closed posture
`TaskSpec.from_file` parses this contract, but `run_task` deliberately refuses
any task that supplies it before adapter dispatch. The Activity Core and
issue-core adapters do not currently populate it. Existing grant-absent direct
and compatibility runs retain their prior behavior while the transaction path
remains production-inert.
Execution may be enabled only after:
1. an authoritative Activity Core/profile field carries the reviewed grant;
2. the lease-bound transaction wraps adapter dispatch and result close;
3. the runner validates the accepted result against this exact grant; and
4. 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.

View file

@ -32,6 +32,11 @@ rein-aharness claim-loop
`TaskExecutorWorkflow` in activity-core stays a stub; execution lives here.
Activity Core does not yet emit the versioned `repository_grant` required by
the lease-bound transaction path. The harness must not infer one from labels,
task prose, `execution_refs`, or target-repo lookup. See
**`docs/repository-grant.md`** for the parsed-but-not-enabled v1 contract.
---
## Legacy / external: issue-core poll