Skip to content

refactor(persona): single source of truth — derive registry from card (P3) - #32

Merged
telagod merged 2 commits into
mainfrom
refactor/persona-single-source
May 30, 2026
Merged

refactor(persona): single source of truth — derive registry from card (P3)#32
telagod merged 2 commits into
mainfrom
refactor/persona-single-source

Conversation

@telagod

@telagod telagod commented May 30, 2026

Copy link
Copy Markdown
Owner

What

Implements P3 of docs/persona-architecture-v2.md — the last structural debt in the persona system: single source of truth for persona identity fields.

Before

self / user / language / label / description lived in two places:

  • config/personas/index.json (hand-maintained)
  • config/personas/<slug>/persona-card.json voice / display_name / description

Drift risk: edit one, forget the other.

After

  • index.json is now just an enable-list + default selector ({ slug, default? }).
  • loadPersonaRegistry derives label/description/self/user/language at runtime from each persona-card.json via a new loadPersonaCard helper.
  • The card is the only authoritative source for these fields.

Chose runtime derivation over build-time generation — no generated artifact, no second copy of the data, nothing to keep in sync.

Guards (new tests)

  • index.json must NOT contain voice/label/description fields (prevents re-introducing the dual source).
  • Derived registry values must match the corresponding persona-card.json exactly.

Verification

  • Pre-change audit: index.json ↔ card were already fully consistent → zero-risk derivation.
  • loadPersonaRegistry is the sole consumer of index.json (no other readers).
  • npm test: 380 passed (+3). npm run verify:skills: 25 skills. Rendering: voice macros inject correctly, zero leak.

Remaining

P6 (lorebook-style on-demand 秘典 injection) — separate, addresses context-bloat issues #16/#13.

telagod added 2 commits May 30, 2026 21:15
…ona-card (P3)

index.json identity fields (self/user/language/label/description) were duplicated
in both index.json and each persona-card.json. This removes the dual source:

- index.json is now just an enable-list + default selector ({slug, default?}).
- loadPersonaRegistry derives label/description/self/user/language at runtime from
  each persona-card.json via new loadPersonaCard helper — the card is the sole
  authoritative source.
- Chose runtime derivation over build-time generation: no generated artifact, no
  second copy to keep in sync.

Guards: two new tests — index.json must not carry voice/label/description fields,
and derived values must match the card exactly.

Pre-change audit confirmed index.json and cards were already fully consistent
(zero-risk derivation). npm test 380 passed (+3); verify:skills 25.
…display_name

P3 made label derive from persona-card.json display_name; this stale assertion
still expected the short '古怪精灵小师妹' instead of the full
'古怪精灵小师妹 · 灵犀洞天'. Fixes the CI failure on PR #32.

npm test 379 passed; verify:skills 25.
@telagod
telagod merged commit 2927636 into main May 30, 2026
15 checks passed
@telagod
telagod deleted the refactor/persona-single-source branch May 30, 2026 13:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant