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:
Ben Stull
2026-05-25 06:08:43 -07:00
parent a255429e57
commit 55a8be051a
12 changed files with 1437 additions and 43 deletions
+7 -2
View File
@@ -79,13 +79,16 @@ def _upsert_cached_rfc(entry: entry_mod.Entry, body_sha: str) -> None:
# §6.6: models_json stays NULL when the frontmatter key is absent
# (inherit operator universe) and '[]' for the explicit opt-out.
models_json = json.dumps(entry.models) if entry.models is not None else None
# §6.7: funder_login mirrors the optional `funder:` frontmatter
# field. NULL means absent — operator credentials are used.
funder_login = entry.funder or None
db.conn().execute(
"""
INSERT INTO cached_rfcs
(slug, title, state, rfc_id, repo, proposed_by, proposed_at,
graduated_at, graduated_by, owners_json, arbiters_json, tags_json,
models_json, body, body_sha, last_entry_commit_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
models_json, funder_login, body, body_sha, last_entry_commit_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, datetime('now'), datetime('now'))
ON CONFLICT(slug) DO UPDATE SET
title = excluded.title,
state = excluded.state,
@@ -99,6 +102,7 @@ def _upsert_cached_rfc(entry: entry_mod.Entry, body_sha: str) -> None:
arbiters_json = excluded.arbiters_json,
tags_json = excluded.tags_json,
models_json = excluded.models_json,
funder_login = excluded.funder_login,
body = excluded.body,
body_sha = excluded.body_sha,
last_entry_commit_at = datetime('now'),
@@ -118,6 +122,7 @@ def _upsert_cached_rfc(entry: entry_mod.Entry, body_sha: str) -> None:
json.dumps(entry.arbiters),
json.dumps(entry.tags),
models_json,
funder_login,
entry.body,
body_sha,
),