Post-v1: per-RFC credential delegation (funder role) folded into §6.7
Second §19.2 settlement after v1. New §6.7 alongside §6.6: optional `funder:` frontmatter field names a single gitea_login; a `funder_consents` app-db row records funder-side opt-in; both halves required for the binding to activate (two-key rule). Funder universe replaces — does not augment — the operator universe per-RFC for attribution-clean resolution. Funder role grants zero §6.1/§6.3 authority. Three revocation paths each restore the operator-credentials status quo. §19.2's credential-delegation entry is split: lighter half marked settled with a pointer to §6.7; operational-realities half (mid-call failure, rotation, billing, rate-limit attribution) lives on as its own entry. Test suite is 125/125 green (106 prior + 19 new). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -80,6 +80,9 @@ tags: [identity, schema]
|
||||
# models: # optional per-§6.6 — absent inherits the
|
||||
# - claude # operator universe; [] opts the RFC out of AI
|
||||
# - gemini # entirely; populated narrows the picker
|
||||
# funder: alice # optional per-§6.7 — names whose registered
|
||||
# API credentials pay for AI calls. Inert until
|
||||
# the named user consents from /settings/funder.
|
||||
---
|
||||
|
||||
## Why this RFC is needed
|
||||
@@ -453,11 +456,93 @@ commitment here is the field, the resolution rule, and the
|
||||
configuration capability, not the click path.
|
||||
|
||||
This section names *which* models are permitted on a given RFC. It
|
||||
does not name *whose API resources pay for them* — credentials
|
||||
remain operator-supplied per §18. Credential delegation and the
|
||||
funder role are a separate topic (§19.2) whose settlement will
|
||||
attach a parallel "credential set" notion alongside this one
|
||||
without changing the availability surface.
|
||||
does not name *whose API resources pay for them* — the credential-
|
||||
delegation half settles in §6.7, where the operator-credentials
|
||||
default is preserved and a per-RFC `funder:` field optionally points
|
||||
the calls at a contributor-supplied credential set.
|
||||
|
||||
---
|
||||
|
||||
### 6.7 Per-RFC credential delegation — the funder role
|
||||
|
||||
§6.6 settles *which* AI models are permitted on a given RFC. This
|
||||
section settles *whose* API credentials pay for them. The two halves
|
||||
are parallel — both live in the meta-repo entry's frontmatter, both
|
||||
follow the same edit-authority rules as `owners:` and `arbiters:`,
|
||||
both mirror through the §4 cache.
|
||||
|
||||
A new optional `funder:` frontmatter field names a single
|
||||
`gitea_login` — the user whose registered API credentials pay for AI
|
||||
calls on this RFC. Absent means the operator-supplied credentials per
|
||||
§18 are used; this is the v1 default and the status quo for every
|
||||
RFC without an explicit funder.
|
||||
|
||||
The funder role is **purely credential-binding**. It confers none of
|
||||
the §6.3 owner/arbiter authority and none of the §6.1 admin/owner
|
||||
authority. The funder gains exactly one capability — withdraw consent
|
||||
— and gains no new read access beyond what their underlying role
|
||||
already affords.
|
||||
|
||||
**Frontmatter + consent hybrid.** The frontmatter names the funder
|
||||
(RFC-side approval, via the standard meta-repo PR flow). A
|
||||
`funder_consents` app-db record records the funder-side approval —
|
||||
the user explicitly opts in per-slug from `/settings/funder`. The
|
||||
frontmatter can name a user who has not consented; the binding stays
|
||||
operationally inert until both halves match. Both sides have a veto.
|
||||
|
||||
**The funder universe replaces the operator universe.** When a
|
||||
funder is in effect for an RFC — frontmatter names them and they
|
||||
have consented — the picker for that RFC resolves to the
|
||||
intersection of:
|
||||
|
||||
- the §6.6 `models:` list (or the implicit "all permitted" when
|
||||
absent), and
|
||||
- the funder's registered universe — the picker keys the operator
|
||||
has enabled and for which the funder has supplied a provider-family
|
||||
API key.
|
||||
|
||||
If the intersection is empty the RFC falls into the §6.6 opt-out
|
||||
shape and the AI surfaces refuse honestly. The operator universe is
|
||||
**not** augmented; the resolution is deterministic and attribution-
|
||||
clean — a call on an RFC with a consenting funder is paid entirely
|
||||
from the funder's credentials. If the funder cannot satisfy a
|
||||
requested model, the model is unavailable for this RFC. The "fall
|
||||
back to operator credentials when a funder call fails" semantics
|
||||
belong to the operational-realities half (§19.2); the lighter half
|
||||
deliberately does not blend funders and operators per-call.
|
||||
|
||||
A funder cannot expand the operator universe through registration —
|
||||
registering an Anthropic key on a deployment whose operator has not
|
||||
enabled `claude` does not make `claude` available on RFCs the funder
|
||||
funds. The operator's enabled set bounds the picker; the funder
|
||||
narrows it further.
|
||||
|
||||
**Three revocation paths, each restoring the operator-credentials
|
||||
status quo.** First — the funder withdraws consent. Instant; the
|
||||
next AI call resolves through the operator universe. Second — an
|
||||
RFC owner, arbiter, or app admin edits the frontmatter to remove
|
||||
the field or name a different funder. Flows through the standard
|
||||
meta-repo PR. Third — the named user's account is disabled per §6.1.
|
||||
Their consent rows are treated as inactive; the resolution flips
|
||||
back without an explicit revocation gesture.
|
||||
|
||||
**Editing the funder field.** Same authority as editing `models:`
|
||||
(or `owners:` / `arbiters:`). Super-draft entries: the claimed
|
||||
owners and app-wide admins. Active RFCs: the RFC's owners and
|
||||
arbiters per §6.3, plus app-wide admins. The dedicated chrome for
|
||||
the edit is downstream — clustered with the §19.2 metadata-pane UX
|
||||
topic for super-drafts and with whatever surface admins use for
|
||||
active-RFC frontmatter edits.
|
||||
|
||||
**Explicitly deferred to the operational-realities half (§19.2).**
|
||||
Mid-conversation credential failure handling; retry-with-fallback to
|
||||
operator credentials when a funder call fails; per-RFC billing
|
||||
surface and cost visibility; per-funder rate-limit attribution and
|
||||
quota-exhaustion behavior; the key-rotation ceremony for a funder
|
||||
swapping in a fresh key without dropping in-flight conversations.
|
||||
The lighter half ships the structural shape — frontmatter, consent,
|
||||
resolution, revocation. The heavier half ships the runtime
|
||||
hardening.
|
||||
|
||||
---
|
||||
|
||||
@@ -2485,6 +2570,27 @@ The follow-up session will refine this. A minimal starting set:
|
||||
user is acting in an admin/owner authority capacity or as an
|
||||
arbiter on an RFC where the muted user is also active.
|
||||
- `DELETE /api/users/<id>/notification-mute` — remove it.
|
||||
- `GET /api/users/me/funder` — read the signed-in user's funder
|
||||
surface per §6.7: the list of provider families for which they
|
||||
have registered credentials (without the keys themselves) and the
|
||||
list of RFC slugs they have consented to fund.
|
||||
- `POST /api/users/me/funder/credentials` — register or replace an
|
||||
API key for a provider family (`anthropic`, `google`, `openai`).
|
||||
Body: `provider`, `api_key`. The provider name must match one the
|
||||
operator has enabled; registering for a provider the operator has
|
||||
not enabled is refused since per §6.7 a funder cannot expand the
|
||||
operator universe.
|
||||
- `DELETE /api/users/me/funder/credentials/<provider>` — remove the
|
||||
registered key for a provider family. Idempotent. Existing consent
|
||||
rows survive; the resolved funder universe for affected RFCs
|
||||
simply shrinks.
|
||||
- `POST /api/rfcs/<slug>/funder/consent` — the signed-in user opts
|
||||
in to fund this RFC per §6.7. Idempotent. Refused if the signed-in
|
||||
user has no registered credentials at all (a consent without any
|
||||
registered universe would be inert).
|
||||
- `DELETE /api/rfcs/<slug>/funder/consent` — withdraw consent per
|
||||
§6.7's first revocation path. Restores the operator-credentials
|
||||
status quo on the next AI call.
|
||||
- `GET /api/email/unsubscribe` — one-click per-category
|
||||
unsubscribe per §15.4. Signed URL; idempotent; redirects to a
|
||||
short confirmation page.
|
||||
@@ -2517,8 +2623,12 @@ them:
|
||||
GitHub Copilot. `ENABLED_MODELS` and per-provider API keys via env —
|
||||
these now define the operator's *universe* of available models, the
|
||||
set the deployment is provisioned to run. Per-RFC selection from
|
||||
that universe is settled in §6.6; credential delegation and the
|
||||
funder role remain a §19.2 candidate.
|
||||
that universe is settled in §6.6; per-RFC credential delegation
|
||||
(whose keys pay for the call) is settled in §6.7. Either the
|
||||
operator's keys or, when a consenting funder is named, the funder's
|
||||
registered keys — never blended per-call. The operational
|
||||
hardening (mid-call failure handling, retry, rotation, billing
|
||||
attribution) remains a §19.2 candidate.
|
||||
- The discuss-vs-contribute distinction inside an RFC view (to be
|
||||
fully specified in the follow-up session).
|
||||
- Gitea OAuth for user authentication. The OAuth identity is the basis
|
||||
@@ -2702,20 +2812,33 @@ binding.
|
||||
downstream — clustered with the metadata-pane UX candidate
|
||||
below for super-drafts, and with whatever surface admins use
|
||||
for active-RFC frontmatter edits.*
|
||||
- **Per-RFC credential delegation and the funder role.** The
|
||||
heavier half of the original per-RFC-model topic — who supplies
|
||||
the API resources behind the models a given RFC permits. The
|
||||
availability half (§6.6) names *which* models are allowed;
|
||||
credential delegation names *whose keys pay for the calls*.
|
||||
Touches security (delegation grant shape, revocation), billing
|
||||
(per-RFC spend, attribution), abuse mitigation (rate limits per
|
||||
funder, quota exhaustion), key rotation (mid-conversation
|
||||
failure handling, retry-with-fallback), and a possible
|
||||
`funder` role distinct from owner/arbiter that scopes credential
|
||||
authority without conferring frontmatter authority. Load-bearing
|
||||
once the framework runs past single-operator deployment; the v1
|
||||
shape — operator-supplied keys per §18 — is the right default
|
||||
until a real multi-operator scenario surfaces.
|
||||
- **Per-RFC credential delegation — funder role + grant shape.**
|
||||
*Settled in the post-v1 session that picked it. The meta-repo
|
||||
entry frontmatter grew an optional `funder:` field per §6.7,
|
||||
parallel in shape to `owners:` / `arbiters:` / `models:`. The
|
||||
frontmatter names the funder (RFC-side approval, via the meta-repo
|
||||
PR flow); a `funder_consents` app-db record records funder-side
|
||||
approval (the user opts in per-slug from `/settings/funder`); both
|
||||
halves are required for the binding to be operationally active.
|
||||
When in effect, the funder universe replaces — not augments — the
|
||||
operator universe for the RFC's picker. The funder role is purely
|
||||
credential-binding (no §6.3 / §6.1 authority granted). Three
|
||||
revocation paths each restore the operator-credentials status quo.
|
||||
The operational hardening — retry/fallback, mid-call failure,
|
||||
rotation, billing — lives on as the entry below.*
|
||||
- **Per-RFC credential delegation — operational realities.** The
|
||||
heavier half of the original credential-delegation topic, split
|
||||
out when §6.7 settled the structural shape. What happens at
|
||||
runtime when funder credentials fail mid-conversation; whether
|
||||
failed funder calls fall back to operator credentials (and how
|
||||
that interacts with §6.7's attribution-clean rule); per-RFC
|
||||
billing surface and cost visibility; per-funder rate-limit
|
||||
attribution and quota-exhaustion behavior; the key-rotation
|
||||
ceremony for a funder swapping in a fresh key without dropping
|
||||
in-flight conversations. Earns its session once a real
|
||||
multi-operator scenario surfaces and the structural §6.7 shape
|
||||
meets enough load to expose where the runtime path needs
|
||||
hardening.
|
||||
- **Admin surfaces.** Where role management, muting, audit-log
|
||||
views, the graduation-readiness queue, and Topic 13's
|
||||
notification-preferences settings (email categories per §15.4,
|
||||
|
||||
Reference in New Issue
Block a user