Skip to content

Game Profile: npc.soul + player.soul graduate into soul_protocol.profiles.game - #277

Merged
prakashUXtech merged 6 commits into
devfrom
feat/game-profile
Jul 24, 2026
Merged

Game Profile: npc.soul + player.soul graduate into soul_protocol.profiles.game#277
prakashUXtech merged 6 commits into
devfrom
feat/game-profile

Conversation

@prakashUXtech

Copy link
Copy Markdown
Contributor

Graduates the grudge-kernel experiment into the first Soul Protocol profile. The npc.soul/player.soul runtime moves from examples/ into a proper package, and the Game Profile RFC is written from the working code.

What's in here

  • The experiment itself (4 commits): GrudgeKernel (an NPC that remembers a specific player's wrongs, per-player bonds, grudge levels, and survives a .soul export→awaken), PlayerSoul (portable reputation a never-met NPC reacts to), the pluggable DialogueEngine seam (templated default, LLM optional, claude-cli backend), CostMeter + ReplayCache (deterministic zero-cost replay).
  • Graduation (39bf685): modules move to src/soul_protocol/profiles/game/ via git-mv (history preserved), tests to tests/profiles/game/, examples keep a thin demo shim. Zero modifications to existing core files — the profile claim is empirical.
  • RFC (6c3b1e0): spec/profiles/game.md — profiles-over-core architecture, both roles, normative conventions (grievance/deed tagging, the PUBLIC-visibility rule for reputation memories and the BONDED recall trap it avoids, user_id scoping, round-trip guarantees), graceful degradation, two promote-to-core candidates.

Review notes

  • Base of a 3-PR stack (brain and demo follow). Per house rules: merge this base with --rebase, not squash.
  • The PUBLIC-visibility convention is load-bearing and documented in §Conventions — BONDED memories vanish from recall once bond_strength < 30, which would hide a grudge exactly when it peaks.

Tests

15/15 in tests/profiles/game/ from the new package location; imports verified; full-suite collection healthy (2947 tests, no import errors).

@github-actions

github-actions Bot commented Jul 2, 2026

Copy link
Copy Markdown

Security scan: review needed

Potentially dangerous code patterns detected in changed files. A maintainer should verify these are intentional and safe.### src/soul_protocol/profiles/game/dialogue.py

439:    proc = await asyncio.create_subprocess_exec(

@github-actions

Copy link
Copy Markdown

This PR has been automatically marked as stale because it has not had activity in the last 14 days. It will be closed in 7 days if no further activity occurs. If you're still working on this, please push an update or leave a comment.

@github-actions github-actions Bot added the stale label Jul 16, 2026
@prakashUXtech prakashUXtech added the pinned Exempt from stale bot auto-close label Jul 21, 2026
…dge across a .soul reload

A thin, deterministic, zero-LLM layer over one real Soul (examples/npc_soul_grudge/).
A player who wrongs the NPC weakens its per-player bond and plants tagged episodic
grievances; those survive a .soul export -> awaken round-trip, so the NPC still
remembers and reacts with hostility in the next session.

- grudge.py: GrudgeKernel wrapping Soul — record/grievances/grudge_level/react.
  Grievances stored PUBLIC (a weakened bond hides BONDED memories), attributed by
  user_id, tagged via entities + an in-content marker (MemoryEntry has no metadata
  field). Per-player bond via BondRegistry.weaken(user_id=...).
- demo.py: headless walkthrough — Bjorn the butcher goes warm -> hostile, exports,
  awakens fresh, still remembers; a second player stays warm (per-player proof).
- test_grudge_kernel.py: 5 pytest-asyncio tests incl. the export->awaken round-trip.

Imports the real Soul; touches no core files.
…ul grudge kernel

Extract the NPC's spoken line behind a DialogueEngine Protocol so the same
grudge can be voiced by a deterministic template (default, free) or a real LLM,
without touching the bond/grievance/persistence logic. Mirrors Soul Protocol's
own Protocol + fallback + optional real backend pattern.

- dialogue.py: DialogueEngine Protocol; TemplatedDialogueEngine (the original
  branches, verbatim, kept as the default); LLMDialogueEngine(generate) which
  builds a strong in-character prompt from persona + OCEAN + grudge level +
  named grievances + player line and falls back to the template on empty output
  or any error; claude_cli_generate, a no-key backend that shells out to
  `claude -p` (works here, no ANTHROPIC_API_KEY, ~10s/call).
- grudge.py: react() delegates to self._dialogue.speak(...); birth()/awaken()
  accept dialogue_engine. OCEAN is read from soul.dna.personality; persona is
  carried on the kernel (Soul.birth does not retain it). Existing signature
  preserved, so the original tests pass unchanged.
- demo.py: adds a LIVE section replaying the Bjorn->Ragnar arc + reload with
  LLMDialogueEngine(claude_cli_generate), tagging any templated fallback. The
  original deterministic section still runs first.
- tests: add a record-don't-mock spy test that drives the real LLMDialogueEngine
  and asserts the prompt the model would receive carries the grievance content
  and grudge level, plus a fallback test. All deterministic (no live LLM, no
  subprocess, no network). 7 passing.
…NPC reacts to across a .soul reload

Both directions of the relationship ledger: a slight now also records the deed on
the player's own player.soul (PUBLIC = readable reputation). A fresh NPC who has
never met the player reads their player.soul and reacts to their notoriety, and it
survives a player.soul export->awaken. 11 tests green; deterministic + a live path.
…el moves from examples to soul_protocol.profiles.game

The npc_soul_grudge experiment (15/15 tests green) becomes the first
Soul Protocol profile: a package of conventions over the unchanged core.

- git mv grudge.py, player.py, dialogue.py, costmeter.py from
  examples/npc_soul_grudge/ to src/soul_protocol/profiles/game/;
  sibling imports converted to package-relative, behavior unchanged
- soul_protocol.profiles.game exports the public API: GrudgeKernel,
  PlayerSoul, the DialogueEngine seam + engines, CostMeter/ReplayCache/
  PRICING, the grudge-level and notoriety constants, plus Grievance and
  Deed (return types of public accessors)
- git mv test_grudge_kernel.py to tests/profiles/game/; sys.path hack
  removed, imports consolidated from the package, 15/15 still pass
- examples/npc_soul_grudge/ stays as a thin consumer: demo.py imports
  from the package; README points at the package and the upcoming spec
- drop a dead severity local in record_deed (pre-existing F841 surfaced
  by src/ lint coverage; deeds() recomputes severity at recall time)

No core files touched — new files and moves only.
…rotocol profile

Written from the graduated reference runtime at
src/soul_protocol/profiles/game/. Covers the profiles-over-core layering
(L0 core unchanged through L3 products), the two roles (GrudgeKernel /
PlayerSoul), the normative conventions (content-marker + entities
tagging, the PUBLIC-visibility rule and the BONDED recall trap it
avoids, per-player user_id + BondRegistry scoping, bond semantics,
export/awaken round-trip guarantees), graceful degradation for generic
.soul readers, the DialogueEngine seam with cost instrumentation, and
two promote-to-core candidates surfaced by building the profile
(a profiles: field in soul.json; first-class MemoryEntry metadata).
@github-actions

Copy link
Copy Markdown

Issues (must fix)

  • PR title does not follow Conventional Commits format (e.g. feat: add recall API, fix(memory): handle empty tiers).
  • No linked issue found. PRs should reference an issue (Fixes #123).
  • No evidence of local testing found. Please include terminal output or screenshots.

Heads up

  • Large PR detected (2617 lines across 12 files). Consider splitting into smaller PRs.

Please update your PR to address these points.

@prakashUXtech
prakashUXtech merged commit 0f322fb into dev Jul 24, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

needs-work pinned Exempt from stale bot auto-close stale

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant