Fossil SCM
branch/forumpost-locking
The ability to "lock" forum posts, such that subsequent responses and edits are disallowed, has being a recurring feature request since the Fossil forum capabilities were introduced. The distributed data model is in inherent conflict with that feature, so "real" locking isn't feasible, but we can implement "advisory" locking which functions similarly to how leaf closure works.
The forum-locking branch provides one implementation of doing so. We use the term "lock" and "close" interchangeably here. "Locked" is the more conventional term in this context but "closed" is the name of the underlying artifact tag for historical reasons.
Summary: by applying a "closed" tag to a forum post, we can keep the UI from permitting edits of, and responses to, that post, recursively in the case of responses. That is, once a post is closed, all responses to it are also implicitly closed (without explicit application of tags to them).
The core requirements of forum post closure are that a closed post cannot be edited, may not be responded to, and any responses which exist before closure may not be edited after the post is closed. There are exceptions to these restrictions:
-
Admin users may continue to edit and respond.
-
No attempt is made to impose restrictions on posts which arrive via the Fossil sync mechanism. Only posts manipulated via the UI are handled. (This is, not coincidentally, similar to how leaf closure works: a subsequent check-in to a closed leaf which arrives via the sync protocol silently trumps the closure.)
Though fundamentally simple to implement, the interactions between versions of posts and linking of responses introduces new complexity on how the effect of a "closed" tag cascades through a post's responses, and closure of forum posts requires handling of a couple of oddities which do not apply to the simpler case of leaf/branch closure:
-
Any given forum post may have any number of edits. Each edited version has its own identity (hash), linked to its previous version via a P-card (same as a wiki page or check-in).
-
Any given response to a post may be in response to any given version of the post it's responding to. That is, the I-cards may differ for each response to a given edited post.
The forum UI hides that complexity by rendering forum posts in a conventional tree-style view, showing (by default) the latest version of any given post, noting that a post and a response are the same thing, differing only in whether or not they have an "in-reply-to" parent (an "I-card", in Fossil artifact terms).
Unlike leaf closure, which uses a non-propagating "closed" tag, forum posts require that a propagating "closed" tag be applied to (only) the first version of a given post. If the tag is instead applied to a subsequent version, it becomes possible to reply to prior versions because they lack the lock. In order to keep complexity to a minimum, and avoid tagging every version of a given post, closing and re-opening a post, via addition resp. cancellation of a "closed" tag, always applies to the (only) the first version. This approach makes it relatively simple to detect closure of a post and cascade that through all responses (recursively). It also means that the tag does not have to be updated when an admin creates a new version of a given post by editing it.
The caveat with the approach of tagging only the first version is that Fossil's data model permits tags to be applied to arbitrary artifacts, e.g. to arbitrary versions of a given post. Closing a non-initial version will, however, confuse the forum view and can either cause posts to appear locked though they are not intended to be, or to be effectively unlocked despite a parent post being locked. This caveat is considered a minimal risk: a user would have to tag the second (or subsequent) version of a given post via the CLI "tag" command (or similar) to introduce these side effects. The UI for closing and re-opening takes care to always deal with the initial version of posts.