You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: .changelog/NEXT.md
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -123,3 +123,5 @@
123
123
- **`getSettings()` now serves from an in-memory cache instead of re-reading settings.json on every call.** `getSettings()` is invoked 100+ times across the codebase (several per request), each previously doing a fresh filesystem read + JSON.parse of app-wide, rarely-changing data. It now memoizes the parsed settings, populated lazily on first read and refreshed off the `settings:updated` event that every `save()`/`updateSettings()`/`updateSettingsWith()` already emits — so app-driven writes keep the cache coherent while write paths still read fresh off disk inside their write queue for the read-merge-write, preserving write-ordering guarantees. Mirrors the existing `settings:updated`-invalidated cache in `sharing/annotationIdentity.js`. Alongside it, a few independent per-file read loops are now parallelized (`digital-twin-analysis.validateCompleteness`, editorial series-health's series+settings load) and hot page derivations memoized (`Review` grouping/sorting, `Tribe` care-queue), cutting redundant work on socket-driven re-renders.
124
124
125
125
- **Branch & PR reconciliation now runs on any managed app as a Chief-of-Staff scheduled task — not just PortOS.** The branch reconciler (finish this machine's unfinished local git work: delete fully-merged orphaned branches + their worktrees, open PRs for pushed-but-unopened work, resolve merge conflicts, drive the review loop, and auto-merge when a PR is green) used to be a PortOS-only feature with its own daily cron, `/api/branch-reconcile` route, `settings.branchReconcile` toggle, and a dedicated Settings tab — hardwired to the PortOS checkout. It is now a first-class per-app CoS task type, **`branch-reconcile`**, configured like every other improvement task (per-app enable, provider/model, cadence, cooldown, budget) under Chief of Staff → task scheduling. It runs `perpetual` (drain-until-done): each dispatch runs the deterministic, peer-safe cleanup + classification against the *app's* repo, dispatches the coordinator agent only while actionable in-flight branches remain, then parks on a daily recheck — so no agent is burned on a no-op run. A progress-signature convergence guard ensures the drain only re-dispatches when the actionable set actually *changed* since the last run (a branch advanced NEEDS_PR→IN_REVIEW→merged, or a new/removed branch): a cycle that leaves the same branches in the same states (a branch judged "not ready", a PR blocked on human review or red CI) parks instead of re-spawning an identical coordinator back-to-back. The peer-safety guarantee is unchanged (only local `refs/heads/` are ever touched; a federated peer's branch exists here only as a remote-tracking ref and is structurally invisible), and the per-behavior toggles (`cleanupMerged` / `openPr` / `resolveConflicts` / `autoMerge`) are now per-app task-metadata overrides. Off by default; enabling it on an app is the user's explicit consent to let it drive PRs on a schedule. The old dedicated scheduler, route, settings key, and Settings tab are removed; a migration (`scripts/migrations/170-branch-reconcile-to-cos-task.js`) carries a previously-enabled `branchReconcile` opt-in into the new task (cron→recheckCron, actions→per-app metadata) scoped to the PortOS app, and drops the dead settings key — so an install that had it on keeps reconciling instead of silently stopping. (`server/services/branchReconcile.js`, `server/services/cosTaskGenerator.js`, `server/services/taskSchedule.js`, `server/services/taskPromptDefaults/prompts.js`)
126
+
127
+
- **[issue-2175] Generation-side character framework + structure doctrine (CWQE Phase 10 remainder).** Following the worldbuilding-doctrine slice (#2219), the character-generation and structure-planning prompts now teach the craft up front. The character bible gains the Ghost → Wound → Lie → Want → Need chain (with interlock checks: state the Lie in one sentence; the Need/Truth is its direct opposite; the Ghost causally explains the Lie), a declared arc type (positive/negative/flat), the Three Sliders (proactivity/likability/competence 1–10, rule: HIGH on ≥2 or one-with-growth; all-low = boring, all-high = Mary Sue), and a secrets list — all OPTIONAL so pre-#2175 records round-trip unchanged (`server/lib/storyBible.js` sanitizer + Zod-shape parity via the existing `canonArrayField` sanitize-on-write, client mirror in `client/src/lib/bibleLimits.js`, character-sheet UI in `CharacterDetailEditor.jsx` with `htmlFor`/`id` pairing, and no-clobber merge in `universeCharacterExpand.js` for the AI-expand path). The `character.consistency` / `arc.*` editorial checks now receive the authored Lie/Want/Need/arc-type when present (via `canonCharacterTraitsSummary`) so they reconcile plan-vs-delivery instead of inferring both. Structure prompts gain lean doctrine: `pipeline-season-episodes.md` a try-fail mandate (60%+ of middle episodes end "Yes, but"/"No, and"), beat rules (Catalyst external; Break Into Two a protagonist choice; All Is Lost includes a death — literal or of a hope/relationship/identity) and an active-climax rule; `pipeline-arc-overview.md` MICE-style thread nesting (threads close in reverse order of opening; name the opening/closing thread per season). Shipped-template edits ship to existing installs via hash-keyed migrations 171/172/173 (with the drift-cross-sync of prior owners 003/005/019/027/166). Remaining Phase 10 items (Le Guin style doctrine into the style-guide flow) stay tracked on #2175.
{name: 'ghost',label: 'Ghost (backstory wound cause)',placeholder: 'the past event that wounded them — must causally explain the Lie',max: L.GHOST_MAX,type: 'textarea'},
52
+
{name: 'wound',label: 'Wound',placeholder: 'the lasting emotional damage the Ghost left',max: L.WOUND_MAX,type: 'textarea'},
53
+
{name: 'lie',label: 'Lie (false belief)',placeholder: 'state in one sentence — "I only matter if I win"',max: L.LIE_MAX,type: 'textarea'},
54
+
{name: 'need',label: 'Need (Truth — opposite of the Lie)',placeholder: 'the direct opposite of the Lie — "I matter whether I win or lose"',max: L.NEED_MAX,type: 'textarea'},
55
+
{name: 'want',label: 'Want (external goal)',placeholder: 'the concrete goal they pursue — usually conflicts with the Need',max: L.WANT_MAX,type: 'textarea'},
Copy file name to clipboardExpand all lines: data.reference/prompts/stages/pipeline-arc-overview.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -60,7 +60,8 @@ The series is grounded in this World Builder world: **{{worldName}}**. When you
60
60
-**`logline`** — one sentence; what changes in this season.
61
61
-**`endingHook`** — the image or line that pulls the audience into season N+1. Skippable for the final season (leave empty).
62
62
-**`episodeCountTarget`** — integer. Divide `issueCountTarget` across the seasons roughly proportionally to season weight. Sum of all `episodeCountTarget`s should approximately equal `issueCountTarget`.
63
-
6.**Foreshadowing ledger (2–6 seeds).** Plan the major setups the series plants early and pays off later — a Chekhov's gun, a prophecy, an unexplained scar, a withheld secret. For each seed record:
63
+
6.**Thread nesting (MICE).** Treat each season as opening and closing narrative threads (a Milieu / Inquiry / Character / Event question). Threads must close in the REVERSE order they open — the last thread opened is the first resolved, like nested brackets. In each season's `logline` (or the `summary`), name the thread this season OPENS and the thread it CLOSES, so the nesting is legible: a season that opens a thread it never closes leaves a dangling question; one that closes a thread out of order breaks the nesting.
64
+
7.**Foreshadowing ledger (2–6 seeds).** Plan the major setups the series plants early and pays off later — a Chekhov's gun, a prophecy, an unexplained scar, a withheld secret. For each seed record:
64
65
-**`label`** — a short name for the seed (e.g. *The locked room*, *Mara's limp*, *The recurring bell*).
65
66
-**`plantIssue`** — the 1-indexed issue number where it's first planted (subtly introduced, not explained).
66
67
-**`reinforceIssues`** — 0 or more issue numbers between plant and payoff where the seed is quietly reinforced so the reader doesn't forget it. Keep it a light touch — a glimpse, not a recap.
0 commit comments