glas-harness/docs/publish-grant-design.md
tegwick 90f16df85a
Some checks failed
ci / validate (push) Has been cancelled
GLAS-WP-0016: rein-aharness owns the publisher (decision c6f23433 supersedes 1c9817ee)
activity-core declined the publisher as outside its charter; it keeps the
grant and evidence-reconciliation role. Record rein-aharness tool profile
green-research-commit (820d33b) as T03 done.

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
2026-10-13 21:29:36 +02:00

3.8 KiB

Path-scoped publish grants

Status: accepted 2026-10-13. Publisher owner: rein-aharness (operator decision c6f23433, superseding 1c9817ee). 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 rein-aharness 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;
    • reports publish evidence (remote, branch, pushed_head, fast_forward_only, published) to Activity Core, which reconciles run close against the grant (ACTIVITY-WP-0046). 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.

Publisher owner

The publisher is one capability serving both Glas-profiled and blueprint runs. rein-aharness owns it as a separately named, separately granted capability (hub decision c6f23433, 2026-10-13). Its worker already imports the bundle outside the sandbox and runs both Glas-profiled and blueprint jobs; the push in assembly_checkpoint.py moves into this capability (legacy inventory gap 6).

Activity Core was chosen first (decision 1c9817ee) and declined (message 5961c59d): pushing commits is repository editing, outside its INTENT and SCOPE; a per-grant target set does not fit its bounded operations; and push credentials would make the scheduler the fleet's high-value write principal. Activity Core keeps the grant role: it admits and carries repository_grant v2 on the ops_run and reconciles run close against grant and publish evidence. glas-harness is excluded by its INTENT (no production service host).