Repository source: docs/plans/archive/zenmemes_rules_pinned_post_options.md
ZenMemes Rules Pinned Post Implementation Plan
Context
The ZenMemes.com rules are saved in zenmemes_rules.txt. The product question is how to make them prominent enough to shape first-time participation without adding a persistent, intrusive onboarding panel.
The current app supports ordinary threads and thread labels. It does not appear to have first-class pinned or sticky thread behavior yet.
Retained Direction
Use a normal rules post with a pinned thread label.
This keeps the rules in the forum's normal content model:
the rules are linkable through
/threads/<id>replies, reactions, and audit history continue to work
the pin is derived from canonical thread-label records
the board gains a small amount of ordering and presentation behavior instead of a separate announcement surface
Scope
Implement:
a canonical rules thread seeded from
zenmemes_rules.txta canonical
pinnedthread-label record for that threadboard sorting that places pinned threads before normal threads
a compact pinned marker on board cards
focused test coverage for ordering, rendering, and canonical rebuild behavior
Do not implement yet:
a first-visit rules panel
a separate announcement region
label-management UI
thread-label removal or unpinning UI
special rules content duplication outside the canonical post
Canonical Content Plan
Create a normal root post in the writable canonical repository:
records/posts/<rules-thread-id>.txtSubject: The Rules of ZenMemes.combody copied from
zenmemes_rules.txtnormal public board tags, unless an existing deployment convention requires a specific tag
Use a stable, readable post id if the canonical parser allows it. If current post-id validation only supports generated ids, use a generated id and document it in this plan after creation.
Create a separate thread-label record instead of adding #pinned to the rules body:
records/thread-labels/<record-id>.txtThread-ID: <rules-thread-id>Operation: addLabels: pinnedoptional
Reason: Pin ZenMemes rules on board
Reason: pinned is display and ordering metadata. It should not be visible as authored rules text unless the community intentionally wants the body to contain that hashtag.
Board Ordering Semantics
Pinned ordering should be applied before the active board sort.
For every board sort:
pinned threads appear above non-pinned threads
pinned threads are sorted among themselves using the active sort
non-pinned threads keep the existing active sort behavior
Examples:
sort=newest: newest pinned threads first, then newest normal threadssort=oldest: oldest pinned threads first, then oldest normal threadssort=top: highest-scoring pinned threads first, then highest-scoring normal threads
For board views:
view=all: include pinned and non-pinned threads, with pinned firstview=liked: continue applying the liked filter first, then pin-aware ordering to the filtered set
This avoids creating a separate board region and keeps the behavior easy to reason about: pinning changes priority, not membership.
UI Plan
Update the board card template to render a small marker when thread_labels contains pinned.
Recommended display:
text:
Pinnedlocation: near the title or metadata line
style: compact metadata badge, not a large callout
Do not render all thread labels on board cards as part of this slice unless the implementation is already doing that cleanly. The only required board presentation change is the Pinned marker.
The thread page can continue showing normal labels through the existing thread-label display. If the current thread page renders Labels: pinned, that is acceptable for this slice.
Implementation Slices
Slice 1: Seed Canonical Rules Content
Status: completed in branch slice 1.
Files likely involved:
zenmemes_rules.txttests/fixtures/parity_minimal_v1/records/posts/thread-zenmemes-rules.txttests/fixtures/parity_minimal_v1/records/thread-labels/thread-label-20260530000001-zenrules.txt
Checklist:
Rules thread id: thread-zenmemes-rules.
Slice 1 verification: ./v3 test passed after making the hashtag-write smoke test independent of the number of seed thread-label records.
Slice 2: Add Pin-Aware Board Sorting
Status: completed in branch slice 2.
Files likely involved:
src/ForumRewrite/Application.phptests/LocalAppSmokeTest.phpor a focused board-ordering test
Checklist:
Slice 2 verification: ./v3 test passed. WriteApiSmokeTest::testPinnedThreadsSortBeforeNormalThreadsForBoardSorts covers pinned priority for newest, oldest, and top; existing board sort tests continue covering normal relative ordering.
Slice 3: Render Board Marker
Status: completed in branch slice 3.
Files likely involved:
templates/pages/board.phppublic/assets/site.csstests/LocalAppSmokeTest.php
Checklist:
Slice 3 verification: ./v3 test passed. LocalAppSmokeTest::testApplicationRendersCoreRoutes verifies the seeded rules thread link and exactly one board marker on /threads/.
Slice 4: Static Artifacts And Rebuild Verification
Status: completed in branch slice 4.
Files likely involved:
src/ForumRewrite/Host/StaticArtifactBuilder.phpexisting build or smoke commands
Checklist:
Slice 4 verification: ./v3 test passed. LocalAppSmokeTest::testStaticArtifactBuilderWritesApacheFriendlyArtifactLayout verifies the generated rules thread artifacts, static board marker/order, and rebuilt thread_labels_json; existing incremental label-write smoke tests continue passing.
Verification
Run the narrowest relevant tests first:
Canonical parser or read-model thread-label tests if seed records are added to fixtures.
Board ordering tests for
newest,oldest, andtop.Local app smoke tests covering board and thread rendering.
Static artifact smoke tests if public HTML artifacts are part of the deployment path.
Manual checks:
/threads/showsThe Rules of ZenMemes.comabove normal threads./threads/?sort=oldeststill shows pinned rules above normal threads./threads/?sort=topstill shows pinned rules above normal threads.the rules thread is reachable and replyable.
the rules body matches
zenmemes_rules.txt.
Follow-Up Option
If first-time conversion still needs a stronger prompt later, layer a one-time first-visit panel on top as a pointer to the pinned rules thread. Do not duplicate the rules body into that panel.