# PlotDirector Codex Operations Guide This repository is the PlotDirector ASP.NET Core application. Use this file as the first stop for operational knowledge that is not obvious from source. ## Environment Architecture - Main repo path: `/srv/repos/PlotDirector`. - Web app project: `PlotLine/PlotLine.csproj`. - Test project: `PlotLine.Tests/PlotLine.Tests.csproj`. - Solution file: `PlotLine.slnx`. - Word add-in project: `PlotDirector.WordCompanion/`. - Development site host files: `/srv/apps/plotdirector-dev/current`. - Development release archive: `/srv/apps/plotdirector-dev/releases/`. - Development systemd service: `plotdirector-dev`. - Service working directory: `/srv/apps/plotdirector-dev/current`. - Service environment file: `/etc/plotdirector/plotdirector.env`. - The dev app listens locally on `http://127.0.0.1:5050` behind nginx as `https://dev.plotdirector.com/`. ## Database - Production-style dev database name: `PlotDirector_Development`. - Older/local default database name in appsettings may be `PlotLine`; do not assume that is the effective dev database. - Runtime connection details come from `/etc/plotdirector/plotdirector.env`, key `ConnectionStrings__DefaultConnection`. - Do not print, copy, or commit connection strings, passwords, API keys, SMTP secrets, Stripe secrets, or OpenAI keys. - The SQL Server is reachable from the app host using the environment-file connection string. If a one-off SQL runner is needed, read the env file safely without shell-evaluating values: ```bash conn="" while IFS= read -r line; do case "$line" in ConnectionStrings__DefaultConnection=*) conn="${line#ConnectionStrings__DefaultConnection=}" ;; esac done < /etc/plotdirector/plotdirector.env export PLOT_DIRECTOR_SQL_CONNECTION="$conn" ``` - Do not use `source /etc/plotdirector/plotdirector.env`; unquoted values with spaces or special characters can break the shell and leak confusion into the task. - Use stored procedures for application database access. Do not add inline SQL in application code. - Old SQL scripts are immutable. Never edit an existing numbered script to fix a live schema issue; add a new forward-only script. - Before restarting/deploying during Story Intelligence work, check there are no active runs in `StoryIntelligenceRuns`, `StoryIntelligenceJobs`, or `WholeBookPlotSynthesisRuns`. - Do not restore, reset, or overwrite `PlotDirector_Development` unless the user explicitly asks and the target backup has been verified. Restore backups only to disposable verification databases first. ## SQL Migration Procedure - Number new scripts under `PlotLine/Sql/` using the next available prefix, for example `175_...sql`. - Scripts should be idempotent where practical: guard table/column/index creation with existence checks and use `CREATE OR ALTER PROCEDURE`. - Apply database changes to dev deliberately and capture the script path in the final response. - After applying SQL, run a smoke query that confirms the expected tables/procedures/columns exist and that the connection reports `PlotDirector_Development`. - Permanent delete paths have historically exposed missing cascade/cleanup dependencies. When adding tables that reference projects, books, chapters, scenes, characters, candidates, or runs, design deletion behaviour intentionally. ## Build And Test - Full test gate: ```bash dotnet run --project PlotLine.Tests/PlotLine.Tests.csproj ``` - Build gate: ```bash dotnet build PlotLine.slnx ``` - Publish gate: ```bash dotnet publish PlotLine/PlotLine.csproj -c Release -o /tmp/plotdirector-dev-publish-- ``` - Known quirk: running build and tests in parallel can cause static web asset cache file locks, especially around `*.staticwebassets*.json` or `rjsmrazor.dswa.cache.json`. Run build/test serially when verifying. - Prefer `rg`/`rg --files` for repository searches. ## Running Locally - From `/srv/repos/PlotDirector`, run: ```bash dotnet run --project PlotLine/PlotLine.csproj ``` - For local database/API work, provide configuration through environment variables, user secrets, or a safe local appsettings override. Do not rely on secrets committed in appsettings, and do not add new secrets to source. - The deployed dev service uses `/etc/plotdirector/plotdirector.env`; local terminal runs do not automatically use that file unless you explicitly provide equivalent environment variables. ## Development Deployment Use the existing physical-directory deployment pattern. `current` is a real directory, not a symlink. 1. Confirm the commit to deploy: ```bash git status --short --branch git log -1 --oneline ``` 2. Confirm no active Story Intelligence work is running before restart. 3. Publish to a fresh temp folder: ```bash release="-$(date -u +%Y%m%d%H%M%S)" publish_dir="/tmp/plotdirector-dev-publish-$release" release_dir="/srv/apps/plotdirector-dev/releases/$release" backup_dir="/srv/apps/plotdirector-dev/current-before-$release" dotnet publish PlotLine/PlotLine.csproj -c Release -o "$publish_dir" ``` 4. Install the release: ```bash sudo mkdir -p "$release_dir" sudo cp -a "$publish_dir"/. "$release_dir"/ sudo chown -R plotdirector:plotdirector "$release_dir" sudo cp -a /srv/apps/plotdirector-dev/current "$backup_dir" sudo chown -R plotdirector:plotdirector "$backup_dir" sudo rsync -a --delete "$release_dir"/ /srv/apps/plotdirector-dev/current/ sudo chown -R plotdirector:plotdirector /srv/apps/plotdirector-dev/current sudo systemctl restart plotdirector-dev ``` 5. Verify: ```bash systemctl is-active plotdirector-dev systemctl status plotdirector-dev --no-pager -n 30 curl -k -L --max-time 20 -o /tmp/pd-dev-home.html -w 'http_code=%{http_code}\nfinal_url=%{url_effective}\nbytes=%{size_download}\n' https://dev.plotdirector.com/ sudo stat -c 'CurrentDll=%n %y %s bytes' /srv/apps/plotdirector-dev/current/PlotLine.dll ``` - A `HEAD` request to the dev site may return `405`; use `GET` with `curl -L` for the real smoke check. - Keep the release folder and current-before backup named with the deployed short SHA and UTC timestamp for traceability. ## Project Structure - `PlotLine/Controllers/`: MVC controllers. - `PlotLine/Views/`: Razor views. - `PlotLine/Services/`: application services, Story Intelligence workers, OpenAI integration, import/onboarding flow. - `PlotLine/Data/`: repositories and database access. - `PlotLine/Models/`: domain and DTO models. - `PlotLine/ViewModels/`: UI view models. - `PlotLine/Hubs/`: SignalR hubs. - `PlotLine/wwwroot/`: static CSS/JS/assets. - `PlotLine/Sql/`: forward-only SQL migration scripts and stored procedure definitions. - `PlotLine.Tests/Program.cs`: lightweight integration/regression test harness. - `docs/` and `Docs/`: project documentation stores; check both before creating new documentation. ## Story Intelligence Conventions - PlotDirector must work for arbitrary books and authors. Do not add production special cases for Alpha Flame or any other manuscript-specific names, places, vehicles, objects, or relationships. - Manuscript-specific examples may appear in regression fixtures only, and tests should include unrelated examples so production code cannot pass by recognising one fixture. - Use generic evidence for significance: recurrence, scene/chapter presence, ownership, narrative prominence, title presence, knowledge significance, and participation in important events. - Relationship classification must use generic interaction evidence and configured relationship types, not character-specific rules. - Character/alias resolution should use canonical identities, aliases, and evidence rather than book-specific names. - Scene manuscript text in `SceneManuscriptSources` is the durable source for canonical scene analysis. - Core import and Story Intelligence are separate phases. Do not reintroduce the old visualisation/replay workflow as part of production import. - Whole-book plot synthesis should happen after character resolution and should not add another per-scene AI pass. - If prompt/source text is too large, fail the specific synthesis job clearly rather than silently truncating manuscript text. ## Operational Safety - Avoid destructive git commands such as `git reset --hard` or `git checkout --` unless the user explicitly asks. - The worktree may include user changes. Inspect before editing and do not revert unrelated changes. - Do not deploy while an import or Story Intelligence analysis is active unless the user explicitly accepts the interruption. - Do not modify current database state for read-only investigation tasks. - Do not apply SQL during read-only audit tasks. - Use disposable verification databases for restore checks and drop them afterwards unless instructed otherwise. - Keep deployment and SQL notes concise in final responses: commit, SQL script, tests, deployed release, service status, and any residual risks.