return EXIT_FAILURE;
                                }
                        }
-                       cgirls_req req = cgirls_path2req(line);
+                       cgirls_req req = cgirls_path·to·req(line);
                        if (!empty) {
                                free(line);
                        }
-                       line = cgirls_req2path(req);
-                       cgirls_freereq(req);
+                       line = cgirls_req·to·path(req);
+                       cgirls_req·free(req);
                        if (!line) {
                                free(lineptr[0]);
                                fprintf(stderr, "Error: Failed to allocate string for path.\n");
                                return EXIT_FAILURE;
                        }
-                       req = cgirls_path2req(line);
-                       reline = cgirls_req2path(req);
-                       cgirls_freereq(req);
+                       req = cgirls_path·to·req(line);
+                       reline = cgirls_req·to·path(req);
+                       cgirls_req·free(req);
                        if (!reline) {
                                free(lineptr[0]);
                                free(line);
 
 #include "aa.h"
 #include "request.h"
 
-void cgirls_freereq (cgirls_req req) {
-       free(req.cgirls_project);
-       free(req.cgirls_id);
-       if (req.cgirls_subpath) {
+static char const*const cgirls_mtypes[] = {
+       [cgirls_mtype_txt] = ".txt",
+       [cgirls_mtype_htm] = ".htm",
+       [cgirls_mtype_xml] = ".xml",
+       [cgirls_mtype_rdf] = ".rdf",
+};
+constexpr size_t cgirls_n·mtypes =
+       sizeof(cgirls_mtypes) / sizeof(char*);
+
+static char const*const cgirls_vbs[] = {
+       [cgirls_vb_unknown] = "unknown",
+       [cgirls_vb_index] = "index",
+       [cgirls_vb_show] = "show",
+};
+constexpr size_t cgirls_n·vbs =
+       sizeof(cgirls_vbs) / sizeof(char*);
+static cgirls_vb const cgirls_parsable·vbs[] = {
+       cgirls_vb_index,
+       cgirls_vb_show,
+};
+constexpr size_t cgirls_n·parsable·vbs =
+       sizeof(cgirls_parsable·vbs) / sizeof(cgirls_vb);
+
+void cgirls_req·free (cgirls_req req) {
+       free(req.project);
+       free(req.id_THIS_WILL_CHANGE);
+       if (req.subpath) {
                size_t i = 0;
-               char* c = req.cgirls_subpath[i];
+               char* c = req.subpath[i];
                while (c) {
                        free(c);
-                       c = req.cgirls_subpath[++i];
+                       c = req.subpath[++i];
                }
-               free(req.cgirls_subpath);
+               free(req.subpath);
        }
-       free(req.cgirls_baseid);
-       free(req.cgirls_status.cgirls_message);
+       free(req.baseid_THIS_WILL_CHANGE);
+       free(req.status.message);
 }
 
-char* cgirls_gobblepath(char const* ndx[1], char const*const end[1]) {
+static char* cgirls_gobble·path(char const* ndx[1], char const*const end[1]) {
        char const* eor = strchr(ndx[0], '/');
        char* result = nullptr;
        if (!eor) {
        return result;
 }
 
-cgirls_req cgirls_path2req(char const*const pathinfo) {
+cgirls_req cgirls_path·to·req(char const*const pathinfo) {
        assert(pathinfo != nullptr);
 
        // Initialize the result.
        cgirls_req req = {
-               .cgirls_action = cgirls_vb_unknown,
-               .cgirls_type = cgirls_mtype_any,
-               .cgirls_project = nullptr,
-               .cgirls_id = nullptr,
-               .cgirls_subpath = nullptr,
-               .cgirls_baseid = nullptr,
-               .cgirls_status = {
-                       .cgirls_code = 200,
-                       .cgirls_message = nullptr,
+               .verb = cgirls_vb_unknown,
+               .mtype = cgirls_mtype_any,
+               .project = nullptr,
+               .id_THIS_WILL_CHANGE = nullptr,
+               .subpath = nullptr,
+               .baseid_THIS_WILL_CHANGE = nullptr,
+               .status = {
+                       .code = 200,
+                       .message = nullptr,
                },
        };
 
        // the project of the request. If there is no first slash, the
        // project extends to the end of the string. An empty string is
        // equivalent to having no project.
-       req.cgirls_project = cgirls_gobblepath(ndx, end);
+       req.project = cgirls_gobble·path(ndx, end);
 
        // The portion of the pathinfo which follows the first slash but
        // precedes the second gives the action of the request. If there is
        // constants). If a verb is present, but unrecognized, it is assigned
        // the special value `cgirls_vb_unknown´, which should generally be
        // interpreted as an error.
-       char* soa = cgirls_gobblepath(ndx, end);
+       char* soa = cgirls_gobble·path(ndx, end);
        if (soa) {
                char*const eoa = strchr(soa, 0);
                if (eoa - soa > 4) {
                        // present (it will be the last 4). Then set the first character
                        // of the extension to null, effectively trimming the verb.
                        char* ext = eoa - 4;
-                       for (size_t i = 0; i < cgirls_n·mtypes; ++i) {
-                               cgirls_mtype ixt = cgirls_mtypes[i];
-                               if (strncmp(ext, ixt, 4) == 0) {
-                                       req.cgirls_type = ixt;
+                       for (cgirls_mtype i = 0; i < cgirls_n·mtypes; ++i) {
+                               char const*const ixt = cgirls_mtypes[i];
+                               if (ixt && strncmp(ext, ixt, 4) == 0) {
+                                       req.mtype = i;
                                        ext[0] = 0;
                                        break;
                                }
                }
                for (size_t i = 0; i < cgirls_n·parsable·vbs; ++i) {
                        cgirls_vb ivb = cgirls_parsable·vbs[i];
-                       if (strcmp(soa, ivb) == 0) {
-                               req.cgirls_action = ivb;
+                       char const*const svb = cgirls_vbs[ivb];
+                       if (svb && strcmp(soa, svb) == 0) {
+                               req.verb = ivb;
                                break;
                        }
                }
                free(soa);
        } else if (ndx[0] == end[0]) {
-               req.cgirls_action = cgirls_vb_index;
+               req.verb = cgirls_vb_index;
        }
 
        // The portion of the pathinfo which follows the second slash but
        // string. A single identifier may be given, or two identifiers may
        // be given separated by two periods. An empty string is equivalent
        // to no identifier.
-       char* idid = cgirls_gobblepath(ndx, end);
+       char* idid = cgirls_gobble·path(ndx, end);
        if (idid) {
                // If the identifier string contains two successive dots, the base
                // and target identifiers must be extracted and the original
                        char const*const eods = dots + 2;
                        char const*const eoii = strchr(idid, 0);
                        if (dots > idid) {
-                               req.cgirls_baseid = strndup(idid, dots - idid);
+                               req.baseid_THIS_WILL_CHANGE = strndup(idid, dots - idid);
                        }
                        if (eods < eoii) {
-                               req.cgirls_id = strndup(eods, eoii - eods);
+                               req.id_THIS_WILL_CHANGE = strndup(eods, eoii - eods);
                        }
                        free(idid);
                } else {
-                       req.cgirls_id = idid;
+                       req.id_THIS_WILL_CHANGE = idid;
                }
        }
 
                        sos = end[0];
                }
        }
-       req.cgirls_subpath = calloc(n·s + 1, sizeof(char*));
-       if (!req.cgirls_subpath) {
+       req.subpath = calloc(n·s + 1, sizeof(char*));
+       if (!req.subpath) {
                return req;
        }
        size_t i·s = 0;
                        sep = end[0];
                }
                if (sep > ndx[0]) {
-                       req.cgirls_subpath[i·s++] = strndup(ndx[0], sep - ndx[0]);
+                       req.subpath[i·s++] = strndup(ndx[0], sep - ndx[0]);
                }
                if (end[0] > sep) {
                        ndx[0] = sep + 1;
                }
        }
        assert(i·s == n·s);
-       req.cgirls_subpath[i·s] = nullptr;
+       req.subpath[i·s] = nullptr;
 
        // Return the result.
        return req;
 }
 
-char* cgirls_req2path(cgirls_req req) {
-       cgirls_vb vb = cgirls_vb_index;
-       bool has·ids = req.cgirls_baseid || req.cgirls_id;
-       bool has·type = req.cgirls_type;
-       bool has·subpath = req.cgirls_subpath && req.cgirls_subpath[0];
+char* cgirls_req·to·path(cgirls_req req) {
+       char const* vb = nullptr;
+       char const* mtype = nullptr;
+       bool has·ids = req.baseid_THIS_WILL_CHANGE || req.id_THIS_WILL_CHANGE;
+       bool has·subpath = req.subpath && req.subpath[0];
        size_t length = 0;
 
+       // Get the string corresponding to the verb. Do not assume that the
+       // verb is welbehaved (actually corresponding to an enumeration
+       // constant).
+       if (req.verb < cgirls_n·vbs) {
+               vb = cgirls_vbs[req.verb];
+       }
+       if (!vb) {
+               vb = cgirls_vbs[cgirls_vb_unknown];
+       }
+
+       // Get the string corresponding to the mediatype, or `nullptr´. Do
+       // not assume that the verb is welbehaved (actually corresponding to
+       // an enumeration constant).
+       if (req.mtype < cgirls_n·mtypes) {
+               mtype = cgirls_mtypes[req.mtype];
+       }
+
        // Get the length of the various parts. This length includes a
        // trailing slash, but in practice this will be replaced by the final
        // null byte.
-       if (req.cgirls_project) {
-               length += strlen(req.cgirls_project) + 1;
-               for (size_t i = 0; i < cgirls_n·vbs; ++i) {
-                       cgirls_vb ivb = cgirls_vbs[i];
-                       if (req.cgirls_action == ivb) {
-                               vb = ivb;
-                               break;
-                       }
-               }
-               if (vb != cgirls_vb_index || has·type || has·ids || has·subpath) {
+       if (req.project) {
+               length += strlen(req.project) + 1;
+               if (req.verb != cgirls_vb_index || mtype || has·ids || has·subpath) {
                        length += strlen(vb) + 1;
                }
-               if (has·type) {
-                       length += strlen(req.cgirls_type);
+               if (mtype) {
+                       length += strlen(mtype);
                }
                if (has·ids) {
-                       if (req.cgirls_baseid) {
-                               length += strlen(req.cgirls_baseid) + 2;
+                       if (req.baseid_THIS_WILL_CHANGE) {
+                               length += strlen(req.baseid_THIS_WILL_CHANGE) + 2;
                        }
-                       if (req.cgirls_id) {
-                               length += strlen(req.cgirls_id);
+                       if (req.id_THIS_WILL_CHANGE) {
+                               length += strlen(req.id_THIS_WILL_CHANGE);
                        }
                        length += 1;
                } else if (has·subpath) {
                }
                if (has·subpath) {
                        size_t i = 0;
-                       char* c = req.cgirls_subpath[i];
+                       char* c = req.subpath[i];
                        while (c) {
                                length += strlen(c) + 1;
-                               c = req.cgirls_subpath[++i];
+                               c = req.subpath[++i];
                        }
                }
        } else {
                return nullptr;
        }
        char* cursor = result;
-       if (req.cgirls_project) {
-               cursor = stpcpy(cursor, req.cgirls_project);
+       if (req.project) {
+               cursor = stpcpy(cursor, req.project);
                (cursor++)[0] = '/';
-               if (vb != cgirls_vb_index || has·type || has·ids || has·subpath) {
+               if (req.verb != cgirls_vb_index || mtype || has·ids || has·subpath) {
                        cursor = stpcpy(cursor, vb);
-                       if (has·type) {
-                               cursor = stpcpy(cursor, req.cgirls_type);
+                       if (mtype) {
+                               cursor = stpcpy(cursor, mtype);
                        }
                        (cursor++)[0] = '/';
                }
                if (has·ids) {
-                       if (req.cgirls_baseid) {
-                               cursor = stpcpy(cursor, req.cgirls_baseid);
+                       if (req.baseid_THIS_WILL_CHANGE) {
+                               cursor = stpcpy(cursor, req.baseid_THIS_WILL_CHANGE);
                                cursor = stpcpy(cursor, "..");
                        }
-                       if (req.cgirls_id) {
-                               cursor = stpcpy(cursor, req.cgirls_id);
+                       if (req.id_THIS_WILL_CHANGE) {
+                               cursor = stpcpy(cursor, req.id_THIS_WILL_CHANGE);
                        }
                        (cursor++)[0] = '/';
                } else if (has·subpath) {
                }
                if (has·subpath) {
                        size_t i = 0;
-                       char* c = req.cgirls_subpath[i];
+                       char* c = req.subpath[i];
                        while (c) {
                                cursor = stpcpy(cursor, c);
-                               c = req.cgirls_subpath[++i];
+                               c = req.subpath[++i];
                                (cursor++)[0] = '/';
                        }
                }
 
 // SPDX-FileCopyrightText: 2025 Lady <https://www.ladys.computer/about/#lady>
 // SPDX-License-Identifier: GPL-2.0-only
 
+/**
+ ** This file defines types, constants, and function signatures
+ ** necessary for dealing with the ⹐semantics⹑ of C·Girls requests.
+ ** (Implementations of these functions are provided in `request.c´.)
+ **/
+
 #ifndef CGIRLS_REQUEST_H
 #define CGIRLS_REQUEST_H
 
-/*
-The following constant expressions provide recognized media type
-extensions.
-*/
-constexpr char* cgirls_mtype_any = nullptr;
-constexpr char cgirls_mtype_txt[] = ".txt";
-constexpr char cgirls_mtype_htm[] = ".htm";
-constexpr char cgirls_mtype_xml[] = ".xml";
-constexpr char cgirls_mtype_rdf[] = ".rdf";
-typedef char const* cgirls_mtype;
-constexpr size_t cgirls_n·mtypes = 4;
-static cgirls_mtype const cgirls_mtypes[cgirls_n·mtypes] = {
-       cgirls_mtype_txt,
-       cgirls_mtype_htm,
-       cgirls_mtype_xml,
-       cgirls_mtype_rdf,
-};
+/**
+ ** § Types
+ **////////////////////////////////////////////////////////////////////
+/**
+ ** ❦ `enum cgirls_mtype´
+ **
+ ** The `cgirls_mtype´ enumeration is used to indicate recognized
+ ** mediatype extensions.
+ **/
+enum cgirls_mtype : unsigned char {
+/**
+ ** The value `cgirls_mtype_any´ indicates no mediatype preference.
+ **/
+       cgirls_mtype_any = 0,
+
+/**
+ ** The value `cgirls_mtype_txt´ indicates a preference for
+ ** `text/plain´ content.
+ **/
+       cgirls_mtype_txt = 1,
+
+/**
+ ** The value `cgirls_mtype_htm´ indicates a preference for
+ ** `text/html´ content.
+ **/
+       cgirls_mtype_htm = 2,
+
+/**
+ ** The value `cgirls_mtype_xml´ indicates a preference for
+ ** `application/xml´ content, ideally with an `<?xml-stylesheet?>´
+ ** processing instruction.
+ **/
+       cgirls_mtype_xml = 3,
+
+/**
+ ** The value `cgirls_mtype_rdf´ indicates a preference for
+ ** `application/rdf+xml´ content.
+ **/
+       cgirls_mtype_rdf = 4,
 
-/*
-The following constant expressions provide recognized action verbs.
-*/
-// Actions in general:
-constexpr char cgirls_vb_index[] = "index";
-constexpr char cgirls_vb_unknown[] = "unknown";
-// Actions on projects:
-// constexpr char cgirls_vb_branches[] = "branches";
-// constexpr char cgirls_vb_tags[] = "tags";
-// Actions on single objects:
-constexpr char cgirls_vb_show[] = "show";
-// constexpr char cgirls_vb_raw[] = "raw";
-// constexpr char cgirls_vb_blame[] = "blame";
-// Actions on ranges of commits:
-// constexpr char cgirls_vb_diff[] = "diff";
-// Actions on lists of commits:
-// constexpr char cgirls_vb_log[] = "log";
-// constexpr char cgirls_vb_shortlog[] = "shortlog";
-// constexpr char cgirls_vb_atom[] = "atom";
-// constexpr char cgirls_vb_patch[] = "patch";
-typedef char const* cgirls_vb;
-constexpr size_t cgirls_n·vbs = 3;
-static cgirls_vb const cgirls_vbs[cgirls_n·vbs] = {
-       cgirls_vb_index,
-       cgirls_vb_unknown,
-       cgirls_vb_show,
 };
-constexpr size_t cgirls_n·parsable·vbs = 2;
-static cgirls_vb const cgirls_parsable·vbs[cgirls_n·parsable·vbs] = {
-       cgirls_vb_index,
-       cgirls_vb_show,
+typedef enum cgirls_mtype cgirls_mtype;
+
+/**
+ ** ❦ `enum cgirls_vb´
+ **
+ ** The `cgirls_vb´ enumeration is used to indicate recognized verbs
+ ** for requests.
+ **/
+enum cgirls_vb : unsigned char {
+
+/**
+ ** The value `cgirls_vb_unknown´ indicates an unknown or unspecified
+ ** verb.
+ **/
+       cgirls_vb_unknown = 0,
+
+/**
+ ** The value `cgirls_vb_index´ indicates a request for an index of
+ ** projects.
+ **/
+       cgirls_vb_index = 1,
+
+/**
+ ** The value `cgirls_vb_branches´ indicates a request for an index of
+ ** branches in a given project. The value `cgirls_vb_tags´ indicates a
+ ** request for an index of tags.
+ **/
+       // cgirls_vb_branches = ??,
+       // cgirls_vb_tags = ??,
+
+/**
+ ** The value `cgirls_vb_show´ indicates a request for an object in a
+ ** human‐readable manner. The value `cgirls_vb_raw´ indicates a
+ ** request for the raw contents of an object. The value
+ ** `cgirls_vb_blame´ indicates a request for a blame of a commit.
+ **/
+       cgirls_vb_show = 2,
+       // cgirls_vb_raw = ??,
+       // cgirls_vb_blame = ??,
+
+/**
+ ** The value `cgirls_vb_index´ indicates a request for a diff between
+ ** two commits.
+ **/
+       // cgirls_vb_diff = ??,
+
+/**
+ ** The values `cgirls_vb_log´, `cgirls_vb_shortlog´, `cgirls_vb_atom´,
+ ** and `cgirls_vb_patch´ indicate requests for logs of a number of
+ ** commits in various formats.
+ **/
+       // cgirls_vb_log = ??,
+       // cgirls_vb_shortlog = ??,
+       // cgirls_vb_atom = ??,
+       // cgirls_vb_patch = ??,
+
+/**
+ ** Note that the numbering for verbs does not follow their order in
+ ** the above list, but rather is fixed to when they were first
+ ** supported. New verbs may be added in the future.
+ **
+ ** Verbs can be categorized into a few distinct classes :—
+ **
+ ** • Verbs which do not require a project :— `cgirls_vb_index´.
+ **
+ ** • Verbs which require a project, but not a revspec :—
+ ** `cgirls_vb_branches´, `cgirls_vb_tags´.
+ **
+ ** • Verbs which request information about a single object :—
+ ** `cgirls_vb_show´, `cgirls_vb_raw´, `cgirls_vb_blame´.
+ **
+ ** • Verbs which compare two commits :— `cgirls_vb_diff´.
+ **
+ ** • Verbs which produce information about an open‐ended number of
+ ** commits :— `cgirls_vb_log´, `cgirls_vb_shortlog´,
+ ** `cgirls_vb_atom´, `cgirls_vb_patch´.
+ **/
 };
+typedef enum cgirls_vb cgirls_vb;
 
+/**
+ ** ❦ `struct cgirls_req_status´
+ **
+ ** The struct `cgirls_req_status´ wraps a status code and message for
+ ** a response.
+ **
+ ** The `.message´ is only significant if `.code´ is not `200´.
+ **/
 typedef struct cgirls_req_status cgirls_req_status;
 struct cgirls_req_status {
-       unsigned short cgirls_code;
-       char* cgirls_message; // if `cgirls_code´ is not ok
+       unsigned short code;
+       char* message; // if `code´ is not ok
 };
 
+/**
+ ** ❦ `struct cgirls_req´
+ **
+ ** The struct `cgirls_req´ represents a request.
+ **
+ ** Requests must have a verb, may specify a mediatype extension, and
+ ** might also reference a project, revspec, and subpath.
+ **
+ ** All requests have a status, which is used to express request
+ ** validity. If `.status.code´ is not `200´, the request is invalid
+ ** and a response with the associated code and message is recommended.
+ **/
 typedef struct cgirls_req cgirls_req;
 struct cgirls_req {
-       cgirls_vb cgirls_action;
-       cgirls_mtype cgirls_type;
-       char* cgirls_project;
-       char* cgirls_id;
-       char** cgirls_subpath;
-       char* cgirls_baseid;
-       cgirls_req_status cgirls_status;
+       cgirls_vb verb;
+       cgirls_mtype mtype;
+       char* project;
+       char* id_THIS_WILL_CHANGE;
+       char** subpath;
+       char* baseid_THIS_WILL_CHANGE;
+       cgirls_req_status status;
 };
 
-/*
-Frees up any dynamically‐allocated memory which was allocated by
-`cgirls_path2req´.
-*/
-void cgirls_freereq (cgirls_req req);
-
-/*
-Converts the provided “path info” string into a `cgirls_req´ struct
-and returns the result.
-
-This struct contains dynamically‐allocated strings which must be freed
-by calling `cgirls_freereq´.
-
-Maximally, a “path info” string has the following form :—
-
-       {project}/{action}/{baseid}..{id}/{subpath}
-
-—: (where subpath can contain additional slashes, and action may
-optionally include one of a small number of supported extensions).
-`baseid´ is optional; if omitted, the dots preceding `id´ are also
-dropped. For all other components, all preceding components must be
-provided if a given component is provided.
-*/
-cgirls_req cgirls_path2req(char const*const pathinfo);
+/**
+ ** § Functions
+ **////////////////////////////////////////////////////////////////////
+/**
+ ** ❦ `cgirls_req cgirls_path·to·req(char const*const)´
+ **
+ ** The `cgirls_path·to·req´ function takes a path string (such as one
+ ** provided by the C·G·I `PATH_INFO´ environment variable) and returns
+ ** a `cgirls_req´ which represents its semantics.
+ **
+ ** This resulting struct contains a lot of dynamically‐allocated data,
+ ** so it ☞︎must☜︎ be freed with `cgirls_req·free´ after use.
+ **
+ ** Maximally, the path string is processed according to the following
+ ** form :—
+ **
+ ** |`{project}/{action}/{revspec}/{subpath}´
+ **
+ ** —: (where `{subpath}´ can contain additional slashes, and
+ ** `{action}´ consists of a verb and optionally a supported mediatype
+ ** extension). Not all components necessarily need to be specified,
+ ** and not all possible values are valid or meaningful.
+ **
+ ** In case of an error, `.status.code´ on the returned `cgirls_req´
+ ** will be some·thing other than `200´.
+ **/
+cgirls_req cgirls_path·to·req(char const*const);
 
-/*
-Returns the canonical “path info” string which represents the provided
-`cgirls_req´.
+/**
+ ** ❦ `void cgirls_req·free(cgirls_req)´
+ **
+ ** The `cgirls_req·free´ function frees up any dynamically‐allocated
+ ** memory in the provided `cgirls_req´, assuming that it was created
+ ** with `cgirls_path·to·req´ or similar.
+ **/
+void cgirls_req·free(cgirls_req);
 
-Note that if `cgirls_req.cgirls_project´ is the null pointer, the
-canonical “path info” string is always the empty string.
-*/
-char* cgirls_req2path(cgirls_req);
+/**
+ ** ❦ `char* cgirls_req·to·path(cgirls_req)´
+ **
+ ** The `cgirls_req·to·path´ function does the reverse of
+ ** `cgirls_path·to·req´: It takes in a `cgirls_req´ structure and
+ ** returns the canonical path string which represents it.
+ **
+ ** All possible `cgirls_req´s have a canonical string representation;
+ ** `cgirls_req·to·path´ will only return `nullptr´ if it
+ **
+ ** It is worth noting that, if the `.project´ is the null pointer, the
+ ** canonical path string will always be the empty string.
+ **/
+char* cgirls_req·to·path(cgirls_req);
 
 #endif /* CGIRLS_REQUEST_H */