docs/current/content-and-publishing.md
Download Markdown
The private novel continuation read/save endpoints treat cancellation of the incoming request
as HTTP 499 before returning through MVC. Navigating away during the publication lookup no
longer surfaces as an unhandled application failure in the debugger. Already canceled reads
do not start database work; independent cancellations and genuine database/storage failures
still propagate. Account identity, private caching and normal progress validation are unchanged.
Ownership: Public Web ContinueController; regression coverage: ContinuationRequestCancellationTests.
Studio is the authoring owner. PublicWeb reads admitted content; visiting a public page must not initialize or publish a draft. Engineering articles, Journal publications, lore, novels, music, videos and character experiences retain their own content models and shared editorial rules.
Editorial lifecycle
The November 5 beta credit catalog is Starter Cache 150 credits / USD 6.99,
Neon Reserve 400 / USD 12.99, and Archive Vault 1,000 / USD 25.99. These are
one-time purchases. scripts/sql/20261105-beta-credit-packs.sql applies the reviewed
edit to the existing three USD catalog rows, with old/new-value preconditions and
idempotent retry. The catalog database remains the authority for Wallet, cart and
new checkout quotes; pending/completed purchase snapshots and existing wallet
balances retain their original amounts. Do not rewrite historical EF seed migrations
or previously issued purchase receipts to change today's offer.
The public Engineering Knowledgebase uses eight versioned Gynara concept illustrations: Reika for
platform architecture, Akari for grounded answers, Synaptica for the hybrid story runtime, Miyu for
authoring, Hikari Ame for publishing, Yuki for ownership, Faye for private rooms, and Neuro-X for
embodiment research. The images use the existing sprite identities as references. They are editorial
concept art; the embodiment article keeps its Experimental status and research placement.
Content/PublicAssets/engineering-gynara-v1.json records the prompts, reference/source hashes and
WebP delivery metadata. The files live under the configured media root at
public-assets/images/engineering/gynara-v1, registered in external-public-assets.json.
scripts/database/Publish-EngineeringGynaraArtworkV1.sql changes only the eight published image
paths, rejects intervening image changes, and preserves article text, status and timestamps.
Web Shared EngineeringArtwork provides character-specific alt text. Responsive crops keep faces
visible in topic cards; mobile articles display the complete illustration above the heading.
The card framing in engineering-knowledgebase.css covers all three installed artwork versions
(gynara-v1, gynara-v2, gynara-v3), including the six Gynara development articles. Keep the
right-side character focal point when adding a version, with a farther-right crop for Akari's
engine illustration; engineering-artwork.test.cjs checks
all nineteen installed illustrations and seventeen public cards at desktop and mobile widths.
Author draft -> submit current revision -> review -> approve exact revision -> publish -> retrieve
Assignments determine what an Editor can change. Admin approval and publication remain explicit steps. Editing an approved draft can require another review. Imported/generated content is a candidate, not authorization to publish. Character visibility and VN/room release approval are separate decisions.
Use Content CMS for catalog work and the dedicated editors for character/room or VN graph changes. Keep stable slugs, keys and immutable release hashes. A deployed private VN remains private even if its owning character later becomes public. Publishing a VN does not publish its character.
Replace Journal images from a post
Admins see Replace image beside a post's cover, Markdown article images and featured image embeds. The control opens a focused Studio editor for that placement. Upload a JPEG, PNG or WebP (up to 25 MB and 40 megapixels), or choose a published, non-mature Media Library image. Preview the selection, then Save image to return to the same post and image. Posts without a cover offer Add cover image. Members and Editors do not receive these controls or replacement permissions.
Studio owns the Admin authorization, antiforgery token and write. PublicWeb only renders trusted Studio destinations; managed development starts Studio through the existing loading screen. Replacements retain the post's publication state, title, text outside the selected image, captions, URL and comments. They change that post's placement rather than overwriting an image used by other posts. Uploads use the existing decoded-image validation and immutable Media Library paths. An upload is published when its placement saves; interrupted or stale submissions may leave an unpublished upload available in Media Library.
A conditional write rejects changes made while the editor was open or the upload was running. Markdown
reference images are replaced by occurrence, preserving other uses of the reference. No schema migration
is needed. Ownership: JournalImagesController, IJournalPostImageEditor, the Journal media owner's
JournalPostEmbedService.Images.cs, JournalPostImageMarkup, and journal-images.js. Regression coverage
includes relational replacement tests, HTTP authorization/antiforgery tests and an isolated browser fixture;
these checks do not replace live post artwork.
Journal's area _ViewImports.cshtml must register the shared tag helpers so studio-path controls
render as navigable links. JournalImageLinkViewTests renders the compiled post and verifies cover,
add-cover and featured-image destinations, including the managed Studio loading route and Admin scope.
Engineering and Akari knowledge
CMS Engineering notes answer one why/how question with a summary, What, Why, How and an Akari brief. Production/Foundation notes appear as current published topics; Experimental/Archived notes identify proposals or historical designs. Audience filtering applies to both index and article reads.
The source-controlled handbook provides the current architecture and onboarding reference, updated with code. It complements CMS notes rather than overwriting future editorial edits at startup. Staff procedures remain in the Admin handbook. Rebuild approved knowledge projections after a coordinated editorial refresh; a successful projection proves availability, not the quality of every model answer.
Discovery and relationships
Discovery filters publication, text, content kind and applicable relationships in SQL before its bounded candidate limit. Profile and related-content requests query only relevant catalogs. The result limit is deliberate: the current search is not an unlimited full-text index or an exact count of every matching record. Empty results retain selected filters so members can recover.
Novel artwork and chapter media
Admins can open Novel artwork from the authoring library or a novel's chapter list. Each novel has a private collection of story moments, generation briefs, revision notes and immutable image/video versions. Uploading selects a new candidate while retaining earlier versions. Selecting another take does not change a chapter: every placement pins an exact version. Brief downloads include character guidance and the anatomy/continuity review checklist. This area prepares and accepts generation work; it does not call an image generator itself.
In the chapter editor, expand Images and videos at story moments, load artwork, place the manuscript
cursor between paragraphs, choose a version and description, then insert it. Repeat for additional
moments. Preview chapter layout previews unsaved text; normal save/review/publication controls still
apply. The manuscript stores standalone [Description](novel-image:<32-digit version ID>) or
[Description](novel-video:<32-digit version ID>) paragraphs. Move or remove those lines to edit placement.
Fenced code, inline links and arbitrary HTML do not grant media access. Publication review rejects
missing files and mismatched media types. Editor-assigned authors retain normal manuscript editing;
the private candidate picker and uploads are Admin-only.
Readers see images at those positions, with full-size links and captions. Videos have native playback controls and never autoplay. Cinematic text playback reveals each media block when it reaches that point; Comfort reading shows all placements with the chapter. Public media URLs require a currently published, non-retired chapter and a matching placement in that novel. Staff preview is authenticated. Source prompts, review notes and unplaced candidates remain private.
Chapter narration is a proposed next phase: pre-generate Akari-only Chatterbox audio, retain the exact text/voice receipt, indicate stale narration after manuscript edits, and expose optional Member playback with pause/seek. The current artwork feature does not generate narration or add a narration player.
Implementation: src/DrakimaCore.Application/Novels/NovelArtworkContracts.cs,
Infrastructure/Novels/FileNovelArtworkLibrary.cs, Services/Novels/NovelChapterMediaMarkup.cs,
Studio NovelArtworkController and chapter-media-editor.js, Public ReaderController.Media.cs.
Member-facing state
Video descriptions and discussion sources
Every video needs a 200–4,000 character description covering its premise, themes and connection to established character lore, plus at least one associated published canonical Gynoid. Both CMS release review and Upload and publish enforce these requirements; upload validates before writing media. The upload form now accepts featured characters. Draft descriptions may remain incomplete until review.
For music videos, authors must link the published song lyrics in the description using a relative
Markdown link to its Lyrics path, for example /Music/the-gynara-legend-corrupted-circuits/tracks/2/lyrics.
Use the track ID from its Lyrics page, not its track number. Up to three lyric links are supported.
The release check validates each linked track, album and both catalog products against the public
lyrics reader's publication/retirement rules. Standalone videos explain their premise without a lyric
link. Editorial review still checks substance: a length threshold cannot certify factual quality.
Describe confirmed scenes, separate interpretation from canon, and leave unknown origins/endings open.
The watch page renders these descriptions through the existing HTML-disabled Markdown renderer.
For a tagged video reply, VideoDiscussionContext reads the current description, the associated cast's
public biographies and explicitly linked published lyrics through IVideoDiscussionSources and the
focused ApplicationDbContextVideoDiscussionSources adapter. No title guessing, external fetching,
comment-selected sources or private-card reads occur in this evidence path. The tagged character's
existing Community identity remains authoritative. Lyrics are framed as performance, not proof of
literal events or powers; the model must not claim to have watched scenes absent from the evidence.
Video evidence has a 12,000-character outer cap: description 4,000, up to three biographies of 1,200
each (tagged/primary cast first), and 4,000 shared across lyric sources. Truncated sources are labeled.
Journal and novel source excerpts retain their 6,000-character cap and existing three-comment lineage.
When optional Akari semantic review is enabled, it resolves the same current video evidence before
assessing the candidate, rather than judging lore or lyric claims without their sources.
Content/Videos/discussion-descriptions-v1.json records the reviewed descriptions for Mistress of the
Night (Rykara), Eccentric Doll and Akari and the Clock. It is an editorial reference, not a startup seed;
later CMS edits remain authoritative. This change uses existing descriptions and cast relationships,
with no schema migration or identity/card revision. The Runtime compatibility port avoids changing
the installed Arcade-pinned shared Application assembly. Regression owners are
VideoDiscussionContextTests, VideoUploadServiceTests and CommunityThreadParticipationServiceTests.
Live Community threads and Gynoid mentions
Journal posts, public videos and novel chapters share a Community thread widget. While the page is visible, it checks for published replies every two seconds and inserts updates without a page reload. This includes completed LLM replies; generation itself is not streamed into the public thread. Open reply/report forms, typed drafts and the caret survive updates. Thread/post totals and moderation changes are refreshed too. A short accessible status announces new posts without moving focus. Posting a thread or reply also uses AJAX: the page stays open at the same reading position, and the saved comment appears in the widget. Incoming replies above the viewport preserve the visible text's position without smooth scrolling. Submission disables duplicate clicks, preserves drafts on errors, and clears only the submitted text after success. Text entered while a request is running stays intact. Successful replies collapse their input form back to Reply. Failed submissions and new drafts typed while posting keep the form open; keyboard focus returns to Reply when its submitted editor closes. After a successful post, an older in-flight snapshot is invalidated without aborting its HTTP request. It finishes without being displayed, then one immediate refresh reads the saved thread; concurrent posts coalesce into that refresh. This avoids canceling the server's database read after every post (which can break into an attached debugger even when the comment and AI reply saved successfully). Video polling resolves only the current public video identity before reading the thread, skipping watch-page playlists and related videos. Withdrawal and viewer permissions are still checked on each poll. Navigation, hidden-tab and timeout cancellation retain the existing request-aborted handling. Without JavaScript, the existing form submission and redirect remain available.
Typing @ in a thread or reply opens the public Gynoid name list, including all 19 currently published
characters. Further typing filters names and handles; click a name or use Up/Down and Enter/Tab to
insert its registered mention. Escape dismisses the picker. Newly inserted reply boxes have the same
picker. The list comes from IGynoidMentionCatalog, excluding unpublished and project-local identities;
it does not modify character cards or prompt context.
Clear all in the notification bell or inbox updates the member's notifications in place. It does not navigate, reload the current page, interrupt playback, or replace open editors. The menu, badge and any visible inbox counts/list refresh from the caller's server-rendered result; system checks remain available. A pre-clear poll cannot restore dismissed entries. Confirmation, antiforgery and account/audience checks still apply; failures retain the current view. Without JavaScript, the form returns to its validated local page instead of sending the member to the notification inbox.
Community Gynoid replies use 19 dedicated, individually generated close-up portraits based on each
character's reaction pictographs. Both retained and new replies resolve the versioned image through
Services/Social/CommunityGynoidAvatarCatalog.cs, including Akari's Lorekeeper replies. The 256-pixel
WebP exports total about 413 KiB, display in the existing circular avatar frame, and load lazily.
Member avatars keep their profile setting; unregistered characters retain their existing portrait.
This display change does not edit Gynoid profiles, character cards or stored comments.
Content/PublicAssets/community-avatars-v1.json records all 19 prompts, references and accepted hashes.
Images live in the configured media root at
public-assets/images/gynoids/<slug>/cards/profile/community-avatar-v1/<slug>-community-avatar-v1.webp
and are registered in external-public-assets.json. The isolated community-avatars.test.cjs browser
fixture checks the installed files, desktop/mobile circular rendering and an incoming AJAX reply.
The existing public page actions accept refreshCommunity=true, recheck publication visibility and
return only _ContentCommentList. Viewer-specific, non-cacheable ETags avoid repeatedly transferring
unchanged long replies. Hidden/navigation-away pages pause polling; requests time out, retry with
backoff after connection failures, and stop on revoked access or withdrawn content. No database change
is required. Ownership: Web Shared Presentation/CommunityThreadRefresh.cs, shared comment partials,
content-engagement.js and community-mentions.js; Public Web Journal, Videos and Reader actions.
Regression coverage: CommunityThreadRefreshTests, the matching JavaScript tests, and the isolated
Tests/Browser/community-threads.test.cjs browser journey. That fixture uses synthetic HTTP responses
and the real browser scripts; it does not start the website or call a live model. The additional
community-comment-position.test.cjs fixture checks desktop/mobile viewport stability during posting,
validation errors and incoming replies above the reader.
Continue where you left off
Signed-in members see Continue where you left off below their main identity, services and security
information within Your Profile, the first avatar-menu
link: recent retained chats, favorite Gynoids, current novel chapters and explicit bookmarks,
their existing Arcade run, and owned music. /Continue redirects to the profile's continuation section.
Neither Legacy nor Builder Home embeds private continuation. First-visit welcome videos keep their existing behavior. All member projections
use private/no-store responses; the hub never creates chats, starts gameplay, spends credits or invokes AI.
Chat links carry the exact owned thread key. Expired unpinned chats, empty drafts and unpublished
characters are excluded. Favorite toggles live on published Gynoid profiles. Arcade links open the
existing Continue flow, preserving retained release/save ownership. Music comes from active entitlements.
Novel readers and publication contents load the signed-in account's reading position before resuming. Automatic progress is coalesced; explicit bookmarks save immediately. An opaque per-novel revision rejects stale device writes, while a per-account browser cache keeps reading usable during outages. Resume measures the chapter's document position after fonts and illustrations settle, preserving the same reading percentage across desktop and phone layouts without overwriting it during restoration. An older tab must reload after a conflict. Guest browser progress is not silently assigned to an account: Import browser progress offers an explicit import when that account has no saved novel position. Guests retain local reading progress. Editorial previews never write account progress. Published chapter membership is checked again when saving and resuming; a withdrawn chapter cannot become a hub target.
An optional in-site notification links to /Identity/Account/Manage#continue during signed-in visits.
It is enabled by default and delivered no more than once per rolling seven-day period, across devices,
tabs and host restarts. Members can disable future reminders with the setting beside their dashboard.
Opening a continuation reminder marks it read and dismisses it from the member's bell and inbox,
then redirects to the continuation anchor so the browser scrolls directly to that section. Opening
Your Profile normally starts with the main profile information. Other notification types keep their
existing behavior. Reading/clearing notifications and toggling the preference do not reset the delivery time. The account
lease serializes preference changes, delivery and erasure; a durable idempotency key makes interrupted
publication safe to retry. Notifications expire after seven days; delivery failure does not block navigation.
No email, AI provider, background broadcast or new database schema is involved.
The bounded FileMemberContinuationStore owns favorites/bookmarks and reminder preferences/receipts under
<MediaRootPath>/protected/member-continuation (or private App_Data/member-continuation without
external storage). Public hosts must share this private root to sync accounts between hosts. Files are
hashed by account identity, serialized under a cross-process lease and replaced atomically without
backup/history copies. Existing account export/erasure participants include this data; an erased
account's content-free tombstone rejects late writes. No database schema migration is needed.
The Runtime compatibility owner composes existing novel/music/Arcade ports and the existing Gynoid
read adapter; it does not alter the pinned shared Application assembly used by Arcade.
The member dashboard and chat metadata adapter are registered only in PublicWeb, alongside its Arcade
catalog. All host profiles retain the private store and account export/erasure participant. Workers and
Studio do not depend on the member dashboard or need public Arcade navigation services to start.
Implementation: Contracts/Continuity, Services/Continuity, Infrastructure/Continuity,
Composition/DrakimaContinuationComposition.cs, Public ContinueController, the MemberContinue,
GynoidFavorite and NovelAccountSync components, and shared novel-account-sync.js.
Discovery and reader experience
The beta home offers character discovery and Drakima Arcade, which leads to the
/DrakimaArcade page for deployed dedicated games, with an upcoming-releases message when none are
available. Both authored visual novels and combat chapters require a verified current release; member entry and replay are free,
and the authored story, battles and saves need no AI connection. Its Step into their world introduction highlights
private conversations, character voices, outfits, member memory, Romantic Balcony and free lore-inspired
Moments, with a Meet the Gynoids button. Story-only cards show choices and save/resume instead of battle controls;
hybrid stories distinguish free scripted playback from optional AI and speech credit use. Detailed room introductions, free Lead Moments, AI/voice
pricing guidance and beta availability belong in the Site Guide. AkariLoreKeeper's widget offers
interactive help. The first combat chapter is undergoing isolated acceptance; source installation alone
does not publish a game. See the staff Turn Based Combat guide for its delivery state and operating steps.
Desktop navigation lists Home, Journal, Meet the Gynoids, Drakima Arcade, Music, Videos and Light Novels.
Explore groups Engineering, Gallery, Discover and additional published Primary
page links without removing their routes. Long page labels wrap inside its bounded, scrollable dropdown.
Admin Console remains in the account dropdown for authorized staff, without a duplicate main navbar link.
The primary menu expands at 1400 pixels; smaller windows retain the collapsible menu. An open Explore
dropdown occupies a full row in that menu, keeping its links clear of account controls. The catalogue
uses /DrakimaArcade, and selected-game links use /DrakimaArcade/games/{key}. Admission rules are unchanged.
Shared scroll padding leaves room for the sticky header when focusing or following page anchors.
Light novel chapters offer Comfort reading in Reading options: a quiet panel, plain type and a narrower reading measure. This device preference carries across chapters and reveals the full text instead of automatically streaming it. Replay stream remains explicit; bookmarks, discussion links and Binge Music keep their existing behavior. Browser storage failure does not prevent reading. Chapter navigation, bookmarking and discussion stay in a compact toolbar. Reading options are collapsed by default on desktop and mobile; the keyboard-accessible disclosure reveals appearance, text playback and speed. The optional Binge Music panel groups transport, playback modes, volume and favorites in a matching dark layout with visible focus and pressed states. Its chapter-specific styles leave private-room controls and the shared playback lifecycle unchanged. At desktop widths (1200px and above), Reading options and Binge Music disclosures sit in the middle of the top toolbar. Smaller screens retain stacked native disclosures; their open state stays in sync when resizing. Without JavaScript, native disclosures remain available at every size.
The contents also indexes embedded Prelude, Interlude and Postlude headings and their numbered parts.
Repeated section headings appear once; code samples and blockquotes are excluded. Links use the same
Markdown heading IDs as the reader. Opening a section reveals its chapter and positions the heading
after preceding illustrations load. Canonical chapter URLs, manuscripts, progress and bookmarks remain
chapter-owned. A Gynoid's Dream exposes the four-part Interlude after Chapter 40 and Postlude after
Chapter 60 through these links. Ownership: Services/Novels/NovelChapterContents.cs and
PublicNovelReaderService.cs, mapped by the public reader controller.
The shared footer links to the complete Site Guide. The XML sitemap remains available to crawlers
through /sitemap.xml and robots.txt, without a reader-facing footer link.
The footer's Beta feedback link opens the signed-in Support Desk with a reviewable page label and request reference. Only route names are carried from the page, never its query string or entity keys. Beta feedback does not inherit an AI session or offer transcript attachment. Members can clear the references, edit the message and review the private preview before explicitly sending it to the team.
Public AI pricing is one credit for Casual, two for Thinking and three for Research; completed-response speech is a separate one-credit purchase. Daily wallet top-up brings the balance to ten, rather than adding ten to every existing balance. Purchased balances are not reduced. Stable operation/ledger keys prevent retries, cached answers and ready audio playback from charging again. Creator exemptions remain server-owned.
Implementation evidence: Services/Editorial, Services/Engineering/EngineeringKnowledgeService.cs,
Services/Discovery, Infrastructure/Credits, src/DrakimaCore.Studio.Web/Areas/Admin,
src/DrakimaCore.Public.Web/Controllers/SupportDeskController.cs,
src/DrakimaCore.Web.Shared/wwwroot/js/novel-reader.js,
src/DrakimaCore.Public.Web/wwwroot/css/novel-reading.css.