Project admins can retroactively move a comment from one requirement to another within the same component. The original target is preserved as provenance, the comment text is annotated with a visible marker, and an audit trail entry is recorded — so the move is both legible to triagers reading the thread and traceable through the audit log.
This is the general-purpose admin tool for fixing comments that landed on the wrong rule (e.g. before Soft Redirect existed, or for one-off corrections). It's also the foundation that batch re-parenting tools build on.
Updates rule_id and the polymorphic commentable_id/commentable_type to the target rule (dual-write).
Sets original_commentable_id if it isn't already set — preserves the commenter's first target across multiple moves (see Comment Provenance).
Prepends a visible marker to the comment text:
[Moved from CNTR-00-001028: typo'd rule id]The original comment body...
1 2
Writes a vulcan_audited audit row capturing the rule_id / commentable_id change with the operator's reason in audit_comment.
Cascades to the reply subtree — every reply nested under the moved comment (recursively) also gets its rule_id/commentable_* rewritten to the target rule so the whole thread stays attached. The cascade uses the same depth-N walk as admin_destroy.
Move Comment
Project admins can retroactively move a comment from one requirement to another within the same component. The original target is preserved as provenance, the comment text is annotated with a visible marker, and an audit trail entry is recorded — so the move is both legible to triagers reading the thread and traceable through the audit log.
This is the general-purpose admin tool for fixing comments that landed on the wrong rule (e.g. before Soft Redirect existed, or for one-off corrections). It's also the foundation that batch re-parenting tools build on.
When to use
For cross-component moves: not supported (and intentionally so — component-scoped triage workflows depend on the within-component invariant).
How to use
What happens on the server
Review#move_to_rule!(target_rule, reason:, moved_by:):rule_idand the polymorphiccommentable_id/commentable_typeto the target rule (dual-write).original_commentable_idif it isn't already set — preserves the commenter's first target across multiple moves (see Comment Provenance).2
vulcan_auditedaudit row capturing therule_id/commentable_idchange with the operator's reason inaudit_comment.rule_id/commentable_*rewritten to the target rule so the whole thread stays attached. The cascade uses the same depth-N walk asadmin_destroy.Permissions and gating
What the reader sees
A comment that has been moved shows:
[Moved from PREFIX-RULE_ID: reason]line at the top of the comment text.Replies stay with the parent — readers don't see partial threads at the old rule.
Related
original_commentable_idcolumn that survives multiple moves.