Reconcile sprint planning after Knowledge Flow workshop: - Server briefing: add #545-#551 workshop tickets, correct dependency chain, reference D-079–D-083, remove stale "blocked by workshop" - Joint briefing: mark workshop complete, add completion proofs #9 (contradiction) and #10 (NPC-to-NPC transfer), update teams table - Copy briefing: add #552 contradiction monologue ticket with full Mellanie authoring spec per D-083 and Paula Round 2 output Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7.3 KiB
Sprint 17: Tell — Server Tasks
Goal: NPCs volunteer information unprompted and express personality through delivery; the knowledge graph becomes a live system with grants, propagation, contradiction detection, and NPC information boundaries; POI infrastructure lands; protocol versioning ships.
Branch: server
Agents: Dudley (simulation), Tyre (arch), Hoshe (QA)
Carry-over from Sprint 16
None. Sprint 16 server was 100% complete (4/4 done).
Workshop Output
The Knowledge Flow & NPC Boundaries workshop completed before this sprint. Outcomes at docs/workshops/knowledge-flow-npc-boundaries/workshop-outcomes.md.
Decisions registered: D-079 (Grant Architecture), D-080 (NPC-to-NPC Propagation), D-081 (Unprompted Disclosure), D-082 (NPC Information Boundaries MVP), D-083 (Contradiction Detection Pipeline)
Questions closed: Q-024 (gossip timing — conversation system hook), Q-025 (KG memory — not a concern at current scale), Q-026 (contradiction detection — event-driven at KG write time)
Team lead decision: Entity grants ship in Sprint 17 (compound KnowledgeGrant enum with Entity variant, ContentEntityRegistry at NPC spawn).
Tickets
Knowledge Graph Infrastructure (Workshop Tickets)
| # | Title | Priority | Blocked by | Est. lines |
|---|---|---|---|---|
| #545 | KnowledgeGrant schema + ContentEntityRegistry | critical | — | ~120 |
| #546 | KnowledgeGranted event + handler | high | #545 | ~150 |
| #547 | ContradictionClaim struct + detection in observe_entity | high | #545 | ~160 + tests |
| #548 | NPC-to-NPC knowledge transfer system | high | #545, #546 | ~160 |
| #549 | tell_state.rs KG awareness — MVP boundary (#142) | high | #545 | ~35 |
| #550 | Contradiction monologue + event chain | high | #545, #546, #547, #548, #552 | ~90 |
| #551 | DisclosureCandidates + unprompted disclosure | high | #545, #546, #548 | ~220 |
Stories (Acceptance Gates)
| # | Title | Priority | Blocked by |
|---|---|---|---|
| #141 | Knowledge-based information gating | high | #546 |
| #142 | NPC information boundaries | high | #546, #548, #549 |
| #172 | Layer 4: Unprompted disclosure | high | #551 |
| #173 | Trait modifier system | high | — |
Standalone
| # | Title | Priority | Blocked by |
|---|---|---|---|
| #148 | POI data model | high | — |
| #149 | POI discovery system | high | #148 |
| #232 | Create protocol versioning scheme | high | — |
Use db/connectors/ticket show <id> for full details.
Dependency Chain
#545 (KnowledgeGrant schema) ─ CRITICAL ROOT
├─→ #546 (event + handler)
│ ├─→ #548 (NPC-to-NPC transfer)
│ │ ├─→ #551 (disclosure) → #172 (story gate)
│ │ ├─→ #550 (contradiction monologue) ← also needs #547, #552
│ │ └─→ #142 (story gate)
│ └─→ #141 (story gate)
├─→ #547 (ContradictionClaim) → #550
├─→ #549 (tell_state KG) → #142 (story gate)
│
Parallel tracks (no KG deps):
#148 → #149 (POI)
#173 (trait modifiers)
#232 (protocol versioning)
Critical path: #545 → #546 → #548 → #551 → #172 Parallel from day 1: #547 (with #545), #549 (after #545), #148, #173, #232
Key Decisions
decisions/perception.md— D-079 (grant architecture), D-080 (NPC-to-NPC propagation), D-081 (unprompted disclosure), D-082 (NPC boundaries MVP), D-083 (contradiction detection)decisions/content.md— D-028 (dialogue architecture, four relational layers), D-024 (NPC 10 axes), D-035 (tag taxonomy)decisions/architecture.md— D-041 (knowledge graph data model), D-010 (information boundaries), D-020 (engine architecture)decisions/perception.md— D-033 (entity color from relationship)
Implementation Notes
#545 — KnowledgeGrant schema + ContentEntityRegistry
D-079. Compound KnowledgeGrant enum with Fact and Entity variants via #[serde(untagged)]. ContentEntityRegistry resource (BTreeMap<String, StableId>) populated at NPC spawn time. ~0.5 day infrastructure. This is the critical root — everything else depends on it.
#546 — KnowledgeGranted event + handler
D-079. New KnowledgeEventType::KnowledgeGranted variant. Fires at line selection time in server/src/simulation/dialogue.rs. Wires the knowledge_grant field on IndexedDialogueLine (server/src/content/line_pool.rs line 297) — currently Option<KnowledgeGrant>, always None.
#547 — ContradictionClaim struct + detection
D-083. Add contradicted_claim: Option<ContradictionClaim> to EntityKnowledge. Detection fires in observe_entity() when: existing entry has source: ToldBy, position differs, and |current_tick - told_tick| < CONTRADICTION_WINDOW_TICKS (600 ticks). Parallel with #546.
#548 — NPC-to-NPC knowledge transfer
D-080. Separate transfer_npc_knowledge system (ECS borrow constraint — can't hold two mutable KGs in same system). Runs after run_npc_conversations. Trust-gated: Surface 0-1, Real 1-2, Secret 2-3 facts. Confidence capped at KnowsOf. Constructs ToldBy source.
#549 — tell_state.rs KG awareness
D-082. MVP information boundary. Add Option<&KnowledgeGraph> to tell_state query. NPC relationship reads come from KG (other-entity knowledge), self-knowledge stays on axes (always ground truth). ~35 lines, standalone after #545.
#550 — Contradiction monologue + event chain
D-083. ContradictionDetected event → monologue system triggers source-named line → relationship shifts to PersonOfInterest → AnomalyMarker set → D-033 amber color. Pre-resolve source_display_name into event payload. Depends on #552 (copy team authors the lines).
#551 — DisclosureCandidates + unprompted disclosure
D-081. DisclosureCandidates component (separate from DerivedTellState). Trigger gates: trust >= Surface, mood != Hostile, contentment >= -10, witness inhibition, location privacy. Three rate-limit layers: per-fact history, per-NPC 300-tick cooldown, global 1/10-tick StableId-ordered cap. Trait-based two-stage filter (what + how).
#172 — Layer 4: Unprompted disclosure (story)
Acceptance gate for #551. Verify: NPC with high trust and relevant knowledge volunteers information unprompted. Player's KG gains a new fact via knowledge_grant.
#173 — Trait modifier system
D-081 two-stage design. Stage 1: traits filter WHAT is disclosed (Cautious → KnowsDetails minimum, Gossipy → Suspects minimum). Stage 2: traits modify HOW (delivery mood, line selection weight). Composes with Layer 3 (trust-gated) and Layer 4 (#551).
#148 / #149 — POI data model + discovery
POIs enter KG as FactId("poi.*") namespace per D-079. PointOfInterest component with name, location, category, discovery source, visibility rules. Discovery via KnowledgeEventType::KnowledgeGranted with Fact variant.
#232 — Protocol versioning
Standalone infrastructure. Version field in protocol messages, compatibility checking, migration strategy. No gameplay change.
PR Workflow
When ready to submit, create a PR with tea CLI:
tea pr create --repo jpmschweitzer/settled-reach --login schweitz --title "feat(server): sprint 17 description" --description "body" --base main --head server