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 <noreply@anthropic.com>
This commit is contained in:
@@ -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.
|
||||
Reference in New Issue
Block a user