GLAS-WP-0016/0017: plan FI brief profile, assembly-checkpoint route and shared publish grant
Some checks failed
ci / validate (push) Has been cancelled

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 269924@bnt-lap001
Assistant-Session: 02bbdd77-e96c-4580-8952-f4dc9d8a8508
This commit is contained in:
tegwick 2026-10-13 20:47:21 +02:00
parent 5ce4f38aed
commit d511f97e06
3 changed files with 223 additions and 0 deletions

View file

@ -0,0 +1,58 @@
# Path-scoped publish grants
Status: proposed (GLAS-WP-0016-T05, 2026-10-13). One design for every tenant
that publishes a governed run's commit to its own remote. First consumers:
freedom-intelligence daily brief (`briefs/**`) and assembly-economics
checkpoints (`checkpoints/**`).
## Problem
Both tenants need the same thing: a run produces commits confined to declared
paths, and those commits reach `origin/main` fast-forward only, with at most one
rebase retry, never merge or force. Today the assembly push lives inside
rein-aharness `assembly_checkpoint.py` (legacy inventory gap 6) and the FI push
is requested as part of a tool profile. Neither is a named, separately granted
capability.
## Design
1. **The grant is declared by the tenant, carried by Activity Core.** The
tenant's activity definition holds a `repository_grant` v2 block
(`allowed_paths`, `commit_count`, `publication: {remote, ref, mode,
decision}`). Activity Core validates it and attaches it to the claimed
ops_run. The FI declaration
(`freedom-intelligence/activity-definitions/fi-daily-research-brief.declaration.yaml`)
is the template; assembly-economics copies its shape with
`allowed_paths: [checkpoints/**]` and `commit_count.max` as its run needs.
2. **The session never publishes.** Agent sessions keep a commit-only tool
profile with no push and no Forgejo credential. A Glas profile's tool
profile does not carry publication rights; it only names the paths the
session may write.
3. **Publication is a deterministic step after the run.** The Glas worker
already captures the one-commit result as a Git bundle through the sandbox
owner and imports it under the original baseline, grant and lease
(GLAS-WP-0015, 2026-09-09). A publisher step outside the sandbox then:
- checks every commit touches only `allowed_paths` and the count is within
`commit_count`;
- pushes fast-forward only to `publication.ref`;
- on rejection fetches, rebases once if every unpublished commit is still
inside `allowed_paths`, and pushes again; otherwise it stops and records
the failure;
- never merges or forces;
- records the pushed SHA as run evidence.
It publishes only when the claimed ops_run carries a publication grant.
4. **The push credential belongs to the publisher, not to the run.** It is a
per-tenant, per-repository Forgejo credential under OpenBao custody, found
with `warden route find`. It never enters the sandbox.
5. **Deterministic runs use the same publisher.** A tenant-owned blueprint (no
Glas profile) hands its commits to the same publisher under the same grant
shape. Assembly-checkpoint does not need an agent session for this.
## Open: who owns the publisher
The publisher is one capability serving both Glas-profiled and blueprint runs.
Candidates: Activity Core (it already holds the grant and ops_run), rein-aharness
(it runs the worker that imports the bundle), or a separate typed capability.
Recommendation: Activity Core, because it validates and holds the grant, and
both execution paths already pass through it. This is the operator's decision,
tracked as GLAS-WP-0016-T05.