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:
@@ -0,0 +1,40 @@
|
||||
-- §6.7: per-RFC credential delegation — the funder role.
|
||||
--
|
||||
-- Three pieces hang together:
|
||||
--
|
||||
-- 1. cached_rfcs.funder_login mirrors the optional `funder:` frontmatter
|
||||
-- field. NULL means absent — operator credentials per §18 are used.
|
||||
-- A populated value names the user whose registered credentials pay,
|
||||
-- contingent on a matching consent row below.
|
||||
--
|
||||
-- 2. user_funder_credentials stores per-user, per-provider API keys.
|
||||
-- A user can register at most one key per provider family; the keys
|
||||
-- are stored as-supplied (encryption-at-rest is an operational
|
||||
-- decision, deferred to §19.2's operational-realities half).
|
||||
--
|
||||
-- 3. funder_consents records the funder-side opt-in per-slug. A
|
||||
-- frontmatter `funder:` field naming a user without a matching
|
||||
-- consent row is operationally inert per §6.7's two-key rule.
|
||||
|
||||
ALTER TABLE cached_rfcs ADD COLUMN funder_login TEXT;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_funder_credentials (
|
||||
user_id INTEGER NOT NULL,
|
||||
provider TEXT NOT NULL,
|
||||
api_key TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
updated_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
PRIMARY KEY (user_id, provider),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS funder_consents (
|
||||
user_id INTEGER NOT NULL,
|
||||
rfc_slug TEXT NOT NULL,
|
||||
created_at TEXT NOT NULL DEFAULT (datetime('now')),
|
||||
PRIMARY KEY (user_id, rfc_slug),
|
||||
FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
|
||||
);
|
||||
|
||||
CREATE INDEX IF NOT EXISTS idx_funder_consents_slug
|
||||
ON funder_consents (rfc_slug);
|
||||
Reference in New Issue
Block a user