Files
settled-reach/docs/sprints/sprint-26/server.md
T
jpmschweitzerandClaude Opus 4.6 bccdcfcdcb docs(docs): add frontmatter to all sprint briefings
Standardized YAML frontmatter on all 115 sprint briefing files across
sprints 1-26 with title, description, type, status, sprint number, and
team fields.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-14 00:15:45 +01:00

74 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
title: "Sprint 26 — Server Briefing"
description: "Composable behavior engine, SQLite settings storage, voice pipeline observer integration"
type: sprint
status: archived
sprint: 26
team: "server"
---
# Sprint 26: Clean House — Server Tasks
**Goal:** Ship the voice pipeline to production by integrating observer, removing v0.1 dead weight, and stabilizing the codebase.
**Branch:** `server`
**Agents:** Dudley (simulation), Tyre (arch), Hoshe (QA)
## Carry-over from Sprint 25
| # | Title | Status | Notes |
|---|-------|--------|-------|
| #633 | Composable behavior engine | backlog | Deferred from Sprint 25 — behavior pool explosion problem. No blockers. |
## New Tickets
| # | Title | Blocked by |
|---|-------|------------|
| #627 | SQLite settings storage | — |
| #650 | ContentType::Factual — LLM bypass for fact-bearing lines | — |
| #652 | Voice pipeline: observer integration | #650 (preferred, not hard block) |
| #655 | Remove v0.1 content loading system | — |
| #651 | Friendly and RoutineDeviation tells — iterate post-ship | — |
Use `tooling/db/ticket show <id>` for full details.
## Key Decisions
- `decisions/content.md` — D-138 (LLM re-voicing pipeline: ContentType::Factual from Spike 2, observer wiring spec), D-121 (voice is culture-driven), D-122 (all NPCs generated)
- `decisions/scope.md` — D-117 (zero investigation content in v0.2), D-114 (generator-first)
## Open Questions to Resolve Early
- **Q-057: Composable behavior generation** — partially resolved by D-138 (resolves the pipeline question). #633 implementation still needs a concrete behavior primitive format. Resolve the data structure before writing code. Resolve before #633 starts.
## Notes
- **#650 ContentType::Factual:** The voice module currently routes all content through the LLM. Spike 2 showed that 2B models corrupt quantitative lines ("14 crates in bay seven" → "fourteen crates are missing") and invert denials. Add `Factual` as a third `ContentType` variant alongside `Dialogue` and `Behavior`. Lines tagged `Factual` skip the LLM entirely and are served as base text. The classification logic lives in `server/src/voice/prompt_builder.rs` (currently builds prompts for all content types). Paula endorsed ContentType::Factual in the Spike 2 session — do not revisit the design decision.
- **#652 Voice pipeline observer integration:** The pipeline exists (`server/src/voice/`) but nothing wires into it yet. The observer emits behavior and dialogue events to the client via `server/src/bridge/types.rs` — the voice lookup must intercept those events before they hit the bridge. Integration points: `server/src/voice/lookup.rs` (the query interface), `server/src/perception/observer/mod.rs` (snapshot generation), `server/src/bridge/text_renderer.rs` (current text output path). Fall back to base text on cache miss — never block on LLM. Tell behaviors are passthrough (already routed per #642). Prefer landing #650 first so `Factual` content type is established before observer wiring routes content to it.
- **#655 Remove v0.1 content loading system:** Delete `server/src/content/` entirely: `loader.rs`, `types.rs`, `line_pool.rs`, `hot_reload.rs`, `spawn.rs`, `template.rs`, `instantiation.rs`, `entanglement.rs`, `mod.rs`. Also remove: `tooling/content-converter/`, `tooling/validate-content`, `content-ron/` compiled output, `content/_meta/` style guides. Server tests to delete: `server/tests/content_loading.rs`, `server/tests/content_runtime.rs`, `server/tests/content_scaling.rs`, `server/tests/template_instantiation.rs`, `server/tests/template_schema.rs`. **Preserve** `content/global/` (enums, knowledge, culture profiles — still live). Before deleting `server/src/content/types.rs`, audit re-exports: any types still used by other modules must be moved, not dropped. Run `cargo check` after each deletion step, not once at the end.
- **#633 Composable behavior engine:** Current hand-authored behavior pools in `server/src/npc/routine.rs` enumerate culture×zone×role combinations, which won't scale to the generator. Goal: introduce a behavior primitive format (role action + culture modifier + context tag) and an assembly function that composes them at NpcBlueprint instantiation time. The `NpcBlueprint` struct in `server/src/npc/blueprint.rs` is the output target. Do not delete existing behavior pools until new assembly produces equivalent output — verify with an eyeball diff on generated behaviors for seed 42.
- **#627 SQLite settings storage:** Persistent settings via SQLite on the server side (rusqlite with bundled feature — zero runtime dependency). Architecture: settings live on the SERVER in a SQLite database with per-player tables. The client sends `ChangeSettings` commands over IPC, same as any other player action. The client never touches the database directly. Scope: keybindings, audio volume, display preferences, accessibility options, AI-Enhanced Dialogue toggle. This must land before #646 (client toggle) so the toggle has a real persistence layer instead of a flat config file. Key integration point: the existing subprocess IPC in `server/src/bridge/`. The settings schema should be extensible (key-value with typed columns, not a single JSON blob) so future settings don't require migrations.
- **#651 Friendly/RoutineDeviation tells — iterate post-ship:** Spike 2 showed these two tells produce output indistinguishable from neutral on Gemma 2B. Three options: stronger few-shot examples in the prompt, non-speech-act encoding (body language descriptions rather than dialogue register), or treat as a 2B capacity ceiling and defer to a larger model. Start with stronger examples (lowest cost). If no improvement after 3 prompt iterations, document the ceiling and close. This is a low-priority polish ticket — do not block sprint completion on it.
## Dependency Chain
```
#650 (ContentType::Factual) → #652 (observer integration)
#627 (SQLite settings) → #646 (client: AI toggle, cross-team)
#633 (composable behavior engine) — parallel track, standalone
#655 (remove v0.1 content loading) — parallel track, standalone
#651 (tells iterate) — parallel track, standalone
```
## PR Workflow
When ready to submit, create a PR with `tea` CLI. **All flags are required** to avoid TTY prompts (see CLAUDE.md "Gitea access" section):
```bash
tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(simulation): description" --description "body" --base main --head server
```