Files
settled-reach/docs/sprints/sprint-17/server.md
T
jpmschweitzerandClaude Opus 4.6 0f1b951691 docs(docs): update Sprint 17 briefings with workshop results
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>
2026-02-24 02:12:00 +01:00

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 PersonOfInterestAnomalyMarker 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