You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
feat(permissions): opt-in partial grant ownership — one module-scoped grant currently blocks 403 of 590 grants #102
ct.groupRole owns a whole role instance: every live grant absent from the declaration lands in toDelete. So one unmanageable grant makes the entire role undeclarable — the repo's own doctrine
is that "a partial declaration is strictly worse than none: it turns a clean no-op into a
destructive plan".
On eqrm.church.tools that costs most of the estate. Of 590 authored per-group grants across 59
role instances, only 187 (44 instances) are declarable. The other 403 grants (15 instances)
are blocked — and often by a tiny minority of the grants in the role:
Role instance
Grants
Blocked by
Team Office / Leiter
41
1 dimension: cc_html_template
Team Office / Organisator
41
1: cc_html_template
Team Equip / Leiter, Organisator
5 each
1: cc_html_template
Area Administration / Leiter, Organisator
4 each
1: cc_html_template
Bereich Pastoral Care / Leiter, Organisator, Teilnehmer
1 each
1: cdb_comment_viewer
sIntegrationmeeting / Mitglied
43
ccm_data_category, cdb_comment_viewer
Implementierung Churchtools / Leiter, Mitglied
116, 113
11–12 module dimensions
Every blocking dimension is module data — calendars, wiki, services, songs, resources, finance
queries, flow categories, OAuth clients — i.e. things the tool deliberately does not manage and
never will. The structural grants sitting next to them are perfectly expressible.
What is missing
An explicit, opt-in way to say: own these rights on this role; leave anything you do not recognise
alone. Sketch:
ct.groupRole({key: "team_office_leiter",group: "team_office",role: "Leiter",// Do not revoke live grants that are absent from `grants` — this role also carries// cc_html_template grants that this scaffold has no business owning.preserveUnknown: true,grants: [/* the 40 structural ones */],});
Requirements for it to be safe:
Opt-in per declaration, never a global default — the current strict behaviour is the right
default and must stay.
Loud in the plan: render the preserved grants explicitly (~ N grant(s) preserved, not managed), so "I forgot one" and "I deliberately left module grants alone" never look alike.
Ideally scoped, e.g. preserveUnknown: ["cc_html_template", "ccm_data_category"], so a
genuinely unexpected new grant on a managed dimension still shows up as drift rather than being
swallowed.
That last variant is the one I would build: it keeps the blast radius of the escape hatch to
dimensions the author has consciously excluded.
Acceptance
A role can be declared with unknown grants preserved rather than revoked, opt-in only.
The plan renders preserved grants explicitly; they are never invisible.
Restricting preservation to named scope dimensions is supported.
Default behaviour is unchanged: undeclared grant → revoke.
Context: full scope composition in eqrm/ct-structuredocs/coverage-gaps.md.
The cdb_comment_viewer half is solved — via REST, not the legacy endpoint (PR #112)
#109 suggested this dimension would need the master-data registry. It does not: /person/commentviewers is conventional REST — [{id, name, sortKey}] plus POST/PUT/DELETE on the item path (live-probed on eqrm-dev, CT 3.135.2, 2026-08-14).
ct get comment-viewers lists the names. This unblocks the three role instances on Bereich Pastoral Care that were each blocked by exactly one comment_viewer-scoped grant, so the whole role instance fell out of ct coverage as undeclarable.
One detail worth knowing: id: 0 is a real row on a live instance ("Alle"), so anything treating a falsy id as "not found" would silently drop the scope. There is a test pinning that.
Comment viewers are a catalog ref for now, not a managed resource — their REST surface would fit the resource registry unchanged, so promoting them later is a scope decision rather than a technical one. Nothing has needed to declare one yet.
The preserveUnknown half of this issue is unaffected.
Activity
feat(permissions): commentViewer scope refs — the cdb_comment_viewer …
2000game commentedon Aug 14, 2026
The
cdb_comment_viewerhalf is solved — via REST, not the legacy endpoint (PR #112)#109 suggested this dimension would need the master-data registry. It does not:
/person/commentviewersis conventional REST —[{id, name, sortKey}]plus POST/PUT/DELETE on the item path (live-probed on eqrm-dev, CT 3.135.2, 2026-08-14).So it is just another catalog ref:
ct get comment-viewerslists the names. This unblocks the three role instances on Bereich Pastoral Care that were each blocked by exactly one comment_viewer-scoped grant, so the whole role instance fell out ofct coverageas undeclarable.One detail worth knowing:
id: 0is a real row on a live instance ("Alle"), so anything treating a falsy id as "not found" would silently drop the scope. There is a test pinning that.Comment viewers are a catalog ref for now, not a managed resource — their REST surface would fit the resource registry unchanged, so promoting them later is a scope decision rather than a technical one. Nothing has needed to declare one yet.
The
preserveUnknownhalf of this issue is unaffected.Merge pull request #112 from eqrm/feat/issues-106-110-111
feat(resources): promote comment-viewer to a declarable resource (#151)…