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
the terminal diff, aimed at the operator running ct; and
--json, aimed at machines and CI tooling.
Neither is a good review artifact for non-technical ChurchTools stakeholders. A ministry lead or master-data owner should be able to review, in plain language:
what will be created or changed;
what an automatic group will do;
whether existing data is touched;
whether anything could be deleted; and
what must be checked before somebody runs apply.
A consumer-repository proof of concept, churchtools-processes/tools/render-plan-report.mjs, already turns ct plan --json into a German Markdown report. It demonstrates the value, but it is deliberately project-specific: it focuses on newly created groups and group-member fields, contains fixed wording and role assumptions, knows selected dynamic-group internals, refers to ct-dev, and must reconstruct display names from raw plan data. This should become a generic projection owned and tested by ct-cli, not a script every consumer repository has to reinvent.
Proposed interface
Add a first-class Markdown output format:
ct plan --format markdown > plan.mdct plan --env prod --format markdown > plan-prod.md
Prefer a general format selector:
--format text|json|markdown
Keep --json as a backward-compatible alias for --format json; reject conflicting combinations clearly.
The first concrete consumer needs German (de-DE) wording. The implementation should avoid organization-specific vocabulary and keep human-facing labels in a small locale dictionary so English or another locale can be added without changing plan semantics. The exact locale flag/default can be decided during design, but it must be explicit and deterministic in CI.
Architectural constraint
Markdown is a presentation of the same structured plan result used by terminal and JSON output:
recalculate plan actions, drift, completeness, permission diffs or safety policy; or
introduce resource behavior that differs from terminal/JSON output.
If the structured plan result does not currently contain a display name or context needed for a good report, enrich the shared result once rather than reconstructing it independently in Markdown.
Report content
The Markdown report should include:
Context
environment, ChurchTools host/version and config path where available;
generation timestamp with an injectable clock for deterministic tests;
a prominent statement that this is only a plan and nothing has been written yet.
Plain-language summary
create/update/delete-candidate/no-op counts;
counts grouped by human-readable resource type;
permission grants and revocations;
a clear “no changes required” result when applicable.
Creates and updates
display name first, technical key/ID second;
readable old → new field values for updates;
hierarchy and logical references shown by name where the shared result can resolve them;
source attribution (config, drift, config+drift) explained in non-technical language;
useful semantic summaries for dynamic groups and group-member fields, without assuming specific group names, role IDs or field reference names.
Permissions
grants/revocations grouped by their domain (group role, group-type role, status);
right names and scopes in readable form;
preserved/unknown rights described without implying that ct will revoke them.
Safety and review
dropped config resources clearly described as not deleted by apply;
incomplete plans/unreadable resources shown as a blocking warning, never as a clean plan;
relevant catalog/portability warnings included or referenced without being lost on stderr;
a short review checklist before apply.
Technical appendix
logical keys, ChurchTools IDs and other diagnostic detail useful to the operator;
generic fallback rendering for every current and future resource type.
The main report should not dump raw nested JSON when a value can be described meaningfully. Unknown future fields/types may use an escaped, deterministic fallback in the technical appendix so the renderer never silently omits a planned change.
Resource metadata
Avoid a growing project-specific if (type === "group") script. Reuse or extend the resource registry with presentation metadata where appropriate, for example:
singular/plural display labels;
display-name field;
field labels;
generic value/reference formatters; and
optional type-specific detail renderers for genuinely semantic structures such as dynamic rulesets.
Every resource must have a generic fallback. Adding a new managed resource should not require a Markdown renderer change merely to make that resource visible.
Acceptance criteria
ct plan --format markdown writes a complete Markdown document to stdout.
--json remains backward compatible; --format json produces the same documented JSON shape.
Markdown and JSON/terminal projections originate from the same plan computation and agree on actions, summaries, drift, permissions and completeness.
The report is useful without understanding logical keys, numeric IDs or raw dynamic-group JSON; those details remain available in an appendix.
All managed resource types are represented, with a safe fallback for an unknown/future type.
Creates, updates, drift, delete candidates, permission changes, no-op plans and incomplete plans are covered.
Markdown tables/cells/headings safely escape pipes, line breaks, backticks and user-controlled names.
Output ordering is deterministic; timestamps/locales are injectable or controllable in tests.
Snapshot/fixture tests cover at least:
no changes;
a mixed create/update plan;
drift and config+drift;
delete candidates and preventDestroy context;
permission grant/revoke/preserved entries;
an incomplete plan with fetch errors;
dynamic groups and group-member fields;
unknown resource/field fallback; and
Markdown escaping.
Documentation includes examples for saving the report and publishing it as a CI/PR artifact.
No ChurchTools token or other secret can appear in the report.
Non-goals
Applying changes from Markdown.
Replacing the operator-oriented terminal diff.
Rendering organization-specific approval text or hard-coded ministry/group names.
Hiding technical warnings to make a report look simpler.
Why this belongs in ct-cli
Only ct-cli has the complete semantic context: resource registry, logical references, action attribution, permission catalog, protected environments and the distinction between a delete candidate and what apply actually does. Owning the renderer here prevents consumer repositories from duplicating that knowledge and drifting away from the real plan semantics.
Problem
ct plancurrently has two useful projections:ct; and--json, aimed at machines and CI tooling.Neither is a good review artifact for non-technical ChurchTools stakeholders. A ministry lead or master-data owner should be able to review, in plain language:
apply.A consumer-repository proof of concept,
churchtools-processes/tools/render-plan-report.mjs, already turnsct plan --jsoninto a German Markdown report. It demonstrates the value, but it is deliberately project-specific: it focuses on newly created groups and group-member fields, contains fixed wording and role assumptions, knows selected dynamic-group internals, refers toct-dev, and must reconstruct display names from raw plan data. This should become a generic projection owned and tested byct-cli, not a script every consumer repository has to reinvent.Proposed interface
Add a first-class Markdown output format:
Prefer a general format selector:
Keep
--jsonas a backward-compatible alias for--format json; reject conflicting combinations clearly.The first concrete consumer needs German (
de-DE) wording. The implementation should avoid organization-specific vocabulary and keep human-facing labels in a small locale dictionary so English or another locale can be added without changing plan semantics. The exact locale flag/default can be decided during design, but it must be explicit and deterministic in CI.Architectural constraint
Markdown is a presentation of the same structured plan result used by terminal and JSON output:
The renderer must not:
ct plan --jsonas a subprocess;If the structured plan result does not currently contain a display name or context needed for a good report, enrich the shared result once rather than reconstructing it independently in Markdown.
Report content
The Markdown report should include:
Context
Plain-language summary
Creates and updates
config,drift,config+drift) explained in non-technical language;Permissions
ctwill revoke them.Safety and review
apply;apply.Technical appendix
The main report should not dump raw nested JSON when a value can be described meaningfully. Unknown future fields/types may use an escaped, deterministic fallback in the technical appendix so the renderer never silently omits a planned change.
Resource metadata
Avoid a growing project-specific
if (type === "group")script. Reuse or extend the resource registry with presentation metadata where appropriate, for example:Every resource must have a generic fallback. Adding a new managed resource should not require a Markdown renderer change merely to make that resource visible.
Acceptance criteria
ct plan --format markdownwrites a complete Markdown document to stdout.--jsonremains backward compatible;--format jsonproduces the same documented JSON shape.preventDestroycontext;Non-goals
Why this belongs in
ct-cliOnly
ct-clihas the complete semantic context: resource registry, logical references, action attribution, permission catalog, protected environments and the distinction between a delete candidate and whatapplyactually does. Owning the renderer here prevents consumer repositories from duplicating that knowledge and drifting away from the real plan semantics.