Feature/grand strategy dlc#1
Merged
Merged
Conversation
…, and turn management systems, schemas, and repositories.
…vent handling - Added schemas for secrets, reveal conditions, and game events using Zod for validation. - Developed SecretTools for creating, retrieving, updating, deleting, and revealing secrets. - Implemented a repository pattern for managing secrets in a SQLite database. - Introduced functionality to check reveal conditions based on game events. - Added leak detection to prevent accidental disclosure of secrets. - Enhanced context formatting for LLM integration to ensure DM confidentiality.
Introduces structure placement validation against terrain, preventing cities, towns, and villages from being placed in water or on glaciers. Adds new tools for finding and suggesting valid POI locations, and party movement/position tracking. Updates patch application logic to report errors and warnings, and extends party schema and server tool registration for world map positioning.
Mnehmos
added a commit
that referenced
this pull request
Jun 2, 2026
All three were boundary defects that didn't surface in handler-level tests but fired the moment the system met real MCP traffic + a real character with capitalized class name + an emergent combat scene. Each fix is small and locked in with a targeted regression test that would have caught it. ───────────────────────────────────────────────────────────────────────── Bug #1: agent_manage add_journal rejected at the MCP boundary ───────────────────────────────────────────────────────────────────────── The unified inputSchema declared `kind: AgentSliceKindSchema.optional()`, shared between set_slice (slice kinds) and add_journal (journal kinds). Every add_journal call got rejected at the MCP SDK validation layer before the action router could see it, regardless of whether the kind value was valid for the journal subset. Existing tests passed because they call handleAgentManage directly, bypassing the inputSchema validation that the live MCP path enforces. Fix: union the two enums at the boundary. src/server/consolidated/agent-manage.ts kind: z.union([AgentSliceKindSchema, AgentJournalKindSchema]).optional() Per-action SetSliceSchema and AddJournalSchema already enforce the correct subset, so unifying at the boundary just unblocks both paths. +4 regression tests at the inputSchema layer covering: slice kinds accepted, all 5 journal kinds accepted, invalid kinds rejected, journal-kinds-array on get_journal accepted. ───────────────────────────────────────────────────────────────────────── Bug #2: combat_action cast_spell crashed on capitalized class names ───────────────────────────────────────────────────────────────────────── SPELLCASTING_CONFIG is keyed lowercase ('cleric', 'wizard', ...) but several lookup sites in spell-validator.ts did NOT normalize case or null-check the result. Characters created with class: "Cleric" (capitalized) caused the indexed lookup to return undefined; downstream code accessed `config.canCast` blindly and threw "Cannot read properties of undefined (reading 'canCast')" Six lookup sites were affected: - getMaxSpellLevel - getInitialSpellSlots - calculateSpellSaveDC - calculateSpellAttackBonus - hasSpellSlotAvailable - consumeSpellSlot Fix: introduce a `lookupSpellConfig()` helper that lowercases the class name and null-handles unknown classes (homebrew classes, monster stat blocks). Replace all six unsafe lookups. The existing rest-manage.ts path was already safe via getSpellcastingConfig() so no changes there. +22 regression tests at tests/engine/magic/spell-validator.test.ts: - 6 functions × 3 casings (cleric / Cleric / CLERIC) all return identical, correct results - calculateSpellSaveDC returns 0 for non-spellcaster custom classes - calculateSpellSaveDC returns 0 for empty class string - hasSpellSlotAvailable reports unknown class with a clear reason ───────────────────────────────────────────────────────────────────────── Bug #3: combat_manage create rejected terrain when sent as JSON string ───────────────────────────────────────────────────────────────────────── TerrainSchema was z.object().optional(). Some MCP hosts/transports serialize nested object parameters as JSON strings before validation, causing "Expected object, received string" rejection at the action router layer even when the caller passed a literal object. Fix: wrap TerrainSchema with z.preprocess so it accepts either a literal object OR a JSON-stringified object (parses string before inner validation). The participants array doesn't have this issue (arrays serialize differently through MCP) so we only need to harden the terrain field. +3 regression tests at combat-manage.test.ts: - terrain as object literal works - terrain as JSON-stringified object works (the playtest failure mode) - terrain omitted entirely works ───────────────────────────────────────────────────────────────────────── Verification ───────────────────────────────────────────────────────────────────────── TypeScript build: clean (tsc with no errors). Full suite: 2182 passing, 0 failing, 7 skipped (was 2153 → 2182, +29 tests). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mnehmos
added a commit
that referenced
this pull request
Jun 2, 2026
The maker's first act. Per SPEC.md §8, the ceremony IS the commit and the liturgy IS the changelog. This commit binds the operating charter and the canon corpus into the repository as the foundation of biography #1. Adds: - SYSTEM.md — operating charter for the LLM that adjudicates intents. Two tiers / two gates / OODA loop / nine Standing Rules. Rule 5 is the fog-respect rule ("Never leak one agent's private state into another agent's context"). - docs/bastion/SPEC.md — the 11-section architectural specification: petition/adjudication model (§1), two-layer physics + DLC = summoning (§2.4), time model (§3), adversary model (§4), production model (§5), the four-character roster (§6), power tiers (§7), myth-as-UI (§8), monetization/IP boundaries (§9), §10 build targets, §11 open questions. - docs/bastion/00-campaign-bible.md — 90K-word unified Sebastopyr canon (Atlas, Pantheon, Factions, Timeline, Bestiary, City Districts, NPC Roster, Plot Threads, Daily Life, Player Brief) plus synthesis notes reconciling cross-layer contradictions. - docs/bastion/01-sebastopyr-etymology.md — the city-name note: sebast- (the venerable one who endured the arrows) + -pyr (ward-stone / watchfire in a curtain wall). Both senses intended. - docs/bastion/02-engine-integration-spec.md — integration roadmap mapping §10 build targets onto the current rpg-mcp tool surface and the just-shipped Naruto-5e Phase A/B/C generalization. - docs/bastion/rpg-mcp-bootstrap.json — 38 NPCs, 50 factions, 44 locations, 12 plot threads, 15 bestiary, 11 timeline events, 29 pantheon, plus bargain_ledger seed (Long Ledger / Octave Bargain / Halidan-Quartermaster account / Mother Aspine count / Asperine Vesselain clandestine) and stain backfill on Cathedral + Inquisition NPCs. Force-added past .gitignore's overly-broad rpg-mcp-* rule. - scripts/seed-bastion.ts — type-clean seeder bridging the canon archive to consolidated-tool calls: slug→uuid map, faction-name resolution, tier→stats template for bestiary, urgency-bucket for plot_threads, rpg_mcp_seeds flatten. Not yet executed against live DB. Per SPEC §8: the first build and the first scene are the same act. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Mnehmos
added a commit
that referenced
this pull request
Jun 2, 2026
… — the first Layer-1 install The first build per SPEC §10 closing: a structured query against committed state that returns the load-bearing constraint of a situation, with the Hierarchy of Controls as the ranking primitive. This is the closest subsystem to what rpg-mcp already does (it IS a typed query over committed state); it validates the full Layer-1 → Layer-2 pipeline on the Operator (the maker's avatar-as-conscript); and per §8 it ships the doctrine that ceremony IS commit — every Maker-standing commit is also a chapter in Biography #1. What lands here: - SubsystemDef (data/subsystems/operator-constraint-perception.json) — the Layer-1 definition. Three charges of attention per long rest, scaling 3→4→5→6 across levels 1/5/9/13. JSA wind-up: one action, interruptible, prerequisites enforced (not_concentrating, has_attentional_capacity). Seven honest failure modes — BLIND_SPOT, WRONG_LEVEL_CALL, RESOURCE_EXHAUSTION, OBSERVER_NOT_BOUND, CONCENTRATING, ASSESSMENT_INTERRUPTED, INVALID_TARGET. - Engine (src/engine/perception/) — four pieces: - hierarchy-of-controls.ts — five-rank ranking primitive (elimination > substitution > engineering > administrative > PPE), applicability filtering against scene state, doctrine strings preserved. - hazard-detector.ts — typed query over committed state. Reads rooms, encounters, scenes; returns hazards with disposition discipline — 'unknown' when source metadata is missing rather than fabricating. - blind-spot-detector.ts — honest disclosure when the lens is not bound to the target (OBSERVER_NOT_BOUND) or the looking spent its cost and found nothing (no_op_spoken). - attentional-capacity.ts — the §10.3 resource primitive: spend, refill on long_rest, cap by level, never refundable. - Schema (src/schema/perception.ts, src/schema/character.ts) — Zod surfaces: HazardSchema, ApplicableControlSchema, BlindSpotSchema, AssessmentRow. CharacterSchema.resourcePools added as a forward-compat record so the Operator's attentional_capacity coexists with existing spellSlots. - Storage: - migrations.ts — adds characters.resource_pools (TEXT/JSON), subsystem_bindings table (single-row bootstrap binding the Operator to constraint-perception), perception_assessments ledger (INSERT-only, disposition-tagged, intent_id'd, hash-chained). - repos/character.repo.ts — persists resourcePools through create/update/findById round-trip. - repos/perception-assessment.repo.ts — append-only ledger access, observer + target indices. - Tool (src/server/consolidated/perception-manage.ts) — the public surface, wired into consolidated-registry.ts and consolidated/index.ts. Actions: install_subsystem, bind_observer, read_hazard, get_capacity, get_history. read_hazard runs the full JSA pipeline: precondition check, debit cost, query state, rank controls, disclose blind spots, write ledger row, return disposition (commit / reject_inert / no_op_spoken / unknown). - Tests (32 passing): hierarchy ranking, capacity spend/refill, blind-spot honesty discipline, and the full perception_manage tool surface including the unknown-disposition path when source metadata is absent. - CLAUDE.md — tool count bumped to 34 (30 consolidated + 4 meta), Bastion subsystems section added. Per SPEC §8 the chapter and this commit share one intent. The canonical_moment written to Biography #1 (Chapter II — The Teaching of Sight, and the First Looking, in the maker's voice descending into the Inner Chamber) is the in-world face of this commit. The two writes are one act. Biography #1 noteId: 247cbcdd-592c-4763-93ad-53a06ad47f4d Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.