Problem/Motivation
ACT fails closed. CommentIndexRepository::load() drops a comment and its whole subtree when any ancestor is not accessible to the viewer, missing, or part of a cycle (src/CommentIndexRepository.php:229-242). An ordinary reader therefore loses published replies from other people whenever a moderator unpublishes the parent. The consequences:
- The summary disagrees with core's statistics.
- Unread navigation and the filter cannot reach the hidden replies.
- Permalinks to them return
404(validatedIndex(),src/Controller/CommentFragmentController.php:349-353). - They are missing from the no-JS view.
The re-parent rule in CommentIndex::__construct() (src/CommentIndex.php:65-67) is effectively dead code.
Deletion cascades through core. CommentDeleteForm::submitForm() calls $comment->delete() (src/Form/CommentDeleteForm.php:131), and core deletes every descendant. The only record is the confirmation text (:66).
Moderators need finer tools for three cases:
- abuse removal that keeps the valuable replies below;
- spam removal of a whole subtree, with a record of what was removed;
- takedowns.
This is the decision proposed in ADR 0008 (docs/adr/0008-replies-under-hidden-parents.md).
Proposed resolution
Per ADR 0008:
- Structure is shown; content stays access-gated. A parent the viewer may not view renders as a content-free stub:
- no field values, and no real comment ID (an opaque key, stable within one response);
- no actions, permalink, unread state or filter match;
- the relation line reads "Reply to a removed comment";
- not counted in the summary, but
childCountscount through it; - omitted when it has no visible descendants.
Each reply keeps its own access('view'). Cycles stay dropped and are logged.
- Redact (new permission
redact comments,restrict access: true):- keeps the row, ID,
pid,thread, host, field,createdand status; - clears the subject, all configured fields,
name,mail,homepageandhostname(anduid: proposed, to be decided); - records a redaction marker (who, when) in a new base field;
- is irreversible, and the confirmation says so.
- keeps the row, ID,
- Delete with replies (new permission
delete comments with replies):- required for ACT's inline Delete on a comment that has replies;
- before
delete(), writes an audit entry per deleted comment (cid, uid, created, actor, host, field, parent) and a summary entry through theadvanced_comment_threadslogger channel; - deletion still goes through
CommentInterface::delete().
Every consumer that assumes each ancestor is a real, viewable entity must handle stubs before the ancestry filter is relaxed. Examples: ancestorsOf() in the filter breadcrumb (CommentFragmentController.php:445), and level/ancestor_ids in CommentSliceRenderer.php:288-289.
Remaining tasks
- Decide ADR 0008's open questions:
- hard-deleted parents (stub, re-parent, or fail closed);
- GDPR erasure and audit-log retention;
- stub semantics (permalink in context, unread, summary, moderator labels);
- per-viewer differences from contrib "view own unpublished" modules.
- Decide whether
uidis kept on redaction. - Implement the stub representation across index, settings, refresh payload, filter breadcrumbs, relation line, ancestry path, unread navigation and the no-JS view.
- Redact form and route, base field, permissions, post update and release note. Existing sites keep cascade delete for anyone with core delete access until the new permission is granted.
- Tests:
- no leak of the parent's content or ID in markup, settings or refresh;
- stubs are omitted without visible descendants;
- audit entries are written before
delete(); - permission combinations.
User interface changes
- Stub rows ("Reply to a removed comment" / "Removed by a moderator").
- A new Redact action.
- Delete on comments with replies becomes permission-gated.
API changes
- Two new permissions.
- Stub keys in
parentById,orderedIdsand refresh payloads (opaque, non-numeric). - Audit log entries on the
advanced_comment_threadschannel.
Data model changes
New base field on comment for the redaction marker, with a post update.
Related issues
#3623698
#3622148
#3622150
Comments