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
3.1 KiB
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
- The grant is declared by the tenant, carried by Activity Core. The
tenant's activity definition holds a
repository_grantv2 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 withallowed_paths: [checkpoints/**]andcommit_count.maxas its run needs. - 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.
- 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_pathsand the count is withincommit_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.
- checks every commit touches only
- 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. - 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.