Repository source: docs/plans/theme_directive/theme_directive_step1_solution_assessment.md
Debug mode: enabled
Effort study: railspike-effort / v3/theme_directive; host ledger. Standing P2 enrollment. Split from v3/engagify_theme, its Option B; counted as a distinct cycle with that relationship retained.
Extended estimates: enabled
Cycle estimate: 0.40
Original Query
break out the theme: directive into its own cycle
Context from the parent cycle's query: "This is also where we can start testing page-specific themes, meaning themes that are the default theme for a particular page."
Understood Intent
Let a thread choose its own page theme from inside the forum. A line such as theme: engagify sets that thread's page theme, in the same spirit as the title: and event: directives. The Engagify cycle keeps its page theme list in configuration. This cycle adds the directive as a second way to set a page theme, so that choosing one no longer requires an operator to edit settings.
Problem
After the Engagify cycle, only a site setting can give a thread a page theme, and nobody can set one from the thread itself.
Concepts touched: page theme (introduced by v3/engagify_theme; extended, every option); thread title (precedent; Option B reuses its pattern); calendar event directive (precedent; Option A reuses its pattern). No matching feedback item in docs/feedback/items/.
Shared by every option
This cycle depends on the page theme mechanism from
v3/engagify_theme. It begins after that cycle's page theme stage lands.Only the thread's author or an operator can set a thread's theme. From anyone else, the line stays plain text.
The value must name a theme in
ThemeRegistry.php. An unknown name is ignored.Exit works as it does for any page theme: the viewer's choice to leave is remembered in the browser.
A directive beats the configuration list for its thread. Precedence is settled in Step 2.
Option A — Derived on read, like event:
Estimate: 0.40 Main driver: one directive reader with an authority check and a lookup on the thread page. Uncertainty: low to medium, mostly in baked thread pages.
The thread page finds the latest theme: line in its posts, counting only unretracted, verified posts by the thread's author or a current operator. The root post's own line counts. Nothing is stored, so a rebuild cannot disagree with the posts, and retracting the post withdraws the theme.
Pro: no record family and no schema change.
Pro: existing threads gain a theme through an ordinary reply.
Con: authority is judged when the page is read, so a theme set by a former operator stops applying.
Con: lists and cards do not know a thread's theme; only the thread page does.
Option B — Derived record, like title:
Estimate: 0.75 Main driver: a new record family with spec, write path, read-model column and withdrawal. Uncertainty: medium.
When an author with authority posts a theme: line, the same commit writes a thread-theme record that names the reply, as the title directive does. The read model stores the effective theme on the thread row.
Pro: authority is fixed when the line is written, and exports carry the record.
Pro: any page could read the theme cheaply, though none needs it yet.
Con: a record spec, schema version bump and rebuild test, for a joke theme.
Option C — Root header Theme:
Estimate: 0.55 Main driver: a header through parser, write path, read model and composer. Uncertainty: medium.
The parent cycle's Option B: the thread's root record carries Theme: engagify.
Con: existing threads cannot gain a theme without a new thread.
Con: the composer gains a field few people will use.
Recommendation
Choose Option A. It follows the most recent directive precedent, needs no format or schema change, and lets the anti-cookie notice thread gain Engagify with one reply. If themes ever need to show in lists, Option B's record can come later.
Vertical slice: the directive on one thread, with authority, retraction withdrawal and Exit verified. The whole cycle is a single slice.
— Claude · 2026-11-07 UTC · Model: claude-opus-5-5
Revision 1 — setting a theme later by reply
The maintainer wants to set a thread's theme later, as a comment, not only when the thread starts. This becomes a requirement for every option. Options A and B meet it, since a theme: line works in any reply, so an existing thread gains a theme with one reply. Option C does not meet it, because a root header is fixed when the thread is created. Option C is therefore ruled out. Option A remains the recommendation, and its estimate is unchanged.
— Claude · 2026-11-07 UTC · Model: claude-opus-5-5
Revision 2 — visible or hidden, by the poster's choice
The maintainer wants both a visible and a hidden way to set a theme, chosen by whoever posts it. Combined with Revision 1, both forms must work when a thread starts and later by reply.
New recommendation, Option D: Option A plus a hidden form. Estimate: 0.70 (rough). Main driver: a Theme: record header accepted on replies as well as roots, through parser, write path and composer. Uncertainty: medium, mostly in whether reply records accept a new header without a spec change.
Visible: a
theme:line in the post text, as in Option A. Readers see it, liketitle:andevent:.Hidden: a
Theme:header in the record, above the body, set from a theme choice in the composer. It does not appear in the post text.Both forms feed the same read-time lookup: the latest valid theme from the thread's author or a current operator wins, whichever form it used. Retracting the post withdraws it.
Option C alone fails Revision 1, since a root-only header cannot be added later. Option D keeps C's hidden header but allows it on replies.
Option B still adds nothing the maintainer has asked for and stays a possible later step.
— Claude · 2026-11-07 UTC · Model: claude-opus-5-5
Study checkpoint
2026-11-07T11:45:50Z, railspike-effort / v3/theme_directive, intake and Step 1 handoff. Split from v3/engagify_theme Option B at the maintainer's request; distinct cycle ID with the parent link retained. Scope v1: Option A as recommended above. Starting point assumed: v3/engagify_theme page themes delivered; planning revision d379f5600ab55c99e8b8055d6f0520eda0504595. Reference R1, protocol P2; frozen R1 hashes not re-verified. Single exposed Claude rater, who also wrote the parent's estimates. Before rating, the rater read TitleDirective.php, EventStatus.php, the thread-subject record spec and the thread title and calendar concepts. Pristine intake missing. Intake and Step 1 projected total 0.40. Option estimates 0.40, 0.75 and 0.55 are alternatives and do not add up. No implementation, measured labor or accepted outcome.
2026-11-07T14:41:57Z, branch move: the maintainer asked for this cycle to stand on its own. Planning moved from plan/engagify_theme to plan/theme_directive, branched from feat/engagify_theme, whose page themes are now built (Stage 3). Scope v1, Option A and projected total 0.40 unchanged; no re-rating. Step 1 still awaits approval.
2026-11-07T15:11:25Z, Revision 2 checkpoint: the maintainer asked for visible and hidden forms by poster's choice. Scope v2: Option D (A plus a hidden Theme: header on roots and replies). Projected total 0.40 → 0.70, reason changed scope. Same R1/P2 and single exposed Claude rater. No approval implied.
Step 1 approved by the maintainer on 2026-11-07 ("approved step 1"), with Revisions 1–2: Option D.
Enhancement Requests
Set a thread's theme later by reply, not only at thread start. Disposition: in-scope requirement during Step 1; Revision 1; rules out Option C.
Let the poster choose a visible
theme:line or a hidden theme setting. Disposition: in-scope requirement during Step 1; Revision 2; Option D.