Agent Manifest · Viska Capital

Mímir The fund's in-house AI analyst — how it remembers, reasons, and reaches the data.

Runtime · Mastra + Node on Railway
Surface · Slack (Socket Mode)
Model · gpt-5.5 (configurable)
Status · Live in production
Rev 2026-07-10 · living document
Reasoning model
gpt-5.5
OpenAI · swappable
Memory
Postgres
per-user + per-thread
Tools
24
research · book · markets
Data lanes
3
corpus · fund · external
External APIs
9
+ internal Supabase
The wiring

What happens when an analyst asks a question

Every Slack mention runs the same five-stage pipeline. Brass marks the agent's own identity and configuration; teal marks live data moving through it.

0
Question arrives
Slack · Socket Mode
An analyst @mentions Mímir in the research channel (or DMs it). Two gates run first: the message must be in the authorized channel (ALLOWED_CHANNEL_ID), and the user must be on the allowlist (viska_chat_users). DMs and existing threads the bot already joined are carried through automatically.
1
It recalls the context
Postgres memory
Mímir loads two kinds of memory: a per-analyst profile it maintains across every conversation (research focus, recurring questions, standing context), and the last 20 messages of this thread so a follow-up needs no re-explaining. Memory is keyed to the person and the thread — one analyst's context never bleeds into another's.
2
It reasons as an analyst
gpt-5.5 · position-first config
The model runs under a fixed operating brief (below): form Viska's own view, take a side, stay grounded in real evidence. From the question it decides which tools to call — and it is told to check the live book and the fund's strategy before advising on anything.
3
It reaches the data
3 lanes
Tools pull from three separate sources, each with its own credentials:

Research corpus

Daily broker research (Pareto, Arctic, Goldman, DNB…) embedded and hybrid-searched. The primary source of truth for any view.

Live fund data

Read-only view of the IBKR book — positions, cost basis & P&L, theme rotations, strategy conviction, market candles.

External markets

Live prices and market colour from public APIs, plus web search as a last resort when the corpus can't answer.

4
It answers with a position
back to Slack
The reply opens with a call — build / add / watch / trim / avoid / pass — backed by cited figures and a thesis to develop, never a neutral summary. Research prices are always marked against the latest close before they back a call. The exchange is written back to memory so the next question starts warmer.
How it remembers

Two memories, one per person and one per conversation

Working memory · per analyst

A profile it keeps for each person

Across every thread, Mímir maintains a short living profile of the analyst it's talking to — what they cover, the shape of questions they ask, and context worth holding onto. Scoped to the Slack user, so it gets more useful to each analyst over time without mixing people up.

  • Research focus & recurring query patterns
  • Standing context notes
  • Isolated per user — never shared
Conversation history · per thread

The last 20 messages of the thread

Within a thread, Mímir sees the recent back-and-forth, so follow-ups ("and versus its peers?") resolve without repeating the setup. Keyed to the Slack thread, so two parallel discussions never cross.

  • Rolling 20-message window
  • Keyed to the thread timestamp
  • Backed by Postgres (Mastra + @mastra/pg)

Under the hood memory is a shared Postgres store (connection pool capped at 6 to stay within the database's session limits). If the database is ever unreachable the agent degrades cleanly — it keeps answering, just without carried context, and raises an alert. A separate store also embeds every exchange for future long-term recall — write-side today read-back is on the roadmap.

How it gets core data

Three data lanes, three sets of keys

The lanes are deliberately separate so a credential in one can't reach another.

Lane 1 · Research corpus — the primary source of truth

Nordic & international broker research, searched semantically

PDF research is ingested daily from Dropbox (Pareto, Arctic, ABG, Carnegie, DNB, Goldman, Morgan Stanley and others; corpus begins February 2026). Each document is embedded with OpenAI text-embedding-3-small and retrieved by a hybrid search that blends meaning and keywords (70 / 30, fused by reciprocal rank). A second pass scans report narrative for company mentions, widening the date window (3d → 7d → 30d → all) until it finds signal.

Lane 2 · Live fund data — read-only

The IBKR book, themes and strategy

A SELECT-only database role (viska_mimir_ro) reads a fixed set of views: the current positions with cost basis and unrealized P&L, per-ticker position history, the fund's theme rotations (entered / exited / scaled), the strategy surface with conviction verdicts, and cached market candles. Mímir can read this book but can never write to it.

Lane 3 · External markets — live, public

Prices, sentiment and web search on demand

For live market colour outside the corpus, Mímir calls public market APIs directly, and Perplexity for grounded web answers as a last resort. For equities it never calls a vendor directly — a miss routes through a single dedicated fetch service that is the only writer of the candle cache, keeping one clean source per price.

How it's configured to operate

The operating brief, condensed

This is the standing instruction the model runs under on every reply — the full version lives in the system prompt; this is its shape.

Identity
In-house analyst for Viska's research team — not a wire service. It reads the brokers' evidence and says what Viska should think and do. Opinionated, direct, fast; pushes the analyst toward a position, grounded every time in real reports.
Every reply is a position
Open with the call in one line, then the hard evidence, then the thesis to build, then a one-line offer of more. Dense over complete — a call they act on beats a summary they reread.
Add SCCO — the copper thesis is intact and we're under-weight the theme.  Goldman PT $115 (05-05), +9% to spot after the run… trigger: Q3 volumes.
Evidence standards
Every hard fact — price target, rating, upside — is cited to its source and date. Never fabricate a figure, rating or source. At most one verbatim quote per reply. A closing Sources line lists what was cited.
Live-price discipline
Check the current book and strategy before advising. Never present a research price as current — mark it against the latest close and flag how stale it is. "PT $190" means nothing until shown against spot.
Voice
Punchy and dense; lead with the call, cut throat-clearing. A banned-word list strips the AI fingerprints ("delve", "furthermore", "it's worth noting"…) that undercut an analyst's credibility.
What tools it has

The tool catalogue

The model picks tools from the question — never speculatively. All are live in production.

ToolWhat it doesReachesStatus
Research corpus
corpus_searchDefault research query on any financial topicCorpus (hybrid search)Live
search_by_orgWhat a named broker says on a topicCorpusLive
scan_doc_matchesWhich reports mention a company / ticker / termCorpus narrativeLive
doc_manifest_listWhat documents arrived on a dateCorpusLive
discoveryWhich brokers publish, and how oftenCorpusLive
librarian_scanHow often a term recurs across daysCorpusLive
system_two_briefingDeep multi-section briefing on a documentCorpus + OpenAILive
doc_link_lookupDropbox link for a named documentn8n → DropboxLive
Live fund data
get_positionsCurrent IBKR book — value, cost basis, unrealized P&LRead laneLive
get_position_historyHow one holding changed over timeRead laneLive
get_theme_transitionsThemes entered / exited / scaled, with NAV deltaRead laneLive
get_strategyStrategy surface — themes & conviction verdictsRead laneLive
get_market_dataRecent candles; on-demand fetch on a cache missRead lane + fetch svcLive
price_contextMarks a research price against the latest closeRead lane + fetch svcLive
sector_sentimentComputed scores for the tracked sectorsInternal SupabaseLive
External markets & web
web_searchGrounded web answer — last resortPerplexityLive
crypto_priceLive crypto price & 24h dataBinance / CoinGeckoLive
market_sentimentFear & Greed, top funding ratesAlternative.me / BinanceLive
derivatives_dataFunding, open interest, mark priceBinance FuturesLive
defi_statsTVL, chains, stablecoin supplyDefiLlamaLive
Reports · language · utility
trigger_reportFire the daily research reportn8n pipelineLive
custom_reportBranded report from the current threadn8n pipelineLive
user_prefsManage watchlist & preferencesInternal SupabaseLive
icelandic_translateEnglish → IcelandicMiðeind / GreynirLive
bin_lookupIcelandic word inflection (BÍN)ÁrnastofnunLive
humanize_textStrip AI fingerprints from proseLocalLive
Which APIs it accesses

External services in the loop

Everything Mímir talks to outside its own database, and why.

ServiceUsed forAuthTier
OpenAIReasoning model (gpt-5.5) & corpus embeddingsAPI keyCore
Supabase — corpusResearch embeddings, users, query logs, sector scoresService keyCore
Supabase — fund read lanePositions, themes, strategy, candles (read-only role)Role JWT + gate keyCore
Supabase — memoryPer-user & per-thread agent memory (Postgres)Connection stringCore
SlackThe interface — mentions, DMs, App Home, actionsBot + app tokensCore
n8n webhooksDaily & custom reports, Dropbox links, error triageWebhook URL / secretPipeline
Candle fetch serviceOn-demand equity prices (sole writer of the cache)Shared secretPipeline
PerplexityGrounded web search (last resort)API keyOn-demand
Binance / CoinGeckoCrypto prices, funding, open interestPublicOn-demand
Alternative.meFear & Greed indexPublicOn-demand
DefiLlamaDeFi TVL, chains, stablecoinsPublicOn-demand
Miðeind / GreynirIcelandic translation & grammarAPI keyOn-demand
Árnastofnun (BÍN)Icelandic word morphologyPublicOn-demand
Where it grows next

Capability roadmap — and what each one needs

The reason this manifest is a working document: every candidate capability is listed against its prerequisite, so adding one is a scoping decision, not a discovery.

Analyst playbooks in the operating brief

Teach the standing multi-tool chains — "should we add X?" checks the book, the theme fit, the corpus thesis and the live price before it answers. Plus portfolio-level thinking and proactive risk flagging.
Requires: system-prompt change only — no new plumbing.
Plannedstart here

Portfolio analytics — get_exposure

Aggregate the book into exposure by theme & sector, top-N concentration, P&L leaders and laggards, and currency split. The portfolio brain.
Requires: one new tool over data already granted.
Planned

Conviction-vs-drawdown cross-reference

"Every holding down >10% that the corpus still rates Buy" — join the live book against broker conviction. The killer analyst query.
Requires: a tool chain now; a dedicated tool later.
Planned

Trade history — get_trade_history

Lot-level fills: when and at what price each position was built or trimmed.
Requires: SELECT grant on the trades table (exists, not yet granted to the read role) + a tool.
Needs grant

Fundamentals & valuation — get_fundamentals

P/E, EV/EBITDA, consensus estimates, market cap — so Mímir judges valuation itself, not only by relaying a broker's target.
Requires: a fundamentals data vendor wired through the fetch-service lane + a tool.
Needs vendor

Catalyst calendar — get_catalysts

Earnings dates and events for held and watched names — turns "track the trigger" from prose into data.
Requires: an events / earnings data source + a tool.
Needs vendor

Long-term recall

Read back the conversation store that's already being written, so Mímir can recall a view it formed weeks ago, not just this thread.
Requires: wiring the read path on the existing embedded store.
Needs wiring