Commit Graph

3 Commits

Author SHA1 Message Date
Ben Stull 79a27a946b §22 S6: per-collection enabled_models — the §22.12 model-universe chain
A collection's .collection.yaml may carry an enabled_models list that NARROWS
its project's universe, which narrows the deployment ENABLED_MODELS. Resolution
(extending §6.6/§6.7): funder ∩ per-entry models ∩ collection ∩ project, with
the operator providers as the ceiling.

- migration 031: additive collections.config_json (parallels projects.config_json).
- registry.parse_collection_manifest: read enabled_models into CollectionEntry.config
  (absent = inherit, present incl. [] = narrow; [] opts the collection out of AI);
  reject a non-list. _upsert_named_collection persists config_json. The default
  collection (from projects.yaml) leaves it NULL — it inherits the project.
- models_resolver: _scope_narrowed_universe narrows the operator universe by the
  entry's project then collection enabled_models; the funder universe is bounded
  by it too. A collection cannot widen its project (narrowing from the ceiling).
- collections.get_collection surfaces enabled_models; GET
  /api/projects/:id/collections/:cid returns it.
- test_s6_collection_models_vertical.py: 9 cases (parse, the narrowing chain
  incl. opt-out + cannot-widen, API surfacing).

Backend: 525 passed. Per SPEC §22.12. Releases as part of v0.45.0.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-06 01:30:16 -07:00
Ben Stull 55a8be051a 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>
2026-05-25 06:08:43 -07:00
Ben Stull a255429e57 Post-v1: per-RFC model availability (UX half) folded into §6.6
First §19.2 candidate settled after v1. The heavier per-RFC-model
topic subdivided into UX (this) and credential delegation + funder
role (still §19.2). New §6.6 carries the rule: an optional `models:`
frontmatter field on the meta-repo RFC entry; absent inherits the
operator universe, populated narrows the picker to the intersection
with provisioned providers, `[]` opts the RFC out of AI entirely.
The first resolved entry is the RFC default. §18's ENABLED_MODELS is
reframed as the operator universe.

Code: migration 009 adds nullable cached_rfcs.models_json (NULL ≠ []
is load-bearing); entry.py grows the optional field with absent-vs-
empty round-tripping in parse/serialize; new models_resolver module
holds the rule; api_branches replaces /api/models with the slug-aware
/api/rfcs/{slug}/models and threads the chat + reask paths through
the resolver; api_prs §10.2 uses the resolver and extends the stub
fallback to the opt-out case; frontend passes slug to listModels.

Tests 106/106 green (96 prior + 10 in test_per_rfc_models.py). No
behavioral change for entries without `models:` — operator universe
preserved as default.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 05:42:15 -07:00