Vitruvyan Docs
Codex Prompt — Babel Gardens Finance Vertical Implementation
Last updated: Feb 23, 2026 16:00 UTC Target: ChatGPT 5.3 Codex (autonomous execution) Workspace:
/home/caravaggio/mercatorBranch:main
MISSION
Implement the finance vertical for the Babel Gardens Sacred Order. This is the template approach — the pattern established here will be replicated for all subsequent Sacred Orders (Pattern Weavers, Codex Hunters, Vault Keepers, Orthodoxy Wardens, Memory Orders).
The work consists of 4 deliverables:
- Finance Babel plugin package (
vitruvyan_core/domains/finance/babel_gardens/) - Service plugin loader in
services/api_babel_gardens/to load finance vertical via config - Updated API routes to expose finance-specific endpoints conditionally
- Unit tests + validation
ARCHITECTURAL CONSTRAINTS (NON-NEGOTIABLE)
- LIVELLO 1 stays agnostic —
vitruvyan_core/core/cognitive/babel_gardens/is FROZEN. Do NOT modify any file there. - Finance enters via plugins/config only — through
vitruvyan_core/domains/finance/babel_gardens/andservices/api_babel_gardens/plugins/. - Vertical Contract V1 — all artifacts must conform to
docs/contracts/verticals/VERTICAL_CONTRACT_V1.md. - LLM-first (Nuclear Option) — sentiment/emotion analysis uses LLM as primary engine. FinBERT is a domain signal extractor (additional finance-specific signals), NOT a replacement for LLM sentiment.
- No cross-service imports — finance plugins communicate with Sacred Orders via config injection, NOT by importing service internals.
- Agents for all I/O —
PostgresAgentfor DB,QdrantAgentfor vectors,LLMAgentfor LLM calls. No raw clients. - Environment-driven activation — finance features activate when
BABEL_DOMAIN=finance(default:generic).
CURRENT STATE (What Already Exists)
LIVELLO 1 — Pure Domain (FROZEN, do NOT modify)
Location: vitruvyan_core/core/cognitive/babel_gardens/
Key exports (from __init__.py):
BabelConfig,get_config,set_config,load_config_from_yamlTopicConfig,TopicCategoryEmbeddingResult,SentimentResult,EmotionResult,ProcessingStatusSynthesisConsumer,TopicClassifierConsumer,LanguageDetectorConsumer,ProcessResultChannels,EventEnvelopeMetricNames,HealthCheckNames
Key domain primitives:
domain/signal_schema.py:SignalSchema,SignalExtractionResult,SignalConfig,load_config_from_yaml(),merge_configs()domain/entities.py: Frozen dataclasses —EmbeddingVector,EmbeddingResult,SentimentResult,EmotionResult,SynthesisRequest,SynthesisResultdomain/config.py:BabelConfig(master config),TopicConfig(YAML-loaded taxonomy),EmbeddingModelConfig,SentimentModelConfig, etc.consumers/synthesis.py:SynthesisConsumer— 4 fusion methods: concatenation, weighted_average, attention_fusion, semantic_garden_fusionconsumers/classifiers.py:TopicClassifierConsumer,LanguageDetectorConsumerevents/__init__.py:Channels(11 stream channel constants),EventEnvelopeexamples/signals_finance.yaml: 3 signals (sentiment_valence, market_fear_index, volatility_perception), taxonomy with 6 categories
LIVELLO 2 — Service Layer
Location: services/api_babel_gardens/
Structure:
Existing Finance Plugin
services/api_babel_gardens/plugins/finance_signals.py (320 lines) — ALREADY EXISTS:
FinanceSignalsPluginclass with lazy FinBERT loading (ProsusAI/finbert)extract_sentiment_valence(text, schema) → SignalExtractionResult(maps P(positive) - P(negative) to [-1, 1])extract_market_fear_index(text, schema) → SignalExtractionResult(P(negative) + 0.5 * P(neutral))extract_signals(text, config) → List[SignalExtractionResult](batch extraction)- Missing:
extract_volatility_perception(3rd signal in YAML) - Missing: Multi-model fusion (only has FinBERT, no gemma/multilingual integration)
- Missing: Sector resolution
Existing Finance Domain
vitruvyan_core/domains/finance/ — files present:
__init__.py(exports ResponseFormatter + SlotFiller)intent_config.py(274L, 9 intents + 7 filters)graph_plugin.py(742L, FinanceGraphPlugin)slot_filler.py(352L, 5 slots, 4 languages)response_formatter.py(520L, verdict/gauge/matrix)governance_rules.py(90L, 16 MiFID/FINRA rules)prompts/(368L, 3 languages, 6 scenarios)execution_config.py(STUB)entity_resolver_config.py(STUB)- No
babel_gardens/subdirectory yet
Pydantic Schemas (in schemas/api_models.py)
Finance fingerprint in current schemas:
ModelType.FINANCIAL— default model type for embeddingsUserPreferences.risk_tolerance— finance-origin fieldFusionModeenum (BASIC, ENHANCED, DEEP)- No ticker-specific models
UPSTREAM CODE TO PORT (Reference from vitruvyan)
1. Multi-Model Sentiment Fusion (sentiment_fusion.py, 758 lines)
The upstream vitruvyan has a SentimentFusionModule with multi-model weighted fusion:
- Fusion weights:
{"gemma": 0.45, "finbert": 0.35, "multilingual": 0.20} - 3 fusion modes: BASIC (simple weighted), ENHANCED (language + domain boosting), DEEP (consensus analysis)
- Language-aware boosting: multilingual model × 1.3 for non-English, FinBERT × 1.2 for financial text
- Cache-first pattern with Redis
- Batch processing with semaphore (8 concurrent)
- Calibration with online learning of weights from feedback
- 3 model predictions:
_get_gemma_prediction(),_get_finbert_prediction(),_get_multilingual_prediction()
What to port: The multi-model fusion logic, enhanced/deep fusion with language boosting, calibration. What NOT to port: The raw model inference (mercator uses LLM-first for general sentiment; FinBERT is additional finance signal only).
2. Sector Resolver (sector_resolver.py, 238 lines)
Multilingual GICS sector resolution from sector_mappings PostgreSQL table:
resolve_sector(query_text, language) → {"db_sector", "gics_sector", "pattern_weaver_concept", "matched_alias", "matched_language", "confidence"}- JSONB query against
multilingual_aliasescolumn - CJK bigram tokenization for Chinese/Japanese/Korean
- Stopword filtering for 4 languages
get_all_sectors_multilingual(language) → List[Dict]
3. Model Manager Finance Config
FinBERT model configuration in upstream model_manager.py:
Already exists in mercator's shared/model_manager.py.
4. Financial Embedding Method
Upstream embedding_engine.py has create_financial_embedding() — uses cooperative API first, falls back to local. Model selection: ModelType.FINANCIAL → "gemma_embeddings".
Already exists in mercator's modules/embedding_engine.py.
IMPLEMENTATION PLAN
DELIVERABLE 1: Finance Babel Plugin Package
Create vitruvyan_core/domains/finance/babel_gardens/ with this structure:
File: __init__.py
File: sentiment_config.py
File: financial_context.py
File: sector_resolver.py
File: volatility_lexicon.py
File: signals_finance.yaml
Copy from vitruvyan_core/core/cognitive/babel_gardens/examples/signals_finance.yaml — this becomes the canonical config location for the finance vertical:
File: README.md
Update extract_signals() to dispatch volatility_perception:
DELIVERABLE 3: Service Plugin Loader
Create services/api_babel_gardens/adapters/finance_adapter.py:
Add services/api_babel_gardens/api/routes_finance.py:
Modify services/api_babel_gardens/main.py to conditionally register finance routes:
After the existing router includes, add:
DELIVERABLE 4: Unit Tests
Create vitruvyan_core/domains/finance/babel_gardens/tests/ directory with:
test_sentiment_config.py
test_financial_context.py
test_volatility_lexicon.py
test_sector_resolver.py
DELIVERABLE 5: Integration with services/api_babel_gardens/adapters/__init__.py
Modify or create services/api_babel_gardens/adapters/__init__.py to export the finance adapter:
DOCKER CONFIGURATION
Add BABEL_DOMAIN env var to docker-compose for the babel service:
VALIDATION CHECKLIST
After implementation, verify:
-
python -c "from domains.finance.babel_gardens import FinanceSentimentConfig; print('✅')"— imports work -
python -c "from domains.finance.babel_gardens.sector_resolver import SectorResolver; print('✅')"— sector resolver importable -
python -c "from domains.finance.babel_gardens.volatility_lexicon import extract_volatility_perception; print('✅')"— volatility lexicon importable -
python -c "from domains.finance.babel_gardens.financial_context import FinancialContextDetector; print('✅')"— context detector importable -
pytest vitruvyan_core/domains/finance/babel_gardens/tests/ -v— all unit tests pass - LIVELLO 1 not modified:
git diff vitruvyan_core/core/cognitive/babel_gardens/shows no changes - Finance routes:
curl localhost:2009/v1/finance/signals -X POST -H "Content-Type: application/json" -d '{"text": "Fed signals rate hike"}'→ 200 with 3 signals - Sector resolution:
curl localhost:2009/v1/finance/sector/resolve -X POST -H "Content-Type: application/json" -d '{"query": "tecnologia", "language": "it"}'→ Technology - Enhanced sentiment:
curl localhost:2009/v1/finance/sentiment/enhanced -X POST -H "Content-Type: application/json" -d '{"text": "Markets crash on inflation fears"}'→ fused response - Health check:
curl localhost:2009/health→ 200 with finance components - Non-finance mode: Without
BABEL_DOMAIN=finance,/v1/finance/*→ 404
FILE MANIFEST (Complete list of files to create/modify)
CREATE (new files):
vitruvyan_core/domains/finance/babel_gardens/__init__.pyvitruvyan_core/domains/finance/babel_gardens/sentiment_config.pyvitruvyan_core/domains/finance/babel_gardens/sector_resolver.pyvitruvyan_core/domains/finance/babel_gardens/volatility_lexicon.pyvitruvyan_core/domains/finance/babel_gardens/financial_context.pyvitruvyan_core/domains/finance/babel_gardens/signals_finance.yamlvitruvyan_core/domains/finance/babel_gardens/README.mdvitruvyan_core/domains/finance/babel_gardens/tests/__init__.pyvitruvyan_core/domains/finance/babel_gardens/tests/test_sentiment_config.pyvitruvyan_core/domains/finance/babel_gardens/tests/test_financial_context.pyvitruvyan_core/domains/finance/babel_gardens/tests/test_volatility_lexicon.pyvitruvyan_core/domains/finance/babel_gardens/tests/test_sector_resolver.pyservices/api_babel_gardens/adapters/finance_adapter.pyservices/api_babel_gardens/api/routes_finance.py
MODIFY (existing files):
services/api_babel_gardens/plugins/finance_signals.py— addextract_volatility_perception()methodservices/api_babel_gardens/main.py— conditionally register finance routesservices/api_babel_gardens/adapters/__init__.py— export finance adapter
DO NOT MODIFY:
vitruvyan_core/core/cognitive/babel_gardens/*— LIVELLO 1, FROZEN