From 11db2f4b41283087a4f6ab53610e2cf4ae757296 Mon Sep 17 00:00:00 2001 From: Jeroen Schweitzer Date: Wed, 22 Apr 2026 08:56:21 +0200 Subject: [PATCH] docs(architecture): sprint 37 archetype-trace audit (#878) Tyre's trace of every live consumer of CharacterArchetype across server and client, with the cascade-based rationale for full removal. Captured so future audits don't repeat the same investigation. Co-Authored-By: Claude Opus 4.6 --- docs/architecture/sprint-37-878-audit.md | 110 +++++++++++++++++++++++ 1 file changed, 110 insertions(+) create mode 100644 docs/architecture/sprint-37-878-audit.md diff --git a/docs/architecture/sprint-37-878-audit.md b/docs/architecture/sprint-37-878-audit.md new file mode 100644 index 000000000..d464dd256 --- /dev/null +++ b/docs/architecture/sprint-37-878-audit.md @@ -0,0 +1,110 @@ +# Sprint 37 #878 — CharacterArchetype audit (D-032 obsolete claim) + +**Author:** Tyre (architecture) +**Date:** 2026-04-21 +**Ticket:** #878 — Audit and purge dead smuggler/detective character enum (D-032 obsolete) +**Status:** BLOCKED — load-bearing code found, awaiting lead decision before destructive work. + +## TL;DR + +The ticket's premise — that `CharacterArchetype` (Smuggler/Detective) is dead +code per D-032's "[Obsolete post-D-117]" footnote — is **stale**. The +footnote relied on D-117 (tycoon is the v0.2 bookmark), but `CLAUDE.md` +now declares **"v0.2 target is dropped. No scoping negotiations."** That +revocation is the most recent architectural directive, and it rolls back +the premise that justified marking the enum obsolete. + +Recommendation: **do not delete `CharacterArchetype`**. Instead, update +the decision record to clear the stale obsolete footnote, close the +ticket as "no-op — premise superseded," and (optionally) claim a small +D-record documenting the reversal chain. + +## Audit + +Grep was run against `server/`, `tooling/`, and `tests/`. `CharacterArchetype` +has **five load-bearing consumers** plus content-schema users: + +### 1. IPC protocol surface +- `server/src/bridge/types.rs:51-54` — `StartupMessage.character_archetype: CharacterArchetype`. + Field is serialized into the session handshake. Removing it is a protocol break. +- `server/src/bridge/types.rs:500-518` — enum + `as_monologue_key()` helper + `Default = Detective`. +- Roundtrip tests at lines 1133, 1146, 1157, 1166, 1173, 1184 exercise the field. + +### 2. Observer pipeline (D-057, #422) — real runtime behavior +- `server/src/perception/observer/mod.rs:81,117,138,200` — archetype flows through + `apply_phase2_verb_filter`. +- `server/src/perception/observer/mod.rs:657-760` — `archetype_verb_label()` swaps + container verb labels based on archetype (Smuggler sees `Move`/`Stash`, Detective + sees `Scan`/`Flag`). This is live feature code, not scaffolding. + +### 3. Monologue pool selection (D-032, #587, #595) +- `server/src/simulation/monologue.rs:134-152` — `MonologueState.character: String` is + initialized from `CharacterArchetype.as_monologue_key()` at session start. + Pool partition is by string key, but the string is *derived* from the enum. + +### 4. Gauntlet test-world plumbing +- `server/src/test_world/mod.rs:98` — `pub fn setup_gauntlet(app: &mut App, archetype: CharacterArchetype)`. +- 5 internal callsites (lines 702, 725, 742, 761, 778) plus the external + `archetype_monologue.rs` integration suite. + +### 5. Regression test suite +- `server/tests/archetype_monologue.rs` — entire file is a regression guard + against #587 (archetype→monologue character wiring). Seven tests, four + explicitly assert Smuggler vs Detective behavior. Deleting the enum requires + deleting this guard, which is the thing that catches the bug it was built for. + +### 6. Content schemas (authoring) +- `server/content/schemas/drama_module.schema.yaml:231,233,234,280,558` — + schema enumerates `smuggler | detective | any` for dialogue/monologue + partitioning in drama modules. + +## Decision chain (why the ticket premise is stale) + +``` +D-027 (v0.1 vertical slice = smuggler + detective) + └─ superseded by D-117 (2026-03-05: tycoon is the v0.2 bookmark) + └─ superseded by "v0.2 target is dropped" (CLAUDE.md, current) +``` + +The obsolete footnote in D-035 line 83 and the `[SUPERSEDED]` header on +D-032 both point at D-117 as the supersession. With v0.2 dropped, we are +back to the v0.1 smuggler/detective frame as the implemented base until +the 6-phase cascade reaches Phase 4 (Player control) — and even then, +the cascade describes a 2-floor test map + character rendering, not a +wholesale character-model replacement. + +## Proposed alternative scope for #878 + +Three options, cheapest first: + +### A. Close as no-op + documentation cleanup (recommended) +- Strip the `[Obsolete post-D-117]` footnote from `decisions/content.md:83` + (D-035 tag taxonomy). +- Remove the `[SUPERSEDED]` marker from `decisions/content.md:47` (D-032 + header) or add a "supersession reversed" note. +- Optionally claim a new D-record in `decisions/scope.md` documenting + that the v0.2-dropped directive implicitly reverses D-117's character + frame revocation. +- Zero code changes. Build stays green. 30 minutes. + +### B. Narrow the ticket to the authoring-side leftovers +- If there are *authoring* artifacts (half-written tycoon monologue + partitioning, stale schema fields) that were added in anticipation of + D-117 and never used, those can be purged. But a quick scan of + `drama_module.schema.yaml` shows the schema is consistent with v0.1 usage. +- Requires a content team review — server-team scope alone cannot + confirm what is live in authoring. + +### C. Rename without removing (if lead wants distance from v0.1 framing) +- Rename `CharacterArchetype` → `PlayerCharacterRole` (or similar) and + its variants to preserve behavior while shedding the "smuggler/detective + investigation framing" language. Higher risk, touches ~45 files, and + doesn't actually change runtime. **Not recommended** unless the lead + specifically wants the naming to match post-cascade vocabulary. + +## Recommendation + +Go with **Option A**. The enum is architecturally sound, the ticket is +a casualty of the v0.2→cascade pivot, and the cleanup is documentation- +only. I have completed #877 cleanly; I'll park #878 in_progress pending +the lead's call on A/B/C.