From 1cde1de09054022906de096a4d2d18a41950618b Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 20:22:54 -0300 Subject: [PATCH 01/34] add wallet permission to base role --- docs/authentication.md | 6 +++--- docs/user.md | 6 +++--- main/utils/roles.py | 4 +++- tests/test_roles.py | 15 +++++++++++---- 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/docs/authentication.md b/docs/authentication.md index c19cf2fb..253e1267 100644 --- a/docs/authentication.md +++ b/docs/authentication.md @@ -50,13 +50,13 @@ Parsing: `parseDeviceFields` (`main/app/authentication/session.py:13-27`, stored | Role | Effective permissions | | :--- | :--- | -| `USER` | none (`Permission.NONE`) | -| `PREMIUM` | `USE_ORUNMILA` + `ORUNMILA_EXTENDED_MEMORIES` | +| `USER` | `WALLET` — default on registration | +| `PREMIUM` | `WALLET` + `USE_ORUNMILA` + `ORUNMILA_EXTENDED_MEMORIES` | | `DEVELOPER_STARTER` | = `USER` (no extra permissions) | | `DEVELOPER_ENTERPRISE` | = `DEVELOPER_STARTER` (no extra permissions) | | `ADMIN` | all (`Permission.ALL()`), bypasses checks | -Only two permissions exist: `USE_ORUNMILA`, `ORUNMILA_EXTENDED_MEMORIES`. There are no `VIEW_PROFILE` / `USE_THOTH` / `USE_MAAT` / `USE_OGUM` permissions — delete any such claims. +Only three permissions exist: `USE_ORUNMILA`, `ORUNMILA_EXTENDED_MEMORIES`, `WALLET`. There are no `VIEW_PROFILE` / `USE_THOTH` / `USE_MAAT` / `USE_OGUM` permissions — delete any such claims. ## Rate limits diff --git a/docs/user.md b/docs/user.md index dc8e136d..43689774 100644 --- a/docs/user.md +++ b/docs/user.md @@ -8,13 +8,13 @@ Profile reads, role checks, and session management for the Mansa ecosystem (`USE | Role | Effective permissions | | :--- | :--- | -| `USER` | none (`Permission.NONE`) — default on registration | -| `PREMIUM` | `USE_ORUNMILA` + `ORUNMILA_EXTENDED_MEMORIES` | +| `USER` | `WALLET` — default on registration | +| `PREMIUM` | `WALLET` + `USE_ORUNMILA` + `ORUNMILA_EXTENDED_MEMORIES` | | `DEVELOPER_STARTER` | = `USER` (no extra permissions) | | `DEVELOPER_ENTERPRISE` | = `DEVELOPER_STARTER` (no extra permissions) | | `ADMIN` | all (`Permission.ALL()`), bypasses checks | -Only two permissions exist: `USE_ORUNMILA`, `ORUNMILA_EXTENDED_MEMORIES`. There are no `VIEW_PROFILE` / `USE_THOTH` / `USE_MAAT` / `USE_OGUM` permissions — delete any such claims. There are no role-upgrade endpoints in code; any `upgrade/developer/*` docs are stale. +Only three permissions exist: `USE_ORUNMILA`, `ORUNMILA_EXTENDED_MEMORIES`, `WALLET`. There are no `VIEW_PROFILE` / `USE_THOTH` / `USE_MAAT` / `USE_OGUM` permissions — delete any such claims. There are no role-upgrade endpoints in code; any `upgrade/developer/*` docs are stale. ## API endpoints diff --git a/main/utils/roles.py b/main/utils/roles.py index 5e7b2e82..975933fd 100644 --- a/main/utils/roles.py +++ b/main/utils/roles.py @@ -9,13 +9,15 @@ class Permission(IntFlag): ORUNMILA_EXTENDED_MEMORIES = auto() + WALLET = auto() + @classmethod def ALL(cls): return sum(cls) class Roles(IntFlag): - USER = Permission.NONE + USER = Permission.WALLET PREMIUM = USER | Permission.USE_ORUNMILA | Permission.ORUNMILA_EXTENDED_MEMORIES diff --git a/tests/test_roles.py b/tests/test_roles.py index 56e92898..c645e87e 100644 --- a/tests/test_roles.py +++ b/tests/test_roles.py @@ -8,19 +8,23 @@ def test_permission_enum_values(self): assert Permission.NONE == 0 assert Permission.USE_ORUNMILA > 0 assert Permission.ORUNMILA_EXTENDED_MEMORIES > 0 + assert Permission.WALLET > 0 class TestRoles: - def test_user_has_no_permissions(self): - assert Roles.USER == Permission.NONE + def test_user_has_wallet_only(self): + assert Roles.USER == Permission.WALLET + assert Roles.USER & Permission.WALLET assert not (Roles.USER & Permission.USE_ORUNMILA) def test_premium_has_orunmila_permissions(self): assert Roles.PREMIUM & Permission.USE_ORUNMILA assert Roles.PREMIUM & Permission.ORUNMILA_EXTENDED_MEMORIES - def test_developer_starter_has_no_permissions(self): - assert Roles.DEVELOPER_STARTER == Permission.NONE + def test_developer_starter_matches_user(self): + assert Roles.DEVELOPER_STARTER == Roles.USER + assert Roles.DEVELOPER_STARTER & Permission.WALLET + assert not (Roles.DEVELOPER_STARTER & Permission.USE_ORUNMILA) def test_developer_starter_missing_orunmila(self): assert not (Roles.DEVELOPER_STARTER & Permission.USE_ORUNMILA) @@ -66,6 +70,9 @@ def test_check_access_unknown_role_alone_returns_false(self): def test_check_access_admin_skips_other_roles(self): assert Roles.checkAccess(["ADMIN", "USER"], Permission.USE_ORUNMILA) is True + def test_check_access_user_has_wallet(self): + assert Roles.checkAccess(["USER"], Permission.WALLET) is True + class TestRequirePermission: async def test_raises_403_when_missing(self): From 9a1e67a98a260dac76ba2d2a33e8f481d79911a7 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 20:28:19 -0300 Subject: [PATCH 02/34] add wallet orm models --- main/models/wallet.py | 86 +++++++++++++++++++++++++++++++++++++ tests/test_wallet_models.py | 20 +++++++++ 2 files changed, 106 insertions(+) create mode 100644 main/models/wallet.py create mode 100644 tests/test_wallet_models.py diff --git a/main/models/wallet.py b/main/models/wallet.py new file mode 100644 index 00000000..f9e3dd1d --- /dev/null +++ b/main/models/wallet.py @@ -0,0 +1,86 @@ +from sqlalchemy import ( + Column, + Date, + Enum, + ForeignKey, + Integer, + Numeric, + SmallInteger, + String, + TIMESTAMP, + UniqueConstraint, + func, +) + +from main.models.base import Base + + +class Wallet(Base): + __tablename__ = "wallets" + + walletId = Column(Integer, primary_key=True, autoincrement=True) + userId = Column(Integer, ForeignKey("users.userId", ondelete="RESTRICT"), nullable=False, index=True) + name = Column(String(120), nullable=False) + lastRecalc = Column(TIMESTAMP, nullable=True) + createdAt = Column(TIMESTAMP, server_default=func.current_timestamp(), nullable=False) + + +class Holding(Base): + __tablename__ = "holdings" + + holdingId = Column(Integer, primary_key=True, autoincrement=True) + walletId = Column(Integer, ForeignKey("wallets.walletId", ondelete="RESTRICT"), nullable=False, index=True) + assetType = Column(String(20), nullable=False) + ticker = Column(String(20), nullable=False, index=True) + tickerName = Column(String(120), nullable=True) + quantity = Column(Numeric(18, 8), nullable=False) + avgPrice = Column(Numeric(18, 6), nullable=False) + percentIdeal = Column(Numeric(5, 2), nullable=True) + rating = Column(SmallInteger, nullable=True) + updatedAt = Column(TIMESTAMP, server_default=func.current_timestamp(), nullable=False) + + __table_args__ = (UniqueConstraint("walletId", "ticker", name="uq_holdings_wallet_ticker"),) + + +class Transaction(Base): + __tablename__ = "transactions" + + entryId = Column(Integer, primary_key=True, autoincrement=True) + walletId = Column(Integer, ForeignKey("wallets.walletId", ondelete="RESTRICT"), nullable=False, index=True) + side = Column(Enum("Compra", "Venda", name="entry_side"), nullable=False) + assetType = Column(String(20), nullable=False) + ticker = Column(String(20), nullable=False, index=True) + date = Column(Date, nullable=False) + quantity = Column(Numeric(18, 8), nullable=False) + price = Column(Numeric(18, 6), nullable=False) + costs = Column(Numeric(18, 2), nullable=False, default=0) + createdAt = Column(TIMESTAMP, server_default=func.current_timestamp(), nullable=False) + + +class Target(Base): + __tablename__ = "targets" + + targetId = Column(Integer, primary_key=True, autoincrement=True) + walletId = Column(Integer, ForeignKey("wallets.walletId", ondelete="RESTRICT"), nullable=False, index=True) + keyKind = Column(Enum("ticker", "group", name="target_key_kind"), nullable=False) + keyValue = Column(String(40), nullable=False) + percentIdeal = Column(Numeric(5, 2), nullable=False) + + __table_args__ = (UniqueConstraint("walletId", "keyKind", "keyValue", name="uq_targets_wallet_key"),) + + +class Snapshot(Base): + __tablename__ = "snapshots" + + snapshotId = Column(Integer, primary_key=True, autoincrement=True) + walletId = Column(Integer, ForeignKey("wallets.walletId", ondelete="RESTRICT"), nullable=False, index=True) + date = Column(Date, nullable=False, index=True) + applied = Column(Numeric(18, 2), nullable=False) + equity = Column(Numeric(18, 2), nullable=False) + variation = Column(Numeric(18, 2), nullable=False) + profitTwr = Column(Numeric(10, 6), nullable=True) + profitAmount = Column(Numeric(18, 2), nullable=False) + profitTwr12m = Column(Numeric(10, 6), nullable=True) + profitTwr12mAmount = Column(Numeric(18, 2), nullable=False) + + __table_args__ = (UniqueConstraint("walletId", "date", name="uq_snapshots_wallet_date"),) diff --git a/tests/test_wallet_models.py b/tests/test_wallet_models.py new file mode 100644 index 00000000..6885f502 --- /dev/null +++ b/tests/test_wallet_models.py @@ -0,0 +1,20 @@ +from main.models.base import Base +from main.models.wallet import Holding, Snapshot, Target, Transaction, Wallet + + +def test_wallet_tables_create_and_round_trip(dbSession): + wallet = Wallet(userId=1, name="Principal") + dbSession.add(wallet) + dbSession.commit() + assert wallet.walletId == 1 + holding = Holding( + walletId=wallet.walletId, + assetType="Stock", + ticker="PETR4", + quantity=10, + avgPrice=28.5, + ) + dbSession.add(holding) + dbSession.commit() + assert holding.holdingId == 1 + assert holding.rating is None From d060b044fc7f0b616d556421ac2f0a9cf5814fcf Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 20:40:09 -0300 Subject: [PATCH 03/34] add wallet auth dependency --- main/app/wallet/auth.py | 38 +++++++++++++++++++++++++++ tests/test_wallet_auth.py | 55 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+) create mode 100644 main/app/wallet/auth.py create mode 100644 tests/test_wallet_auth.py diff --git a/main/app/wallet/auth.py b/main/app/wallet/auth.py new file mode 100644 index 00000000..55eadf9e --- /dev/null +++ b/main/app/wallet/auth.py @@ -0,0 +1,38 @@ +import logging + +from fastapi import Depends, HTTPException, Request +from sqlalchemy.orm import Session + +from config import getSession +from main.app.authentication.introspect import introspectToken +from main.utils.roles import Permission, Roles + +logger = logging.getLogger(__name__) + + +def resolveRawToken(request: Request) -> str: + token = request.headers.get("X-Access-Token") + if not token: + authHeader = request.headers.get("Authorization") + if authHeader and authHeader.startswith("Bearer "): + token = authHeader.split(" ")[1] + if not token: + token = request.cookies.get("mansa_token") + if not token: + raise HTTPException(status_code=401, detail="Unauthorized") + return token + + +def getWalletIdentity(request: Request, db: Session = Depends(getSession)) -> dict: + return introspectToken(db, resolveRawToken(request)) + + +def requireWalletUser(identity: dict = Depends(getWalletIdentity)) -> dict: + if not Roles.checkAccess(identity.get("roles", []), Permission.WALLET): + raise HTTPException(status_code=403, detail="Missing required permission: WALLET") + return identity + + +def requireWalletOwnership(walletUserId: int, identity: dict) -> None: + if walletUserId != identity["userId"]: + raise HTTPException(status_code=403, detail="not-owner") diff --git a/tests/test_wallet_auth.py b/tests/test_wallet_auth.py new file mode 100644 index 00000000..57630e8f --- /dev/null +++ b/tests/test_wallet_auth.py @@ -0,0 +1,55 @@ +from fastapi import Depends, FastAPI +from fastapi.testclient import TestClient + +import main.app.wallet.auth as walletAuth +from main.app.wallet.auth import requireWalletUser + + +def make_probe_app(monkeypatch, raw="tok123", roles=None): + seen = {} + + def fake_introspect(db, token): + seen["raw"] = token + return {"userId": 1, "username": "u", "roles": roles if roles is not None else ["USER"]} + + monkeypatch.setattr(walletAuth, "introspectToken", fake_introspect) + app = FastAPI() + + @app.get("/probe") + def probe(user: dict = Depends(requireWalletUser)): + return user + + return TestClient(app, raise_server_exceptions=False), seen + + +def test_bearer_header_reaches_introspect_without_prefix(monkeypatch): + client, seen = make_probe_app(monkeypatch) + resp = client.get("/probe", headers={"Authorization": "Bearer tok123"}) + assert resp.status_code == 200 + assert seen["raw"] == "tok123" + + +def test_access_token_header_wins(monkeypatch): + client, seen = make_probe_app(monkeypatch) + resp = client.get("/probe", headers={"X-Access-Token": "tokABC"}) + assert resp.status_code == 200 + assert seen["raw"] == "tokABC" + + +def test_cookie_fallback_pinned_to_mansa_token(monkeypatch): + client, seen = make_probe_app(monkeypatch) + resp = client.get("/probe", cookies={"mansa_token": "tokCK"}) + assert resp.status_code == 200 + assert seen["raw"] == "tokCK" + + +def test_no_token_returns_401(monkeypatch): + client, _ = make_probe_app(monkeypatch) + assert client.get("/probe").status_code == 401 + + +def test_role_without_wallet_returns_403(monkeypatch): + client, _ = make_probe_app(monkeypatch, roles=[]) + resp = client.get("/probe", headers={"Authorization": "Bearer tok123"}) + assert resp.status_code == 403 + assert resp.json()["detail"] == "Missing required permission: WALLET" From 3622253bf16ffa3be0dc6381397ad573eb89e579 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 20:40:44 -0300 Subject: [PATCH 04/34] add wallet tables migration --- migrations/env.py | 2 + .../versions/73211a401c34_wallet_tables.py | 120 ++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 migrations/versions/73211a401c34_wallet_tables.py diff --git a/migrations/env.py b/migrations/env.py index efe69ba5..7814a629 100644 --- a/migrations/env.py +++ b/migrations/env.py @@ -15,6 +15,8 @@ import main.models.orunmila import main.models.stocksapi_key import main.models.sandbox +import main.models.wallet # noqa: F401 +import main.models.memory # noqa: F401 config = context.config diff --git a/migrations/versions/73211a401c34_wallet_tables.py b/migrations/versions/73211a401c34_wallet_tables.py new file mode 100644 index 00000000..15748d50 --- /dev/null +++ b/migrations/versions/73211a401c34_wallet_tables.py @@ -0,0 +1,120 @@ +"""wallet tables + +Revision ID: 73211a401c34 +Revises: f7a8b9c0d1e2 +Create Date: 2026-09-30 20:38:20.280169 + +""" + +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = "73211a401c34" +down_revision: Union[str, Sequence[str], None] = "f7a8b9c0d1e2" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "wallets", + sa.Column("walletId", sa.Integer(), autoincrement=True, nullable=False), + sa.Column("userId", sa.Integer(), nullable=False), + sa.Column("name", sa.String(length=120), nullable=False), + sa.Column("lastRecalc", sa.TIMESTAMP(), nullable=True), + sa.Column("createdAt", sa.TIMESTAMP(), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False), + sa.ForeignKeyConstraint(["userId"], ["users.userId"], ondelete="RESTRICT"), + sa.PrimaryKeyConstraint("walletId"), + ) + op.create_index(op.f("ix_wallets_userId"), "wallets", ["userId"], unique=False) + op.create_table( + "holdings", + sa.Column("holdingId", sa.Integer(), autoincrement=True, nullable=False), + sa.Column("walletId", sa.Integer(), nullable=False), + sa.Column("assetType", sa.String(length=20), nullable=False), + sa.Column("ticker", sa.String(length=20), nullable=False), + sa.Column("tickerName", sa.String(length=120), nullable=True), + sa.Column("quantity", sa.Numeric(precision=18, scale=8), nullable=False), + sa.Column("avgPrice", sa.Numeric(precision=18, scale=6), nullable=False), + sa.Column("percentIdeal", sa.Numeric(precision=5, scale=2), nullable=True), + sa.Column("rating", sa.SmallInteger(), nullable=True), + sa.Column("updatedAt", sa.TIMESTAMP(), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False), + sa.ForeignKeyConstraint(["walletId"], ["wallets.walletId"], ondelete="RESTRICT"), + sa.PrimaryKeyConstraint("holdingId"), + sa.UniqueConstraint("walletId", "ticker", name="uq_holdings_wallet_ticker"), + ) + op.create_index(op.f("ix_holdings_ticker"), "holdings", ["ticker"], unique=False) + op.create_index(op.f("ix_holdings_walletId"), "holdings", ["walletId"], unique=False) + op.create_table( + "snapshots", + sa.Column("snapshotId", sa.Integer(), autoincrement=True, nullable=False), + sa.Column("walletId", sa.Integer(), nullable=False), + sa.Column("date", sa.Date(), nullable=False), + sa.Column("applied", sa.Numeric(precision=18, scale=2), nullable=False), + sa.Column("equity", sa.Numeric(precision=18, scale=2), nullable=False), + sa.Column("variation", sa.Numeric(precision=18, scale=2), nullable=False), + sa.Column("profitTwr", sa.Numeric(precision=10, scale=6), nullable=True), + sa.Column("profitAmount", sa.Numeric(precision=18, scale=2), nullable=False), + sa.Column("profitTwr12m", sa.Numeric(precision=10, scale=6), nullable=True), + sa.Column("profitTwr12mAmount", sa.Numeric(precision=18, scale=2), nullable=False), + sa.ForeignKeyConstraint(["walletId"], ["wallets.walletId"], ondelete="RESTRICT"), + sa.PrimaryKeyConstraint("snapshotId"), + sa.UniqueConstraint("walletId", "date", name="uq_snapshots_wallet_date"), + ) + op.create_index(op.f("ix_snapshots_date"), "snapshots", ["date"], unique=False) + op.create_index(op.f("ix_snapshots_walletId"), "snapshots", ["walletId"], unique=False) + op.create_table( + "targets", + sa.Column("targetId", sa.Integer(), autoincrement=True, nullable=False), + sa.Column("walletId", sa.Integer(), nullable=False), + sa.Column("keyKind", sa.Enum("ticker", "group", name="target_key_kind"), nullable=False), + sa.Column("keyValue", sa.String(length=40), nullable=False), + sa.Column("percentIdeal", sa.Numeric(precision=5, scale=2), nullable=False), + sa.ForeignKeyConstraint(["walletId"], ["wallets.walletId"], ondelete="RESTRICT"), + sa.PrimaryKeyConstraint("targetId"), + sa.UniqueConstraint("walletId", "keyKind", "keyValue", name="uq_targets_wallet_key"), + ) + op.create_index(op.f("ix_targets_walletId"), "targets", ["walletId"], unique=False) + op.create_table( + "transactions", + sa.Column("entryId", sa.Integer(), autoincrement=True, nullable=False), + sa.Column("walletId", sa.Integer(), nullable=False), + sa.Column("side", sa.Enum("Compra", "Venda", name="entry_side"), nullable=False), + sa.Column("assetType", sa.String(length=20), nullable=False), + sa.Column("ticker", sa.String(length=20), nullable=False), + sa.Column("date", sa.Date(), nullable=False), + sa.Column("quantity", sa.Numeric(precision=18, scale=8), nullable=False), + sa.Column("price", sa.Numeric(precision=18, scale=6), nullable=False), + sa.Column("costs", sa.Numeric(precision=18, scale=2), nullable=False), + sa.Column("createdAt", sa.TIMESTAMP(), server_default=sa.text("(CURRENT_TIMESTAMP)"), nullable=False), + sa.ForeignKeyConstraint(["walletId"], ["wallets.walletId"], ondelete="RESTRICT"), + sa.PrimaryKeyConstraint("entryId"), + ) + op.create_index(op.f("ix_transactions_ticker"), "transactions", ["ticker"], unique=False) + op.create_index(op.f("ix_transactions_walletId"), "transactions", ["walletId"], unique=False) + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f("ix_transactions_walletId"), table_name="transactions") + op.drop_index(op.f("ix_transactions_ticker"), table_name="transactions") + op.drop_table("transactions") + op.drop_index(op.f("ix_targets_walletId"), table_name="targets") + op.drop_table("targets") + op.drop_index(op.f("ix_snapshots_walletId"), table_name="snapshots") + op.drop_index(op.f("ix_snapshots_date"), table_name="snapshots") + op.drop_table("snapshots") + op.drop_index(op.f("ix_holdings_walletId"), table_name="holdings") + op.drop_index(op.f("ix_holdings_ticker"), table_name="holdings") + op.drop_table("holdings") + op.drop_index(op.f("ix_wallets_userId"), table_name="wallets") + op.drop_table("wallets") + # ### end Alembic commands ### From 260a8b3c688836c5186f487f89d0bf009ad6b39f Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 20:46:28 -0300 Subject: [PATCH 05/34] add wallets endpoints --- main/controller/wallet_controller.py | 39 ++++++++++++++++++++++++++++ main/service/user_service.py | 2 ++ main/service/wallet_service.py | 19 ++++++++++++++ tests/conftest.py | 21 +++++++++++++++ tests/test_wallets.py | 36 +++++++++++++++++++++++++ 5 files changed, 117 insertions(+) create mode 100644 main/controller/wallet_controller.py create mode 100644 main/service/wallet_service.py create mode 100644 tests/test_wallets.py diff --git a/main/controller/wallet_controller.py b/main/controller/wallet_controller.py new file mode 100644 index 00000000..268b3e51 --- /dev/null +++ b/main/controller/wallet_controller.py @@ -0,0 +1,39 @@ +import logging + +from fastapi import APIRouter, Depends +from fastapi.responses import ORJSONResponse +from pydantic import BaseModel +from sqlalchemy.orm import Session + +from config import getSession +from main.app.wallet.auth import requireWalletUser +from main.service import wallet_service + +logger = logging.getLogger(__name__) + +router = APIRouter(prefix="/wallet", tags=["wallet"]) + + +class WalletCreate(BaseModel): + name: str + + +@router.post("/wallets", response_class=ORJSONResponse, status_code=201) +def create_wallet_route( + payload: WalletCreate, + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + wallet = wallet_service.create_wallet(db, user["userId"], payload.name) + return {"walletId": wallet.walletId, "name": wallet.name} + + +@router.get("/wallets", response_class=ORJSONResponse) +def list_wallets_route( + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + return [ + {"walletId": walletItem.walletId, "name": walletItem.name, "lastRecalc": walletItem.lastRecalc} + for walletItem in wallet_service.list_wallets(db, user["userId"]) + ] diff --git a/main/service/user_service.py b/main/service/user_service.py index 0477cb90..de3fa23d 100644 --- a/main/service/user_service.py +++ b/main/service/user_service.py @@ -10,6 +10,7 @@ from main.utils.service_manager import getApp from main.utils.scheduler import registerJob from main.controller.user_controller import router as userRouter +from main.controller.wallet_controller import router as walletRouter logger = logging.getLogger(__name__) @@ -44,6 +45,7 @@ class UserService: def initialize(port: int): service = getApp(port) service.include_router(userRouter) + service.include_router(walletRouter) registerJob( removeInactiveSessions, diff --git a/main/service/wallet_service.py b/main/service/wallet_service.py new file mode 100644 index 00000000..f93844ed --- /dev/null +++ b/main/service/wallet_service.py @@ -0,0 +1,19 @@ +import logging + +from sqlalchemy.orm import Session + +from main.models.wallet import Wallet + +logger = logging.getLogger(__name__) + + +def create_wallet(db: Session, userId: int, name: str) -> Wallet: + wallet = Wallet(userId=userId, name=name) + db.add(wallet) + db.commit() + db.refresh(wallet) + return wallet + + +def list_wallets(db: Session, userId: int) -> list[Wallet]: + return db.query(Wallet).filter(Wallet.userId == userId).all() diff --git a/tests/conftest.py b/tests/conftest.py index c2911859..becb245b 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -305,3 +305,24 @@ def make_stocksapi_client(mock_api_key=None): app.dependency_overrides[verifyAPIKey] = lambda: mock_api_key return TestClient(app, raise_server_exceptions=False), app, mock_session + + +def make_wallet_client(mock_identity=None, db=None): + """Return (client, app) with wallet router and mocked deps.""" + from main.controller.wallet_controller import router as walletRouter + from main.utils.errors import registerErrorHandlers + from main.app.wallet.auth import getWalletIdentity + from unittest.mock import MagicMock + import main.models.wallet # noqa: F401 + + app = FastAPI() + app.include_router(walletRouter) + registerErrorHandlers(app) + + session = db if db is not None else MagicMock() + app.dependency_overrides[__import__("config", fromlist=["getSession"]).getSession] = lambda: session + + identity = mock_identity or {"userId": 1, "username": "testuser", "roles": ["USER"]} + app.dependency_overrides[getWalletIdentity] = lambda: identity + + return TestClient(app, raise_server_exceptions=False), app, session diff --git a/tests/test_wallets.py b/tests/test_wallets.py new file mode 100644 index 00000000..afffc8f6 --- /dev/null +++ b/tests/test_wallets.py @@ -0,0 +1,36 @@ +import main.models.wallet # noqa: F401 +from tests.conftest import dbSession, make_wallet_client # noqa: F401 + + +def test_create_wallet_returns_201(dbSession): + client, _, _ = make_wallet_client(db=dbSession) + resp = client.post("/wallet/wallets", json={"name": "Principal"}) + assert resp.status_code == 201 + assert resp.json() == {"walletId": 1, "name": "Principal"} + + +def test_list_wallets_returns_only_mine(dbSession): + from main.models.wallet import Wallet + + client, _, _ = make_wallet_client(db=dbSession) + client.post("/wallet/wallets", json={"name": "Mine"}) + dbSession.add(Wallet(userId=2, name="Theirs")) + dbSession.commit() + names = [wallet["name"] for wallet in client.get("/wallet/wallets").json()] + assert names == ["Mine"] + + +def test_no_token_returns_401(): + from fastapi import FastAPI + from fastapi.testclient import TestClient + from unittest.mock import MagicMock + + from main.controller.wallet_controller import router as walletRouter + from main.utils.errors import registerErrorHandlers + + app = FastAPI() + app.include_router(walletRouter) + registerErrorHandlers(app) + app.dependency_overrides[__import__("config", fromlist=["getSession"]).getSession] = lambda: MagicMock() + resp = TestClient(app, raise_server_exceptions=False).get("/wallet/wallets") + assert resp.status_code == 401 From 0d1629bf5360d9a04677e754c1d1ad288dc17d21 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 20:56:52 -0300 Subject: [PATCH 06/34] add entries ledger and holdings recalc --- main/controller/wallet_controller.py | 66 +++++++++++- main/service/wallet_service.py | 152 ++++++++++++++++++++++++++- tests/test_wallet_entries.py | 133 +++++++++++++++++++++++ 3 files changed, 349 insertions(+), 2 deletions(-) create mode 100644 tests/test_wallet_entries.py diff --git a/main/controller/wallet_controller.py b/main/controller/wallet_controller.py index 268b3e51..96341729 100644 --- a/main/controller/wallet_controller.py +++ b/main/controller/wallet_controller.py @@ -1,6 +1,6 @@ import logging -from fastapi import APIRouter, Depends +from fastapi import APIRouter, Depends, Query from fastapi.responses import ORJSONResponse from pydantic import BaseModel from sqlalchemy.orm import Session @@ -37,3 +37,67 @@ def list_wallets_route( {"walletId": walletItem.walletId, "name": walletItem.name, "lastRecalc": walletItem.lastRecalc} for walletItem in wallet_service.list_wallets(db, user["userId"]) ] + + +def serialize_holding(holding) -> dict | None: + if holding is None: + return None + return {"ticker": holding.ticker, "quantity": float(holding.quantity), "avgPrice": float(holding.avgPrice)} + + +def serialize_entry(entry) -> dict: + return { + "entryId": entry.entryId, + "wallet_id": entry.walletId, + "side": entry.side, + "asset_type": entry.assetType, + "ticker": entry.ticker, + "date": entry.date.isoformat(), + "quantity": float(entry.quantity), + "price": float(entry.price), + "costs": float(entry.costs), + } + + +@router.post("/entries", response_class=ORJSONResponse, status_code=201) +def create_entry_route( + payload: wallet_service.EntryCreate, + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + entry, holding = wallet_service.add_entry(db, user["userId"], payload) + return {"entryId": entry.entryId, "holding": serialize_holding(holding)} + + +@router.get("/entries", response_class=ORJSONResponse) +def list_entries_route( + wallet_id: int, + ticker: str | None = None, + limit: int = Query(default=20, ge=1, le=100), + offset: int = Query(default=0, ge=0), + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + total, items = wallet_service.list_entries(db, user["userId"], wallet_id, ticker, limit, offset) + return {"total": total, "items": [serialize_entry(item) for item in items]} + + +@router.patch("/entries/{entryId}", response_class=ORJSONResponse) +def update_entry_route( + entryId: int, + payload: wallet_service.EntryUpdate, + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + entry, holding = wallet_service.update_entry(db, user["userId"], entryId, payload) + return {"entryId": entry.entryId, "holding": serialize_holding(holding)} + + +@router.delete("/entries/{entryId}", response_class=ORJSONResponse) +def delete_entry_route( + entryId: int, + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + deletedId, holding = wallet_service.delete_entry(db, user["userId"], entryId) + return {"entryId": deletedId, "holding": serialize_holding(holding)} diff --git a/main/service/wallet_service.py b/main/service/wallet_service.py index f93844ed..72655651 100644 --- a/main/service/wallet_service.py +++ b/main/service/wallet_service.py @@ -1,8 +1,12 @@ import logging +from datetime import date as dateType +from typing import Literal +from fastapi import HTTPException +from pydantic import BaseModel, Field from sqlalchemy.orm import Session -from main.models.wallet import Wallet +from main.models.wallet import Holding, Transaction, Wallet logger = logging.getLogger(__name__) @@ -17,3 +21,149 @@ def create_wallet(db: Session, userId: int, name: str) -> Wallet: def list_wallets(db: Session, userId: int) -> list[Wallet]: return db.query(Wallet).filter(Wallet.userId == userId).all() + + +class EntryCreate(BaseModel): + wallet_id: int + side: Literal["Compra", "Venda"] + asset_type: str + ticker: str + date: dateType + quantity: float = Field(gt=0) + price: float = Field(ge=0) + costs: float = Field(default=0.0, ge=0) + + +class EntryUpdate(BaseModel): + date: dateType | None = None + quantity: float | None = Field(default=None, gt=0) + price: float | None = Field(default=None, ge=0) + costs: float | None = Field(default=None, ge=0) + + +def _get_owned_wallet(db: Session, walletId: int, userId: int): + from main.app.wallet.auth import requireWalletOwnership + + wallet = db.query(Wallet).filter(Wallet.walletId == walletId).first() + if wallet is None: + raise HTTPException(status_code=404, detail="wallet not found") + requireWalletOwnership(wallet.userId, {"userId": userId}) + return wallet + + +def _apply_entries(quantity: float, avg: float, entries: list[Transaction]) -> tuple[float, float]: + for entry in entries: + entryQuantity = float(entry.quantity) + entryPrice = float(entry.price) + entryCosts = float(entry.costs) + if entry.side == "Compra": + total = quantity * avg + entryQuantity * entryPrice + entryCosts + quantity += entryQuantity + avg = total / quantity + else: + if entryQuantity > quantity: + raise HTTPException(status_code=422, detail="sell exceeds holding") + quantity -= entryQuantity + return quantity, avg + + +def recalc_holding(db: Session, walletId: int, ticker: str) -> Holding | None: + entries = ( + db.query(Transaction) + .filter(Transaction.walletId == walletId, Transaction.ticker == ticker) + .order_by(Transaction.date, Transaction.entryId) + .all() + ) + holding = db.query(Holding).filter(Holding.walletId == walletId, Holding.ticker == ticker).first() + if not entries: + if holding is not None: + db.delete(holding) + return None + quantity, avg = _apply_entries(0.0, 0.0, entries) + if holding is None: + holding = Holding( + walletId=walletId, assetType=entries[0].assetType, ticker=ticker, quantity=quantity, avgPrice=avg + ) + db.add(holding) + else: + holding.quantity = quantity + holding.avgPrice = avg + return holding + + +def add_entry(db: Session, userId: int, data: EntryCreate) -> tuple[Transaction, Holding | None]: + _get_owned_wallet(db, data.wallet_id, userId) + if data.side == "Venda": + holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() + if holding is None or data.quantity > float(holding.quantity): + raise HTTPException(status_code=422, detail="sell exceeds holding") + entry = Transaction( + walletId=data.wallet_id, + side=data.side, + assetType=data.asset_type, + ticker=data.ticker, + date=data.date, + quantity=data.quantity, + price=data.price, + costs=data.costs, + ) + db.add(entry) + db.flush() + holding = recalc_holding(db, data.wallet_id, data.ticker) + db.commit() + db.refresh(entry) + if holding is not None: + db.refresh(holding) + return entry, holding + + +def list_entries( + db: Session, userId: int, walletId: int, ticker: str | None = None, limit: int = 20, offset: int = 0 +) -> tuple[int, list[Transaction]]: + _get_owned_wallet(db, walletId, userId) + query = db.query(Transaction).filter(Transaction.walletId == walletId) + if ticker is not None: + query = query.filter(Transaction.ticker == ticker) + total = query.count() + items = query.order_by(Transaction.date, Transaction.entryId).offset(offset).limit(limit).all() + return total, items + + +def update_entry(db: Session, userId: int, entryId: int, patch: EntryUpdate) -> tuple[Transaction, Holding | None]: + entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() + if entry is None: + raise HTTPException(status_code=404, detail="entry not found") + _get_owned_wallet(db, entry.walletId, userId) + changes = patch.model_dump(exclude_unset=True) + for fieldName, fieldValue in changes.items(): + if fieldValue is not None: + setattr(entry, fieldName, fieldValue) + db.flush() + try: + holding = recalc_holding(db, entry.walletId, entry.ticker) + except HTTPException: + db.rollback() + raise + db.commit() + db.refresh(entry) + if holding is not None: + db.refresh(holding) + return entry, holding + + +def delete_entry(db: Session, userId: int, entryId: int) -> tuple[int, Holding | None]: + entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() + if entry is None: + raise HTTPException(status_code=404, detail="entry not found") + _get_owned_wallet(db, entry.walletId, userId) + walletId = entry.walletId + ticker = entry.ticker + db.delete(entry) + db.flush() + try: + holding = recalc_holding(db, walletId, ticker) + except HTTPException: + db.rollback() + raise + db.commit() + return entryId, holding diff --git a/tests/test_wallet_entries.py b/tests/test_wallet_entries.py new file mode 100644 index 00000000..314afa40 --- /dev/null +++ b/tests/test_wallet_entries.py @@ -0,0 +1,133 @@ +import main.models.wallet # noqa: F401 +from tests.conftest import make_wallet_client + + +def test_compra_average_includes_costs(dbSession): + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-10", + "quantity": 10, + "price": 10.0, + "costs": 0.0, + }, + ) + resp = client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-02-10", + "quantity": 10, + "price": 20.0, + "costs": 5.0, + }, + ) + assert resp.status_code == 201 + assert resp.json()["holding"] == {"ticker": "PETR4", "quantity": 20.0, "avgPrice": 15.25} + + +def test_venda_keeps_avg_and_rejects_oversell(dbSession): + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-10", + "quantity": 20, + "price": 10.0, + }, + ) + resp = client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Venda", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-03-10", + "quantity": 5, + "price": 30.0, + }, + ) + assert resp.json()["holding"] == {"ticker": "PETR4", "quantity": 15.0, "avgPrice": 10.0} + bad = client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Venda", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-04-10", + "quantity": 99, + "price": 30.0, + }, + ) + assert bad.status_code == 422 + items = client.get(f"/wallet/entries?wallet_id={walletId}").json() + assert items["total"] == 2 + + +def test_edit_replays_holding_from_ledger(dbSession): + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + first = client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-10", + "quantity": 10, + "price": 10.0, + }, + ).json() + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-02-10", + "quantity": 10, + "price": 20.0, + "costs": 5.0, + }, + ) + resp = client.patch(f"/wallet/entries/{first['entryId']}", json={"quantity": 20}) + assert resp.json()["holding"] == {"ticker": "PETR4", "quantity": 30.0, "avgPrice": 13.5} + + +def test_cross_user_wallet_returns_403(dbSession): + from main.models.wallet import Wallet + + dbSession.add(Wallet(userId=2, name="Theirs")) + dbSession.commit() + client, _, _ = make_wallet_client(db=dbSession) + resp = client.post( + "/wallet/entries", + json={ + "wallet_id": 1, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-10", + "quantity": 1, + "price": 1.0, + }, + ) + assert resp.status_code == 403 From e18ac92d58cdd3d6ba8471780734394caba8728e Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 21:06:31 -0300 Subject: [PATCH 07/34] add positions with live price join --- main/controller/wallet_controller.py | 9 ++ main/service/wallet_service.py | 123 ++++++++++++++++++++++++++- tests/test_wallet_positions.py | 97 +++++++++++++++++++++ 3 files changed, 228 insertions(+), 1 deletion(-) create mode 100644 tests/test_wallet_positions.py diff --git a/main/controller/wallet_controller.py b/main/controller/wallet_controller.py index 96341729..7782f3d0 100644 --- a/main/controller/wallet_controller.py +++ b/main/controller/wallet_controller.py @@ -101,3 +101,12 @@ def delete_entry_route( ): deletedId, holding = wallet_service.delete_entry(db, user["userId"], entryId) return {"entryId": deletedId, "holding": serialize_holding(holding)} + + +@router.get("/positions", response_class=ORJSONResponse) +def list_positions_route( + wallet_id: int, + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + return wallet_service.get_positions(db, wallet_id, user["userId"]) diff --git a/main/service/wallet_service.py b/main/service/wallet_service.py index 72655651..9aa8dfe1 100644 --- a/main/service/wallet_service.py +++ b/main/service/wallet_service.py @@ -1,12 +1,17 @@ import logging +import os +from concurrent.futures import ThreadPoolExecutor from datetime import date as dateType +from datetime import datetime from typing import Literal +import requests from fastapi import HTTPException from pydantic import BaseModel, Field from sqlalchemy.orm import Session -from main.models.wallet import Holding, Transaction, Wallet +from config import Config +from main.models.wallet import Holding, Target, Transaction, Wallet logger = logging.getLogger(__name__) @@ -167,3 +172,119 @@ def delete_entry(db: Session, userId: int, entryId: int) -> tuple[int, Holding | raise db.commit() return entryId, holding + + +STOCKS_TIMEOUT = 3 + + +def stocksApiBase() -> str: + return f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}" + + +def stocksApiHeaders() -> dict: + key = os.getenv("STOCKS_API_KEY", "") + return {"X-API-Key": key} if key else {} + + +def fetchLivePrices(tickers: list[str]) -> dict[str, float | None]: + if not tickers: + return {} + + def one(ticker: str) -> tuple[str, float | None]: + try: + resp = requests.get( + f"{stocksApiBase()}/stocks/cotations/live", + params={"search": ticker, "compact": False}, + headers=stocksApiHeaders(), + timeout=STOCKS_TIMEOUT, + ) + if resp.status_code == 429: + logger.warning("Live price quota exhausted for %s", ticker) + return ticker, None + if resp.status_code != 200: + return ticker, None + return ticker, float(resp.json()["data"][0]["PRECO ATUAL"]) + except Exception: + return ticker, None + + with ThreadPoolExecutor(max_workers=min(8, max(1, len(tickers)))) as pool: + return dict(pool.map(one, tickers)) + + +def fetchCachedClose(ticker: str) -> float | None: + try: + resp = requests.get( + f"{stocksApiBase()}/stocks/cotations", + params={"search": ticker}, + headers=stocksApiHeaders(), + timeout=STOCKS_TIMEOUT, + ) + if resp.status_code == 429: + logger.warning("Cached close quota exhausted for %s", ticker) + return None + if resp.status_code != 200: + return None + rows = resp.json()["data"] + latest = max(rows, key=lambda row: datetime.strptime(row["DATA"], "%d-%m-%Y")) + return float(latest["PRECO"]) + except Exception: + return None + + +def get_positions(db: Session, walletId: int, userId: int) -> dict: + _get_owned_wallet(db, walletId, userId) + holdings = db.query(Holding).filter(Holding.walletId == walletId).all() + tickers = [holding.ticker for holding in holdings] + prices = fetchLivePrices(tickers) + for ticker, price in list(prices.items()): + if price is None: + prices[ticker] = fetchCachedClose(ticker) + equities: dict[str, float | None] = {} + for holding in holdings: + holdingQuantity = float(holding.quantity) + holdingAvg = float(holding.avgPrice) + price = prices.get(holding.ticker) + if price is None: + equities[holding.ticker] = None + else: + equities[holding.ticker] = holdingQuantity * price + equityTotal = sum(equity for equity in equities.values() if equity is not None) + items = [] + for holding in holdings: + holdingQuantity = float(holding.quantity) + holdingAvg = float(holding.avgPrice) + price = prices.get(holding.ticker) + equity = equities[holding.ticker] + if price is None or equity is None: + currentPrice = None + equityValue = None + appreciation = None + else: + currentPrice = price + equityValue = equity + appreciation = equity - holdingQuantity * holdingAvg + percentWallet = (equity / equityTotal * 100) if equity is not None and equityTotal else 0 + target = ( + db.query(Target) + .filter(Target.walletId == walletId, Target.keyKind == "ticker", Target.keyValue == holding.ticker) + .first() + ) + percentIdeal = float(target.percentIdeal) if target is not None else None + holdingRating = holding.rating + buyFlag = ( + percentIdeal is not None and percentWallet < percentIdeal and (holdingRating is None or holdingRating >= 6) + ) + items.append( + { + "ticker": holding.ticker, + "quantity": holdingQuantity, + "avgPrice": holdingAvg, + "current_price": currentPrice, + "equity": equityValue, + "appreciation": appreciation, + "percent_wallet": percentWallet, + "percent_ideal": percentIdeal, + "buy_flag": buyFlag, + } + ) + return {"items": items, "equity_total": equityTotal} diff --git a/tests/test_wallet_positions.py b/tests/test_wallet_positions.py new file mode 100644 index 00000000..74dd6afc --- /dev/null +++ b/tests/test_wallet_positions.py @@ -0,0 +1,97 @@ +import requests + +import main.models.wallet # noqa: F401 +from tests.conftest import make_wallet_client + + +def _live_ok(url, params=None, headers=None, timeout=None): + class Resp: + status_code = 200 + + @staticmethod + def json(): + return {"data": [{"TICKER": "PETR4", "PRECO ATUAL": 30.0}]} + + assert params["search"] == "PETR4" + return Resp() + + +def _seed(dbSession, client): + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-10", + "quantity": 10, + "price": 10.0, + }, + ) + return walletId + + +def test_positions_math_with_live_price(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_ok) + client, _, _ = make_wallet_client(db=dbSession) + walletId = _seed(dbSession, client) + item = client.get(f"/wallet/positions?wallet_id={walletId}").json()["items"][0] + assert item["current_price"] == 30.0 + assert item["equity"] == 300.0 + assert item["appreciation"] == 200.0 + + +def test_live_timeout_falls_back_to_null(dbSession, monkeypatch): + def boom(*a, **k): + raise requests.Timeout() + + monkeypatch.setattr(requests, "get", boom) + client, _, _ = make_wallet_client(db=dbSession) + walletId = _seed(dbSession, client) + body = client.get(f"/wallet/positions?wallet_id={walletId}").json() + assert body["items"][0]["current_price"] is None + assert body["equity_total"] == 0 + + +def test_unknown_ticker_returns_null_not_422(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_ok) + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + resp = client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Crypto", + "ticker": "BTC", + "date": "2026-01-10", + "quantity": 1, + "price": 100.0, + }, + ) + assert resp.status_code == 201 + item = client.get(f"/wallet/positions?wallet_id={walletId}").json()["items"][0] + assert item["current_price"] is None + + +def test_cached_fallback_serves_when_live_fails(dbSession, monkeypatch): + def fake_get(url, params=None, headers=None, timeout=None): + if url.endswith("/stocks/cotations/live"): + raise requests.Timeout() + + class Resp: + status_code = 200 + + @staticmethod + def json(): + return {"data": [{"DATA": "01-01-2026", "PRECO": 25.0}, {"DATA": "29-09-2026", "PRECO": 27.5}]} + + return Resp() + + monkeypatch.setattr(requests, "get", fake_get) + client, _, _ = make_wallet_client(db=dbSession) + walletId = _seed(dbSession, client) + item = client.get(f"/wallet/positions?wallet_id={walletId}").json()["items"][0] + assert item["current_price"] == 27.5 From 2497036210c590b5ebfb7e0b35158200bf93f7f5 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 21:19:45 -0300 Subject: [PATCH 08/34] add summary snapshots allocation targets ratings --- main/controller/wallet_controller.py | 45 +++++++++ main/service/wallet_service.py | 131 ++++++++++++++++++++++++++- tests/test_wallet_summary.py | 83 +++++++++++++++++ 3 files changed, 257 insertions(+), 2 deletions(-) create mode 100644 tests/test_wallet_summary.py diff --git a/main/controller/wallet_controller.py b/main/controller/wallet_controller.py index 7782f3d0..5f2f81b4 100644 --- a/main/controller/wallet_controller.py +++ b/main/controller/wallet_controller.py @@ -4,6 +4,7 @@ from fastapi.responses import ORJSONResponse from pydantic import BaseModel from sqlalchemy.orm import Session +from typing import Literal from config import getSession from main.app.wallet.auth import requireWalletUser @@ -110,3 +111,47 @@ def list_positions_route( db: Session = Depends(getSession), ): return wallet_service.get_positions(db, wallet_id, user["userId"]) + + +@router.get("/summary", response_class=ORJSONResponse) +def get_summary_route( + wallet_id: int, + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + return wallet_service.get_summary(db, wallet_id, user["userId"]) + + +@router.get("/allocation", response_class=ORJSONResponse) +def get_allocation_route( + wallet_id: int, + group_by: Literal["ticker", "type"] = Query(default="ticker"), + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + return wallet_service.get_allocation(db, wallet_id, user["userId"], group_by) + + +@router.put("/targets", response_class=ORJSONResponse) +def upsert_target_route( + payload: wallet_service.TargetUpsert, + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + target = wallet_service.upsert_target(db, user["userId"], payload) + return { + "wallet_id": target.walletId, + "key_kind": target.keyKind, + "key_value": target.keyValue, + "percent_ideal": float(target.percentIdeal), + } + + +@router.put("/ratings", response_class=ORJSONResponse) +def set_rating_route( + payload: wallet_service.RatingUpsert, + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + holding = wallet_service.set_rating(db, user["userId"], payload) + return {"ticker": holding.ticker, "rating": holding.rating} diff --git a/main/service/wallet_service.py b/main/service/wallet_service.py index 9aa8dfe1..b8760e76 100644 --- a/main/service/wallet_service.py +++ b/main/service/wallet_service.py @@ -11,7 +11,7 @@ from sqlalchemy.orm import Session from config import Config -from main.models.wallet import Holding, Target, Transaction, Wallet +from main.models.wallet import Holding, Snapshot, Target, Transaction, Wallet logger = logging.getLogger(__name__) @@ -263,7 +263,7 @@ def get_positions(db: Session, walletId: int, userId: int) -> dict: currentPrice = price equityValue = equity appreciation = equity - holdingQuantity * holdingAvg - percentWallet = (equity / equityTotal * 100) if equity is not None and equityTotal else 0 + percentWallet = (equity / equityTotal) if equity is not None and equityTotal else 0 target = ( db.query(Target) .filter(Target.walletId == walletId, Target.keyKind == "ticker", Target.keyValue == holding.ticker) @@ -288,3 +288,130 @@ def get_positions(db: Session, walletId: int, userId: int) -> dict: } ) return {"items": items, "equity_total": equityTotal} + + +class TargetUpsert(BaseModel): + wallet_id: int + key_kind: Literal["ticker", "group"] + key_value: str + percent_ideal: float = Field(ge=0, le=100) + + +class RatingUpsert(BaseModel): + wallet_id: int + ticker: str + rating: int = Field(ge=0, le=10) + + +def get_summary(db: Session, walletId: int, userId: int) -> dict: + wallet = _get_owned_wallet(db, walletId, userId) + holdings = db.query(Holding).filter(Holding.walletId == walletId).all() + applied = sum(float(holding.quantity) * float(holding.avgPrice) for holding in holdings) + tickers = [holding.ticker for holding in holdings] + prices = fetchLivePrices(tickers) + for ticker, price in list(prices.items()): + if price is None: + prices[ticker] = fetchCachedClose(ticker) + equity = 0.0 + for holding in holdings: + price = prices.get(holding.ticker) + if price is not None: + equity += float(holding.quantity) * price + variation = equity - applied + today = dateType.today() + snapshot = db.query(Snapshot).filter(Snapshot.walletId == walletId, Snapshot.date == today).first() + if snapshot is None: + snapshot = Snapshot( + walletId=walletId, + date=today, + applied=applied, + equity=equity, + variation=variation, + profitTwr=None, + profitAmount=variation, + profitTwr12m=None, + profitTwr12mAmount=variation, + ) + db.add(snapshot) + else: + snapshot.applied = applied + snapshot.equity = equity + snapshot.variation = variation + snapshot.profitTwr = None + snapshot.profitAmount = variation + snapshot.profitTwr12m = None + snapshot.profitTwr12mAmount = variation + wallet.lastRecalc = datetime.now() + db.commit() + return { + "applied": applied, + "equity": equity, + "variation": variation, + "profit_twr": None, + "profit_amount": variation, + "profit_twr_12m": None, + "profit_twr_12m_amount": variation, + } + + +def get_allocation(db: Session, walletId: int, userId: int, groupBy: str) -> dict: + _get_owned_wallet(db, walletId, userId) + holdings = db.query(Holding).filter(Holding.walletId == walletId).all() + tickers = [holding.ticker for holding in holdings] + prices = fetchLivePrices(tickers) + for ticker, price in list(prices.items()): + if price is None: + prices[ticker] = fetchCachedClose(ticker) + groupEquity: dict[str, float] = {} + for holding in holdings: + price = prices.get(holding.ticker) + holdingEquity = float(holding.quantity) * price if price is not None else 0.0 + groupKey = holding.ticker if groupBy == "ticker" else holding.assetType + groupEquity[groupKey] = groupEquity.get(groupKey, 0.0) + holdingEquity + equityTotal = sum(groupEquity.values()) + items = [ + { + "key": groupKey, + "equity": groupValue, + "pct": (groupValue / equityTotal) if equityTotal else 0, + } + for groupKey, groupValue in groupEquity.items() + ] + return {"items": items, "equity_total": equityTotal} + + +def upsert_target(db: Session, userId: int, data: TargetUpsert) -> Target: + _get_owned_wallet(db, data.wallet_id, userId) + target = ( + db.query(Target) + .filter( + Target.walletId == data.wallet_id, + Target.keyKind == data.key_kind, + Target.keyValue == data.key_value, + ) + .first() + ) + if target is None: + target = Target( + walletId=data.wallet_id, + keyKind=data.key_kind, + keyValue=data.key_value, + percentIdeal=data.percent_ideal, + ) + db.add(target) + else: + target.percentIdeal = data.percent_ideal + db.commit() + db.refresh(target) + return target + + +def set_rating(db: Session, userId: int, data: RatingUpsert) -> Holding: + _get_owned_wallet(db, data.wallet_id, userId) + holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() + if holding is None: + raise HTTPException(status_code=404, detail="holding not found") + holding.rating = data.rating + db.commit() + db.refresh(holding) + return holding diff --git a/tests/test_wallet_summary.py b/tests/test_wallet_summary.py new file mode 100644 index 00000000..11f4d5dc --- /dev/null +++ b/tests/test_wallet_summary.py @@ -0,0 +1,83 @@ +import requests + +import main.models.wallet # noqa: F401 +from tests.conftest import make_wallet_client + + +def _live_ok(url, params=None, headers=None, timeout=None): + class Resp: + status_code = 200 + + @staticmethod + def json(): + return {"data": [{"TICKER": "PETR4", "PRECO ATUAL": 30.0}]} + + assert params["search"] == "PETR4" + return Resp() + + +def _seed(client): + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-10", + "quantity": 10, + "price": 10.0, + }, + ) + return walletId + + +def test_summary_math_and_snapshot_upsert(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_ok) + client, _, _ = make_wallet_client(db=dbSession) + walletId = _seed(client) + body = client.get(f"/wallet/summary?wallet_id={walletId}").json() + assert body == { + "applied": 100.0, + "equity": 300.0, + "variation": 200.0, + "profit_twr": None, + "profit_amount": 200.0, + "profit_twr_12m": None, + "profit_twr_12m_amount": 200.0, + } + again = client.get(f"/wallet/summary?wallet_id={walletId}").json() + assert again["variation"] == 200.0 + from main.models.wallet import Snapshot + + assert dbSession.query(Snapshot).filter(Snapshot.walletId == walletId).count() == 1 + + +def test_targets_drive_buy_flag_and_ratings_gate(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_ok) + client, _, _ = make_wallet_client(db=dbSession) + walletId = _seed(client) + assert ( + client.put( + "/wallet/targets", + json={"wallet_id": walletId, "key_kind": "ticker", "key_value": "PETR4", "percent_ideal": 80.0}, + ).status_code + == 200 + ) + assert ( + client.put( + "/wallet/targets", + json={"wallet_id": walletId, "key_kind": "ticker", "key_value": "PETR4", "percent_ideal": 101.0}, + ).status_code + == 422 + ) + assert client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 8}).json() == { + "ticker": "PETR4", + "rating": 8, + } + assert ( + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 11}).status_code == 422 + ) + item = client.get(f"/wallet/positions?wallet_id={walletId}").json()["items"][0] + assert item["percent_ideal"] == 80.0 and item["buy_flag"] is True From 7dbe21a3cca8120025f9dfc6a67338316ba408cf Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 21:31:10 -0300 Subject: [PATCH 09/34] fix wallet p1 ci fallout --- main/models/wallet.py | 4 +-- main/service/wallet_service.py | 56 +++++++++++++++++----------------- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/main/models/wallet.py b/main/models/wallet.py index f9e3dd1d..f5045297 100644 --- a/main/models/wallet.py +++ b/main/models/wallet.py @@ -47,7 +47,7 @@ class Transaction(Base): entryId = Column(Integer, primary_key=True, autoincrement=True) walletId = Column(Integer, ForeignKey("wallets.walletId", ondelete="RESTRICT"), nullable=False, index=True) - side = Column(Enum("Compra", "Venda", name="entry_side"), nullable=False) + side = Column(Enum("Compra", "Venda", name="entry_side"), nullable=False) # type: ignore[var-annotated] assetType = Column(String(20), nullable=False) ticker = Column(String(20), nullable=False, index=True) date = Column(Date, nullable=False) @@ -62,7 +62,7 @@ class Target(Base): targetId = Column(Integer, primary_key=True, autoincrement=True) walletId = Column(Integer, ForeignKey("wallets.walletId", ondelete="RESTRICT"), nullable=False, index=True) - keyKind = Column(Enum("ticker", "group", name="target_key_kind"), nullable=False) + keyKind = Column(Enum("ticker", "group", name="target_key_kind"), nullable=False) # type: ignore[var-annotated] keyValue = Column(String(40), nullable=False) percentIdeal = Column(Numeric(5, 2), nullable=False) diff --git a/main/service/wallet_service.py b/main/service/wallet_service.py index b8760e76..8c0917ed 100644 --- a/main/service/wallet_service.py +++ b/main/service/wallet_service.py @@ -52,7 +52,7 @@ def _get_owned_wallet(db: Session, walletId: int, userId: int): wallet = db.query(Wallet).filter(Wallet.walletId == walletId).first() if wallet is None: raise HTTPException(status_code=404, detail="wallet not found") - requireWalletOwnership(wallet.userId, {"userId": userId}) + requireWalletOwnership(int(wallet.userId), {"userId": userId}) return wallet @@ -91,8 +91,8 @@ def recalc_holding(db: Session, walletId: int, ticker: str) -> Holding | None: ) db.add(holding) else: - holding.quantity = quantity - holding.avgPrice = avg + holding.quantity = quantity # type: ignore[assignment] + holding.avgPrice = avg # type: ignore[assignment] return holding @@ -138,14 +138,14 @@ def update_entry(db: Session, userId: int, entryId: int, patch: EntryUpdate) -> entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() if entry is None: raise HTTPException(status_code=404, detail="entry not found") - _get_owned_wallet(db, entry.walletId, userId) + _get_owned_wallet(db, int(entry.walletId), userId) changes = patch.model_dump(exclude_unset=True) for fieldName, fieldValue in changes.items(): if fieldValue is not None: setattr(entry, fieldName, fieldValue) db.flush() try: - holding = recalc_holding(db, entry.walletId, entry.ticker) + holding = recalc_holding(db, int(entry.walletId), str(entry.ticker)) except HTTPException: db.rollback() raise @@ -160,13 +160,13 @@ def delete_entry(db: Session, userId: int, entryId: int) -> tuple[int, Holding | entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() if entry is None: raise HTTPException(status_code=404, detail="entry not found") - _get_owned_wallet(db, entry.walletId, userId) + _get_owned_wallet(db, int(entry.walletId), userId) walletId = entry.walletId ticker = entry.ticker db.delete(entry) db.flush() try: - holding = recalc_holding(db, walletId, ticker) + holding = recalc_holding(db, int(walletId), str(ticker)) except HTTPException: db.rollback() raise @@ -194,7 +194,7 @@ def one(ticker: str) -> tuple[str, float | None]: try: resp = requests.get( f"{stocksApiBase()}/stocks/cotations/live", - params={"search": ticker, "compact": False}, + params={"search": ticker, "compact": False}, # type: ignore[arg-type] headers=stocksApiHeaders(), timeout=STOCKS_TIMEOUT, ) @@ -234,7 +234,7 @@ def fetchCachedClose(ticker: str) -> float | None: def get_positions(db: Session, walletId: int, userId: int) -> dict: _get_owned_wallet(db, walletId, userId) holdings = db.query(Holding).filter(Holding.walletId == walletId).all() - tickers = [holding.ticker for holding in holdings] + tickers = [str(holding.ticker) for holding in holdings] prices = fetchLivePrices(tickers) for ticker, price in list(prices.items()): if price is None: @@ -243,18 +243,18 @@ def get_positions(db: Session, walletId: int, userId: int) -> dict: for holding in holdings: holdingQuantity = float(holding.quantity) holdingAvg = float(holding.avgPrice) - price = prices.get(holding.ticker) + price = prices.get(str(holding.ticker)) if price is None: - equities[holding.ticker] = None + equities[str(holding.ticker)] = None else: - equities[holding.ticker] = holdingQuantity * price + equities[str(holding.ticker)] = holdingQuantity * price equityTotal = sum(equity for equity in equities.values() if equity is not None) items = [] for holding in holdings: holdingQuantity = float(holding.quantity) holdingAvg = float(holding.avgPrice) - price = prices.get(holding.ticker) - equity = equities[holding.ticker] + price = prices.get(str(holding.ticker)) + equity = equities[str(holding.ticker)] if price is None or equity is None: currentPrice = None equityValue = None @@ -307,14 +307,14 @@ def get_summary(db: Session, walletId: int, userId: int) -> dict: wallet = _get_owned_wallet(db, walletId, userId) holdings = db.query(Holding).filter(Holding.walletId == walletId).all() applied = sum(float(holding.quantity) * float(holding.avgPrice) for holding in holdings) - tickers = [holding.ticker for holding in holdings] + tickers = [str(holding.ticker) for holding in holdings] prices = fetchLivePrices(tickers) for ticker, price in list(prices.items()): if price is None: prices[ticker] = fetchCachedClose(ticker) equity = 0.0 for holding in holdings: - price = prices.get(holding.ticker) + price = prices.get(str(holding.ticker)) if price is not None: equity += float(holding.quantity) * price variation = equity - applied @@ -334,13 +334,13 @@ def get_summary(db: Session, walletId: int, userId: int) -> dict: ) db.add(snapshot) else: - snapshot.applied = applied - snapshot.equity = equity - snapshot.variation = variation - snapshot.profitTwr = None - snapshot.profitAmount = variation - snapshot.profitTwr12m = None - snapshot.profitTwr12mAmount = variation + snapshot.applied = applied # type: ignore[assignment] + snapshot.equity = equity # type: ignore[assignment] + snapshot.variation = variation # type: ignore[assignment] + snapshot.profitTwr = None # type: ignore[assignment] + snapshot.profitAmount = variation # type: ignore[assignment] + snapshot.profitTwr12m = None # type: ignore[assignment] + snapshot.profitTwr12mAmount = variation # type: ignore[assignment] wallet.lastRecalc = datetime.now() db.commit() return { @@ -357,16 +357,16 @@ def get_summary(db: Session, walletId: int, userId: int) -> dict: def get_allocation(db: Session, walletId: int, userId: int, groupBy: str) -> dict: _get_owned_wallet(db, walletId, userId) holdings = db.query(Holding).filter(Holding.walletId == walletId).all() - tickers = [holding.ticker for holding in holdings] + tickers = [str(holding.ticker) for holding in holdings] prices = fetchLivePrices(tickers) for ticker, price in list(prices.items()): if price is None: prices[ticker] = fetchCachedClose(ticker) groupEquity: dict[str, float] = {} for holding in holdings: - price = prices.get(holding.ticker) + price = prices.get(str(holding.ticker)) holdingEquity = float(holding.quantity) * price if price is not None else 0.0 - groupKey = holding.ticker if groupBy == "ticker" else holding.assetType + groupKey = str(holding.ticker) if groupBy == "ticker" else str(holding.assetType) groupEquity[groupKey] = groupEquity.get(groupKey, 0.0) + holdingEquity equityTotal = sum(groupEquity.values()) items = [ @@ -400,7 +400,7 @@ def upsert_target(db: Session, userId: int, data: TargetUpsert) -> Target: ) db.add(target) else: - target.percentIdeal = data.percent_ideal + target.percentIdeal = data.percent_ideal # type: ignore[assignment] db.commit() db.refresh(target) return target @@ -411,7 +411,7 @@ def set_rating(db: Session, userId: int, data: RatingUpsert) -> Holding: holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() if holding is None: raise HTTPException(status_code=404, detail="holding not found") - holding.rating = data.rating + holding.rating = data.rating # type: ignore[assignment] db.commit() db.refresh(holding) return holding From b67d8b3693bb3cd3c76f4d9213c02b4aa6e5ba95 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 21:42:19 -0300 Subject: [PATCH 10/34] add earnings model and migration --- main/models/wallet.py | 16 +++++ main/service/wallet_service.py | 2 + .../versions/c4d1e8f2a917_wallet_earnings.py | 58 +++++++++++++++++++ tests/test_wallet_models.py | 25 +++++++- 4 files changed, 100 insertions(+), 1 deletion(-) create mode 100644 migrations/versions/c4d1e8f2a917_wallet_earnings.py diff --git a/main/models/wallet.py b/main/models/wallet.py index f5045297..2836f941 100644 --- a/main/models/wallet.py +++ b/main/models/wallet.py @@ -84,3 +84,19 @@ class Snapshot(Base): profitTwr12mAmount = Column(Numeric(18, 2), nullable=False) __table_args__ = (UniqueConstraint("walletId", "date", name="uq_snapshots_wallet_date"),) + + +class Earning(Base): + __tablename__ = "earnings" + + earningId = Column(Integer, primary_key=True, autoincrement=True) + walletId = Column(Integer, ForeignKey("wallets.walletId", ondelete="RESTRICT"), nullable=False, index=True) + ticker = Column(String(20), nullable=False, index=True) + kind = Column(Enum("Div", "JSCP", "RendTributado", name="earning_kind"), nullable=False) # type: ignore[var-annotated] + exDate = Column(Date, nullable=False) + payDate = Column(Date, nullable=False) + gross = Column(Numeric(18, 2), nullable=False) + netIrAdjusted = Column(Numeric(18, 2), nullable=False) + status = Column(Enum("A Receber", "Recebido", name="earning_status"), nullable=False, index=True) # type: ignore[var-annotated] + + __table_args__ = (UniqueConstraint("walletId", "ticker", "exDate", "kind", name="uq_earnings_accrual"),) diff --git a/main/service/wallet_service.py b/main/service/wallet_service.py index 8c0917ed..8993b322 100644 --- a/main/service/wallet_service.py +++ b/main/service/wallet_service.py @@ -15,6 +15,8 @@ logger = logging.getLogger(__name__) +IR_RATE = {"Div": 0.0, "JSCP": 0.15, "RendTributado": 0.15} + def create_wallet(db: Session, userId: int, name: str) -> Wallet: wallet = Wallet(userId=userId, name=name) diff --git a/migrations/versions/c4d1e8f2a917_wallet_earnings.py b/migrations/versions/c4d1e8f2a917_wallet_earnings.py new file mode 100644 index 00000000..73768920 --- /dev/null +++ b/migrations/versions/c4d1e8f2a917_wallet_earnings.py @@ -0,0 +1,58 @@ +"""wallet earnings + +Revision ID: c4d1e8f2a917 +Revises: 73211a401c34 +Create Date: 2026-09-30 21:40:00.000000 + +Hand-written (autogenerate drifts on this dev DB: orphan Sep-04 tables +wallet_lots/wallet_dividends/prometheus_*/wallet_holdings emit 29 drops; +app DB user lacks CREATE DATABASE so no scaffold DB possible). +Content mirrors autogenerate style of 73211a401c34 exactly: +single create_table(earnings), zero drops. +""" + +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = "c4d1e8f2a917" +down_revision: Union[str, Sequence[str], None] = "73211a401c34" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.create_table( + "earnings", + sa.Column("earningId", sa.Integer(), autoincrement=True, nullable=False), + sa.Column("walletId", sa.Integer(), nullable=False), + sa.Column("ticker", sa.String(length=20), nullable=False), + sa.Column("kind", sa.Enum("Div", "JSCP", "RendTributado", name="earning_kind"), nullable=False), + sa.Column("exDate", sa.Date(), nullable=False), + sa.Column("payDate", sa.Date(), nullable=False), + sa.Column("gross", sa.Numeric(precision=18, scale=2), nullable=False), + sa.Column("netIrAdjusted", sa.Numeric(precision=18, scale=2), nullable=False), + sa.Column("status", sa.Enum("A Receber", "Recebido", name="earning_status"), nullable=False), + sa.ForeignKeyConstraint(["walletId"], ["wallets.walletId"], ondelete="RESTRICT"), + sa.PrimaryKeyConstraint("earningId"), + sa.UniqueConstraint("walletId", "ticker", "exDate", "kind", name="uq_earnings_accrual"), + ) + op.create_index(op.f("ix_earnings_status"), "earnings", ["status"], unique=False) + op.create_index(op.f("ix_earnings_ticker"), "earnings", ["ticker"], unique=False) + op.create_index(op.f("ix_earnings_walletId"), "earnings", ["walletId"], unique=False) + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_index(op.f("ix_earnings_walletId"), table_name="earnings") + op.drop_index(op.f("ix_earnings_ticker"), table_name="earnings") + op.drop_index(op.f("ix_earnings_status"), table_name="earnings") + op.drop_table("earnings") + # ### end Alembic commands ### diff --git a/tests/test_wallet_models.py b/tests/test_wallet_models.py index 6885f502..ce2bc70f 100644 --- a/tests/test_wallet_models.py +++ b/tests/test_wallet_models.py @@ -1,5 +1,5 @@ from main.models.base import Base -from main.models.wallet import Holding, Snapshot, Target, Transaction, Wallet +from main.models.wallet import Earning, Holding, Snapshot, Target, Transaction, Wallet def test_wallet_tables_create_and_round_trip(dbSession): @@ -18,3 +18,26 @@ def test_wallet_tables_create_and_round_trip(dbSession): dbSession.commit() assert holding.holdingId == 1 assert holding.rating is None + + +def test_earning_round_trip(dbSession): + from datetime import date + from main.models.wallet import Wallet + + wallet = Wallet(userId=1, name="W") + dbSession.add(wallet) + dbSession.commit() + row = Earning( + walletId=wallet.walletId, + ticker="PETR4", + kind="JSCP", + exDate=date(2026, 3, 1), + payDate=date(2026, 4, 1), + gross=10.0, + netIrAdjusted=8.5, + status="A Receber", + ) + dbSession.add(row) + dbSession.commit() + assert row.earningId == 1 + assert row.netIrAdjusted == 8.5 From 54adf098f62151b340a776c8a0e48bd68b967f93 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 21:51:12 -0300 Subject: [PATCH 11/34] add earnings sync --- main/controller/wallet_controller.py | 37 +++++++++ main/service/wallet_service.py | 109 ++++++++++++++++++++++++++- tests/test_wallet_earnings.py | 96 +++++++++++++++++++++++ 3 files changed, 241 insertions(+), 1 deletion(-) create mode 100644 tests/test_wallet_earnings.py diff --git a/main/controller/wallet_controller.py b/main/controller/wallet_controller.py index 5f2f81b4..17e4fbd2 100644 --- a/main/controller/wallet_controller.py +++ b/main/controller/wallet_controller.py @@ -155,3 +155,40 @@ def set_rating_route( ): holding = wallet_service.set_rating(db, user["userId"], payload) return {"ticker": holding.ticker, "rating": holding.rating} + + +class EarningsSync(BaseModel): + wallet_id: int + + +def serialize_earning(earning) -> dict: + return { + "ticker": earning.ticker, + "kind": earning.kind, + "gross": float(earning.gross), + "net_ir_adjusted": float(earning.netIrAdjusted), + "status": earning.status, + } + + +@router.get("/earnings", response_class=ORJSONResponse) +def list_earnings_route( + wallet_id: int, + status: str | None = None, + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + return { + "items": [ + serialize_earning(item) for item in wallet_service.list_earnings(db, wallet_id, user["userId"], status) + ] + } + + +@router.post("/earnings/sync", response_class=ORJSONResponse) +def sync_earnings_route( + payload: EarningsSync, + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + return wallet_service.sync_earnings(db, payload.wallet_id, user["userId"]) diff --git a/main/service/wallet_service.py b/main/service/wallet_service.py index 8993b322..8877ee9f 100644 --- a/main/service/wallet_service.py +++ b/main/service/wallet_service.py @@ -11,12 +11,19 @@ from sqlalchemy.orm import Session from config import Config -from main.models.wallet import Holding, Snapshot, Target, Transaction, Wallet +from main.models.wallet import Earning, Holding, Snapshot, Target, Transaction, Wallet logger = logging.getLogger(__name__) IR_RATE = {"Div": 0.0, "JSCP": 0.15, "RendTributado": 0.15} +TIPO_MAP = { + "Dividendo": "Div", + "JCP": "JSCP", + "Juros Sobre Capital Proprio": "JSCP", + "Rend. Tributado": "RendTributado", +} + def create_wallet(db: Session, userId: int, name: str) -> Wallet: wallet = Wallet(userId=userId, name=name) @@ -417,3 +424,103 @@ def set_rating(db: Session, userId: int, data: RatingUpsert) -> Holding: db.commit() db.refresh(holding) return holding + + +def position_at_date(entries: list[Transaction], exDate: dateType) -> float: + # str() trick: Column-typed dates compare mypy-clean as ISO strings (lexicographic == chronological). + datedEntries = [entry for entry in entries if str(entry.date) <= exDate.isoformat()] + quantity, _ = _apply_entries(0.0, 0.0, datedEntries) + return quantity + + +def fetchMarketDividends(ticker: str) -> list[dict]: + try: + resp = requests.get( + f"{stocksApiBase()}/stocks/fundamental", + params={"search": ticker, "fields": "HISTORICO DIVIDENDOS"}, # type: ignore[arg-type] + headers=stocksApiHeaders(), + timeout=STOCKS_TIMEOUT, + ) + if resp.status_code != 200: + return [] + payload = resp.json()["data"] + if payload and isinstance(payload[0], dict) and "HISTORICO DIVIDENDOS" in payload[0]: + return payload[0]["HISTORICO DIVIDENDOS"] + return payload + except Exception: + return [] + + +def sync_earnings(db: Session, walletId: int, userId: int) -> dict: + _get_owned_wallet(db, walletId, userId) + today = dateType.today() + accrued = 0 + skippedUnknown: list[str] = [] + holdings = db.query(Holding).filter(Holding.walletId == walletId).all() + for holding in holdings: + if float(holding.quantity) <= 0: + continue + holdingTicker = str(holding.ticker) + ledgerEntries = ( + db.query(Transaction) + .filter(Transaction.walletId == walletId, Transaction.ticker == holdingTicker) + .order_by(Transaction.date, Transaction.entryId) + .all() + ) + for record in fetchMarketDividends(holdingTicker): + label = record.get("TIPO PROVENTO") + kind = TIPO_MAP.get(label) + if kind is None: + if label not in skippedUnknown: + skippedUnknown.append(label) + continue + try: + exDate = datetime.strptime(record["DATA COM"], "%d-%m-%Y").date() + payDate = datetime.strptime(record["DATA PAGAMENTO"], "%d-%m-%Y").date() + perShare = float(record["VALOR AJUSTADO"]) + except Exception: + continue + quantityAtEx = position_at_date(ledgerEntries, exDate) + if quantityAtEx <= 0: + continue + existing = ( + db.query(Earning) + .filter( + Earning.walletId == walletId, + Earning.ticker == holdingTicker, + Earning.exDate == exDate, + Earning.kind == kind, + ) + .first() + ) + if existing is not None: + continue + gross = perShare * quantityAtEx + earning = Earning( + walletId=walletId, + ticker=holdingTicker, + kind=kind, + exDate=exDate, + payDate=payDate, + gross=gross, + netIrAdjusted=gross * (1 - IR_RATE[kind]), + status="Recebido" if payDate <= today else "A Receber", + ) + db.add(earning) + accrued += 1 + transitioned = 0 + pending = db.query(Earning).filter(Earning.walletId == walletId, Earning.status == "A Receber").all() + for earning in pending: + if str(earning.payDate) <= today.isoformat(): + earning.status = "Recebido" # type: ignore[assignment] + transitioned += 1 + db.commit() + return {"accrued": accrued, "transitioned": transitioned, "skipped_unknown": skippedUnknown} + + +def list_earnings(db: Session, walletId: int, userId: int, status: str | None = None) -> list[Earning]: + _get_owned_wallet(db, walletId, userId) + query = db.query(Earning).filter(Earning.walletId == walletId) + if status is not None: + query = query.filter(Earning.status == status) + return query.order_by(Earning.exDate, Earning.earningId).all() diff --git a/tests/test_wallet_earnings.py b/tests/test_wallet_earnings.py new file mode 100644 index 00000000..e4f7043e --- /dev/null +++ b/tests/test_wallet_earnings.py @@ -0,0 +1,96 @@ +import requests +from freezegun import freeze_time + +import main.models.wallet # noqa: F401 +from tests.conftest import make_wallet_client + + +def _div_fundamental(url, params=None, headers=None, timeout=None): + class Resp: + status_code = 200 + + @staticmethod + def json(): + return { + "data": [ + { + "DATA COM": "01-03-2026", + "DATA PAGAMENTO": "01-04-2026", + "TIPO PROVENTO": "Dividendo", + "VALOR AJUSTADO": 2.0, + }, + { + "DATA COM": "01-06-2026", + "DATA PAGAMENTO": "20-12-2026", + "TIPO PROVENTO": "JCP", + "VALOR AJUSTADO": 1.0, + }, + { + "DATA COM": "01-07-2026", + "DATA PAGAMENTO": "20-12-2026", + "TIPO PROVENTO": "Bonificacao", + "VALOR AJUSTADO": 5.0, + }, + ] + } + + return Resp() + + +@freeze_time("2026-09-30") +def test_sync_accrues_with_qty_at_ex_date(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _div_fundamental) + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-10", + "quantity": 10, + "price": 10.0, + }, + ) + body = client.post("/wallet/earnings/sync", json={"wallet_id": walletId}).json() + assert body == {"accrued": 2, "transitioned": 0, "skipped_unknown": ["Bonificacao"]} + items = client.get(f"/wallet/earnings?wallet_id={walletId}").json()["items"] + by_kind = {r["kind"]: r for r in items} + assert by_kind["Div"] == { + "ticker": "PETR4", + "kind": "Div", + "gross": 20.0, + "net_ir_adjusted": 20.0, + "status": "Recebido", + } + assert by_kind["JSCP"] == { + "ticker": "PETR4", + "kind": "JSCP", + "gross": 10.0, + "net_ir_adjusted": 8.5, + "status": "A Receber", + } + + +@freeze_time("2026-09-30") +def test_sync_is_idempotent(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _div_fundamental) + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-10", + "quantity": 10, + "price": 10.0, + }, + ) + client.post("/wallet/earnings/sync", json={"wallet_id": walletId}) + again = client.post("/wallet/earnings/sync", json={"wallet_id": walletId}).json() + assert again == {"accrued": 0, "transitioned": 0, "skipped_unknown": ["Bonificacao"]} From 48b77c3040c9fb57b96cdddafe884e142eeab050 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 22:09:45 -0300 Subject: [PATCH 12/34] add performance windows --- main/controller/wallet_controller.py | 20 +++- main/service/wallet_service.py | 170 ++++++++++++++++++++++++++- tests/test_wallet_performance.py | 57 +++++++++ 3 files changed, 245 insertions(+), 2 deletions(-) create mode 100644 tests/test_wallet_performance.py diff --git a/main/controller/wallet_controller.py b/main/controller/wallet_controller.py index 17e4fbd2..301bdb99 100644 --- a/main/controller/wallet_controller.py +++ b/main/controller/wallet_controller.py @@ -1,6 +1,7 @@ import logging +from datetime import date as dateType -from fastapi import APIRouter, Depends, Query +from fastapi import APIRouter, Depends, HTTPException, Query from fastapi.responses import ORJSONResponse from pydantic import BaseModel from sqlalchemy.orm import Session @@ -192,3 +193,20 @@ def sync_earnings_route( db: Session = Depends(getSession), ): return wallet_service.sync_earnings(db, payload.wallet_id, user["userId"]) + + +@router.get("/performance", response_class=ORJSONResponse) +def get_performance_route( + wallet_id: int, + ticker: str | None = None, + fromIso: str = Query(alias="from"), + toIso: str = Query(alias="to"), + user: dict = Depends(requireWalletUser), + db: Session = Depends(getSession), +): + try: + startDate = dateType.fromisoformat(fromIso) + endDate = dateType.fromisoformat(toIso) + except ValueError: + raise HTTPException(status_code=422, detail="invalid date, expected YYYY-MM-DD") + return wallet_service.get_performance(db, wallet_id, user["userId"], ticker, startDate, endDate) diff --git a/main/service/wallet_service.py b/main/service/wallet_service.py index 8877ee9f..401625b3 100644 --- a/main/service/wallet_service.py +++ b/main/service/wallet_service.py @@ -3,6 +3,10 @@ from concurrent.futures import ThreadPoolExecutor from datetime import date as dateType from datetime import datetime +from functools import lru_cache +from math import sqrt +from statistics import stdev +from types import SimpleNamespace from typing import Literal import requests @@ -468,7 +472,7 @@ def sync_earnings(db: Session, walletId: int, userId: int) -> dict: .all() ) for record in fetchMarketDividends(holdingTicker): - label = record.get("TIPO PROVENTO") + label = str(record.get("TIPO PROVENTO")) kind = TIPO_MAP.get(label) if kind is None: if label not in skippedUnknown: @@ -524,3 +528,167 @@ def list_earnings(db: Session, walletId: int, userId: int, status: str | None = if status is not None: query = query.filter(Earning.status == status) return query.order_by(Earning.exDate, Earning.earningId).all() + + +PERFORMANCE_EPOCH = "1970-01-01T00:00:00" + + +def fetchPadraoCloses(ticker: str) -> list[tuple[dateType, float]]: + try: + resp = requests.get( + f"{stocksApiBase()}/stocks/cotations", + params={"search": ticker}, + headers=stocksApiHeaders(), + timeout=STOCKS_TIMEOUT, + ) + if resp.status_code != 200: + return [] + parsedCloses: list[tuple[dateType, float]] = [] + for closeRow in resp.json()["data"]: + try: + parsedCloses.append((datetime.strptime(closeRow["DATA"], "%d-%m-%Y").date(), float(closeRow["PRECO"]))) + except Exception: + continue + parsedCloses.sort(key=lambda closeItem: closeItem[0]) + return parsedCloses + except Exception: + return [] + + +@lru_cache(maxsize=1024) +def _cachedPerformance( + walletId: int, + tickerKey: str, + fromIso: str, + toIso: str, + recalcKey: str, + entriesSnap: tuple[tuple[str, str, str, float, float, float, int], ...], + earningsSnap: tuple[tuple[str, str, float, float], ...], +) -> dict: + del recalcKey + if tickerKey: + tickers = [tickerKey] + else: + universe = {entryTicker for entryTicker, _, _, _, _, _, _ in entriesSnap} + universe.update(earnTicker for earnTicker, _, _, _ in earningsSnap) + tickers = sorted(universe) + perTickerDays: dict[str, dict[str, tuple[float, float, float]]] = {} + dividendsReceived = 0.0 + for ticker in tickers: + for earnTicker, exIso, _, netValue in earningsSnap: + if earnTicker == ticker and fromIso <= exIso <= toIso: + dividendsReceived += netValue + series = fetchPadraoCloses(ticker) + tickerEntries = [ + (entryIso, entrySide, entryQty, entryPrice, entryCosts) + for entryTicker, entryIso, entrySide, entryQty, entryPrice, entryCosts, _ in entriesSnap + if entryTicker == ticker + ] + baselineRows = [ + SimpleNamespace(side=entrySide, quantity=entryQty, price=entryPrice, costs=entryCosts) + for entryIso, entrySide, entryQty, entryPrice, entryCosts in tickerEntries + if entryIso < fromIso + ] + positionQty, positionAvg = _apply_entries(0.0, 0.0, baselineRows) # type: ignore[arg-type] + entriesByDay: dict[str, list] = {} + for entryIso, entrySide, entryQty, entryPrice, entryCosts in tickerEntries: + if fromIso <= entryIso <= toIso: + entriesByDay.setdefault(entryIso, []).append( + SimpleNamespace(side=entrySide, quantity=entryQty, price=entryPrice, costs=entryCosts) + ) + closeByIso = { + closeDay.isoformat(): closePrice + for closeDay, closePrice in series + if fromIso <= closeDay.isoformat() <= toIso + } + windowDays = sorted(closeByIso) + prevClose = None + for seriesDay, seriesClose in series: + if seriesDay.isoformat() < fromIso: + prevClose = seriesClose + else: + break + dayMap: dict[str, tuple[float, float, float]] = {} + for dayIso in windowDays: + for datedRow in entriesByDay.get(dayIso, []): + positionQty, positionAvg = _apply_entries(positionQty, positionAvg, [datedRow]) # type: ignore[arg-type] + dayClose = closeByIso[dayIso] + if positionQty > 0 and prevClose: + priceDay = (dayClose - prevClose) / prevClose + dividendYield = 0.0 + for earnTicker, exIso, grossValue, _ in earningsSnap: + if earnTicker == ticker and exIso == dayIso: + dividendYield += (grossValue / positionQty) / prevClose + dayMap[dayIso] = (priceDay + dividendYield, priceDay, positionQty * prevClose) + prevClose = dayClose + perTickerDays[ticker] = dayMap + allDays = sorted({dayIso for dayMap in perTickerDays.values() for dayIso in dayMap}) + dailyTotal: list[float] = [] + dailyPrice: list[float] = [] + for dayIso in allDays: + weightTotal = sum(dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) + if weightTotal > 0: + dailyTotal.append( + sum(dayMap[dayIso][0] * dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) + / weightTotal + ) + dailyPrice.append( + sum(dayMap[dayIso][1] * dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) + / weightTotal + ) + twrValue = 1.0 + for dayReturn in dailyTotal: + twrValue *= 1 + dayReturn + twrValue -= 1 + priceValue = 1.0 + for priceDay in dailyPrice: + priceValue *= 1 + priceDay + priceValue -= 1 + spanDays = (dateType.fromisoformat(toIso) - dateType.fromisoformat(fromIso)).days + if spanDays <= 0: + annualizedValue = 0.0 + else: + annualizedValue = (1 + twrValue) ** (365 / spanDays) - 1 + volatilityValue = stdev(dailyTotal) * sqrt(252) if len(dailyTotal) >= 2 else 0.0 + return { + "twr": twrValue, + "twr_annualized": annualizedValue, + "volatility": volatilityValue, + "dividends_received": dividendsReceived, + "price_return": priceValue, + } + + +def get_performance( + db: Session, walletId: int, userId: int, ticker: str | None, startDate: dateType, endDate: dateType +) -> dict: + wallet = _get_owned_wallet(db, walletId, userId) + recalcStamp = wallet.lastRecalc + recalcKey = str(recalcStamp) if recalcStamp is not None else PERFORMANCE_EPOCH + ledgerQuery = db.query(Transaction).filter(Transaction.walletId == walletId) + if ticker: + ledgerQuery = ledgerQuery.filter(Transaction.ticker == ticker) + ledgerRows = ledgerQuery.order_by(Transaction.date, Transaction.entryId).all() + entriesSnap = tuple( + ( + str(ledgerRow.ticker), + str(ledgerRow.date), + str(ledgerRow.side), + float(ledgerRow.quantity), + float(ledgerRow.price), + float(ledgerRow.costs), + int(ledgerRow.entryId), + ) + for ledgerRow in ledgerRows + ) + earningQuery = db.query(Earning).filter(Earning.walletId == walletId) + if ticker: + earningQuery = earningQuery.filter(Earning.ticker == ticker) + earningRows = earningQuery.all() + earningsSnap = tuple( + (str(earningRow.ticker), str(earningRow.exDate), float(earningRow.gross), float(earningRow.netIrAdjusted)) + for earningRow in earningRows + ) + return _cachedPerformance( + walletId, ticker or "", startDate.isoformat(), endDate.isoformat(), recalcKey, entriesSnap, earningsSnap + ) diff --git a/tests/test_wallet_performance.py b/tests/test_wallet_performance.py new file mode 100644 index 00000000..d7ff3363 --- /dev/null +++ b/tests/test_wallet_performance.py @@ -0,0 +1,57 @@ +from datetime import date + +import pytest +import requests + +import main.models.wallet # noqa: F401 +from main.models.wallet import Earning +from tests.conftest import make_wallet_client + + +def _flat_series_with_one_div(url, params=None, headers=None, timeout=None): + class Resp: + status_code = 200 + + @staticmethod + def json(): + rows = [{"DATA": f"{d:02d}-01-2026", "PRECO": 10.0} for d in range(1, 10)] + rows += [{"DATA": "10-01-2026", "PRECO": 10.0}, {"DATA": "11-01-2026", "PRECO": 11.0}] + return {"data": rows} + + return Resp() + + +def test_performance_splits_price_and_dividends(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _flat_series_with_one_div) + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-02", + "quantity": 10, + "price": 10.0, + }, + ) + dbSession.add( + Earning( + walletId=walletId, + ticker="PETR4", + kind="Div", + exDate=date(2026, 1, 5), + payDate=date(2026, 2, 1), + gross=10.0, + netIrAdjusted=10.0, + status="Recebido", + ) + ) + dbSession.commit() + body = client.get(f"/wallet/performance?wallet_id={walletId}&ticker=PETR4&from=2026-01-01&to=2026-01-11").json() + assert body["twr"] == pytest.approx(0.21) + assert body["price_return"] == pytest.approx(0.1) + assert body["dividends_received"] == 10.0 + assert body["volatility"] > 0 From 50bc42ca1ebf9d9480f663b75e3a4018b19057c1 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 22:58:28 -0300 Subject: [PATCH 13/34] move wallet service into app wallet --- .../{service => app/wallet}/wallet_service.py | 78 +++++++++---------- main/controller/wallet_controller.py | 28 +++---- 2 files changed, 53 insertions(+), 53 deletions(-) rename main/{service => app/wallet}/wallet_service.py (90%) diff --git a/main/service/wallet_service.py b/main/app/wallet/wallet_service.py similarity index 90% rename from main/service/wallet_service.py rename to main/app/wallet/wallet_service.py index 401625b3..9b6b0166 100644 --- a/main/service/wallet_service.py +++ b/main/app/wallet/wallet_service.py @@ -29,7 +29,7 @@ } -def create_wallet(db: Session, userId: int, name: str) -> Wallet: +def createWallet(db: Session, userId: int, name: str) -> Wallet: wallet = Wallet(userId=userId, name=name) db.add(wallet) db.commit() @@ -37,7 +37,7 @@ def create_wallet(db: Session, userId: int, name: str) -> Wallet: return wallet -def list_wallets(db: Session, userId: int) -> list[Wallet]: +def listWallets(db: Session, userId: int) -> list[Wallet]: return db.query(Wallet).filter(Wallet.userId == userId).all() @@ -59,7 +59,7 @@ class EntryUpdate(BaseModel): costs: float | None = Field(default=None, ge=0) -def _get_owned_wallet(db: Session, walletId: int, userId: int): +def getOwnedWallet(db: Session, walletId: int, userId: int): from main.app.wallet.auth import requireWalletOwnership wallet = db.query(Wallet).filter(Wallet.walletId == walletId).first() @@ -69,7 +69,7 @@ def _get_owned_wallet(db: Session, walletId: int, userId: int): return wallet -def _apply_entries(quantity: float, avg: float, entries: list[Transaction]) -> tuple[float, float]: +def applyEntries(quantity: float, avg: float, entries: list[Transaction]) -> tuple[float, float]: for entry in entries: entryQuantity = float(entry.quantity) entryPrice = float(entry.price) @@ -85,7 +85,7 @@ def _apply_entries(quantity: float, avg: float, entries: list[Transaction]) -> t return quantity, avg -def recalc_holding(db: Session, walletId: int, ticker: str) -> Holding | None: +def recalcHolding(db: Session, walletId: int, ticker: str) -> Holding | None: entries = ( db.query(Transaction) .filter(Transaction.walletId == walletId, Transaction.ticker == ticker) @@ -97,7 +97,7 @@ def recalc_holding(db: Session, walletId: int, ticker: str) -> Holding | None: if holding is not None: db.delete(holding) return None - quantity, avg = _apply_entries(0.0, 0.0, entries) + quantity, avg = applyEntries(0.0, 0.0, entries) if holding is None: holding = Holding( walletId=walletId, assetType=entries[0].assetType, ticker=ticker, quantity=quantity, avgPrice=avg @@ -109,8 +109,8 @@ def recalc_holding(db: Session, walletId: int, ticker: str) -> Holding | None: return holding -def add_entry(db: Session, userId: int, data: EntryCreate) -> tuple[Transaction, Holding | None]: - _get_owned_wallet(db, data.wallet_id, userId) +def addEntry(db: Session, userId: int, data: EntryCreate) -> tuple[Transaction, Holding | None]: + getOwnedWallet(db, data.wallet_id, userId) if data.side == "Venda": holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() if holding is None or data.quantity > float(holding.quantity): @@ -127,7 +127,7 @@ def add_entry(db: Session, userId: int, data: EntryCreate) -> tuple[Transaction, ) db.add(entry) db.flush() - holding = recalc_holding(db, data.wallet_id, data.ticker) + holding = recalcHolding(db, data.wallet_id, data.ticker) db.commit() db.refresh(entry) if holding is not None: @@ -135,10 +135,10 @@ def add_entry(db: Session, userId: int, data: EntryCreate) -> tuple[Transaction, return entry, holding -def list_entries( +def listEntries( db: Session, userId: int, walletId: int, ticker: str | None = None, limit: int = 20, offset: int = 0 ) -> tuple[int, list[Transaction]]: - _get_owned_wallet(db, walletId, userId) + getOwnedWallet(db, walletId, userId) query = db.query(Transaction).filter(Transaction.walletId == walletId) if ticker is not None: query = query.filter(Transaction.ticker == ticker) @@ -147,18 +147,18 @@ def list_entries( return total, items -def update_entry(db: Session, userId: int, entryId: int, patch: EntryUpdate) -> tuple[Transaction, Holding | None]: +def updateEntry(db: Session, userId: int, entryId: int, patch: EntryUpdate) -> tuple[Transaction, Holding | None]: entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() if entry is None: raise HTTPException(status_code=404, detail="entry not found") - _get_owned_wallet(db, int(entry.walletId), userId) + getOwnedWallet(db, int(entry.walletId), userId) changes = patch.model_dump(exclude_unset=True) for fieldName, fieldValue in changes.items(): if fieldValue is not None: setattr(entry, fieldName, fieldValue) db.flush() try: - holding = recalc_holding(db, int(entry.walletId), str(entry.ticker)) + holding = recalcHolding(db, int(entry.walletId), str(entry.ticker)) except HTTPException: db.rollback() raise @@ -169,17 +169,17 @@ def update_entry(db: Session, userId: int, entryId: int, patch: EntryUpdate) -> return entry, holding -def delete_entry(db: Session, userId: int, entryId: int) -> tuple[int, Holding | None]: +def deleteEntry(db: Session, userId: int, entryId: int) -> tuple[int, Holding | None]: entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() if entry is None: raise HTTPException(status_code=404, detail="entry not found") - _get_owned_wallet(db, int(entry.walletId), userId) + getOwnedWallet(db, int(entry.walletId), userId) walletId = entry.walletId ticker = entry.ticker db.delete(entry) db.flush() try: - holding = recalc_holding(db, int(walletId), str(ticker)) + holding = recalcHolding(db, int(walletId), str(ticker)) except HTTPException: db.rollback() raise @@ -244,8 +244,8 @@ def fetchCachedClose(ticker: str) -> float | None: return None -def get_positions(db: Session, walletId: int, userId: int) -> dict: - _get_owned_wallet(db, walletId, userId) +def getPositions(db: Session, walletId: int, userId: int) -> dict: + getOwnedWallet(db, walletId, userId) holdings = db.query(Holding).filter(Holding.walletId == walletId).all() tickers = [str(holding.ticker) for holding in holdings] prices = fetchLivePrices(tickers) @@ -316,8 +316,8 @@ class RatingUpsert(BaseModel): rating: int = Field(ge=0, le=10) -def get_summary(db: Session, walletId: int, userId: int) -> dict: - wallet = _get_owned_wallet(db, walletId, userId) +def getSummary(db: Session, walletId: int, userId: int) -> dict: + wallet = getOwnedWallet(db, walletId, userId) holdings = db.query(Holding).filter(Holding.walletId == walletId).all() applied = sum(float(holding.quantity) * float(holding.avgPrice) for holding in holdings) tickers = [str(holding.ticker) for holding in holdings] @@ -367,8 +367,8 @@ def get_summary(db: Session, walletId: int, userId: int) -> dict: } -def get_allocation(db: Session, walletId: int, userId: int, groupBy: str) -> dict: - _get_owned_wallet(db, walletId, userId) +def getAllocation(db: Session, walletId: int, userId: int, groupBy: str) -> dict: + getOwnedWallet(db, walletId, userId) holdings = db.query(Holding).filter(Holding.walletId == walletId).all() tickers = [str(holding.ticker) for holding in holdings] prices = fetchLivePrices(tickers) @@ -393,8 +393,8 @@ def get_allocation(db: Session, walletId: int, userId: int, groupBy: str) -> dic return {"items": items, "equity_total": equityTotal} -def upsert_target(db: Session, userId: int, data: TargetUpsert) -> Target: - _get_owned_wallet(db, data.wallet_id, userId) +def upsertTarget(db: Session, userId: int, data: TargetUpsert) -> Target: + getOwnedWallet(db, data.wallet_id, userId) target = ( db.query(Target) .filter( @@ -420,7 +420,7 @@ def upsert_target(db: Session, userId: int, data: TargetUpsert) -> Target: def set_rating(db: Session, userId: int, data: RatingUpsert) -> Holding: - _get_owned_wallet(db, data.wallet_id, userId) + getOwnedWallet(db, data.wallet_id, userId) holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() if holding is None: raise HTTPException(status_code=404, detail="holding not found") @@ -430,10 +430,10 @@ def set_rating(db: Session, userId: int, data: RatingUpsert) -> Holding: return holding -def position_at_date(entries: list[Transaction], exDate: dateType) -> float: +def positionAtDate(entries: list[Transaction], exDate: dateType) -> float: # str() trick: Column-typed dates compare mypy-clean as ISO strings (lexicographic == chronological). datedEntries = [entry for entry in entries if str(entry.date) <= exDate.isoformat()] - quantity, _ = _apply_entries(0.0, 0.0, datedEntries) + quantity, _ = applyEntries(0.0, 0.0, datedEntries) return quantity @@ -455,8 +455,8 @@ def fetchMarketDividends(ticker: str) -> list[dict]: return [] -def sync_earnings(db: Session, walletId: int, userId: int) -> dict: - _get_owned_wallet(db, walletId, userId) +def syncEarnings(db: Session, walletId: int, userId: int) -> dict: + getOwnedWallet(db, walletId, userId) today = dateType.today() accrued = 0 skippedUnknown: list[str] = [] @@ -484,7 +484,7 @@ def sync_earnings(db: Session, walletId: int, userId: int) -> dict: perShare = float(record["VALOR AJUSTADO"]) except Exception: continue - quantityAtEx = position_at_date(ledgerEntries, exDate) + quantityAtEx = positionAtDate(ledgerEntries, exDate) if quantityAtEx <= 0: continue existing = ( @@ -522,8 +522,8 @@ def sync_earnings(db: Session, walletId: int, userId: int) -> dict: return {"accrued": accrued, "transitioned": transitioned, "skipped_unknown": skippedUnknown} -def list_earnings(db: Session, walletId: int, userId: int, status: str | None = None) -> list[Earning]: - _get_owned_wallet(db, walletId, userId) +def listEarnings(db: Session, walletId: int, userId: int, status: str | None = None) -> list[Earning]: + getOwnedWallet(db, walletId, userId) query = db.query(Earning).filter(Earning.walletId == walletId) if status is not None: query = query.filter(Earning.status == status) @@ -556,7 +556,7 @@ def fetchPadraoCloses(ticker: str) -> list[tuple[dateType, float]]: @lru_cache(maxsize=1024) -def _cachedPerformance( +def cachedPerformance( walletId: int, tickerKey: str, fromIso: str, @@ -589,7 +589,7 @@ def _cachedPerformance( for entryIso, entrySide, entryQty, entryPrice, entryCosts in tickerEntries if entryIso < fromIso ] - positionQty, positionAvg = _apply_entries(0.0, 0.0, baselineRows) # type: ignore[arg-type] + positionQty, positionAvg = applyEntries(0.0, 0.0, baselineRows) # type: ignore[arg-type] entriesByDay: dict[str, list] = {} for entryIso, entrySide, entryQty, entryPrice, entryCosts in tickerEntries: if fromIso <= entryIso <= toIso: @@ -611,7 +611,7 @@ def _cachedPerformance( dayMap: dict[str, tuple[float, float, float]] = {} for dayIso in windowDays: for datedRow in entriesByDay.get(dayIso, []): - positionQty, positionAvg = _apply_entries(positionQty, positionAvg, [datedRow]) # type: ignore[arg-type] + positionQty, positionAvg = applyEntries(positionQty, positionAvg, [datedRow]) # type: ignore[arg-type] dayClose = closeByIso[dayIso] if positionQty > 0 and prevClose: priceDay = (dayClose - prevClose) / prevClose @@ -659,10 +659,10 @@ def _cachedPerformance( } -def get_performance( +def getPerformance( db: Session, walletId: int, userId: int, ticker: str | None, startDate: dateType, endDate: dateType ) -> dict: - wallet = _get_owned_wallet(db, walletId, userId) + wallet = getOwnedWallet(db, walletId, userId) recalcStamp = wallet.lastRecalc recalcKey = str(recalcStamp) if recalcStamp is not None else PERFORMANCE_EPOCH ledgerQuery = db.query(Transaction).filter(Transaction.walletId == walletId) @@ -689,6 +689,6 @@ def get_performance( (str(earningRow.ticker), str(earningRow.exDate), float(earningRow.gross), float(earningRow.netIrAdjusted)) for earningRow in earningRows ) - return _cachedPerformance( + return cachedPerformance( walletId, ticker or "", startDate.isoformat(), endDate.isoformat(), recalcKey, entriesSnap, earningsSnap ) diff --git a/main/controller/wallet_controller.py b/main/controller/wallet_controller.py index 301bdb99..9f5dca20 100644 --- a/main/controller/wallet_controller.py +++ b/main/controller/wallet_controller.py @@ -9,7 +9,7 @@ from config import getSession from main.app.wallet.auth import requireWalletUser -from main.service import wallet_service +from main.app.wallet import wallet_service logger = logging.getLogger(__name__) @@ -26,7 +26,7 @@ def create_wallet_route( user: dict = Depends(requireWalletUser), db: Session = Depends(getSession), ): - wallet = wallet_service.create_wallet(db, user["userId"], payload.name) + wallet = wallet_service.createWallet(db, user["userId"], payload.name) return {"walletId": wallet.walletId, "name": wallet.name} @@ -37,7 +37,7 @@ def list_wallets_route( ): return [ {"walletId": walletItem.walletId, "name": walletItem.name, "lastRecalc": walletItem.lastRecalc} - for walletItem in wallet_service.list_wallets(db, user["userId"]) + for walletItem in wallet_service.listWallets(db, user["userId"]) ] @@ -67,7 +67,7 @@ def create_entry_route( user: dict = Depends(requireWalletUser), db: Session = Depends(getSession), ): - entry, holding = wallet_service.add_entry(db, user["userId"], payload) + entry, holding = wallet_service.addEntry(db, user["userId"], payload) return {"entryId": entry.entryId, "holding": serialize_holding(holding)} @@ -80,7 +80,7 @@ def list_entries_route( user: dict = Depends(requireWalletUser), db: Session = Depends(getSession), ): - total, items = wallet_service.list_entries(db, user["userId"], wallet_id, ticker, limit, offset) + total, items = wallet_service.listEntries(db, user["userId"], wallet_id, ticker, limit, offset) return {"total": total, "items": [serialize_entry(item) for item in items]} @@ -91,7 +91,7 @@ def update_entry_route( user: dict = Depends(requireWalletUser), db: Session = Depends(getSession), ): - entry, holding = wallet_service.update_entry(db, user["userId"], entryId, payload) + entry, holding = wallet_service.updateEntry(db, user["userId"], entryId, payload) return {"entryId": entry.entryId, "holding": serialize_holding(holding)} @@ -101,7 +101,7 @@ def delete_entry_route( user: dict = Depends(requireWalletUser), db: Session = Depends(getSession), ): - deletedId, holding = wallet_service.delete_entry(db, user["userId"], entryId) + deletedId, holding = wallet_service.deleteEntry(db, user["userId"], entryId) return {"entryId": deletedId, "holding": serialize_holding(holding)} @@ -111,7 +111,7 @@ def list_positions_route( user: dict = Depends(requireWalletUser), db: Session = Depends(getSession), ): - return wallet_service.get_positions(db, wallet_id, user["userId"]) + return wallet_service.getPositions(db, wallet_id, user["userId"]) @router.get("/summary", response_class=ORJSONResponse) @@ -120,7 +120,7 @@ def get_summary_route( user: dict = Depends(requireWalletUser), db: Session = Depends(getSession), ): - return wallet_service.get_summary(db, wallet_id, user["userId"]) + return wallet_service.getSummary(db, wallet_id, user["userId"]) @router.get("/allocation", response_class=ORJSONResponse) @@ -130,7 +130,7 @@ def get_allocation_route( user: dict = Depends(requireWalletUser), db: Session = Depends(getSession), ): - return wallet_service.get_allocation(db, wallet_id, user["userId"], group_by) + return wallet_service.getAllocation(db, wallet_id, user["userId"], group_by) @router.put("/targets", response_class=ORJSONResponse) @@ -139,7 +139,7 @@ def upsert_target_route( user: dict = Depends(requireWalletUser), db: Session = Depends(getSession), ): - target = wallet_service.upsert_target(db, user["userId"], payload) + target = wallet_service.upsertTarget(db, user["userId"], payload) return { "wallet_id": target.walletId, "key_kind": target.keyKind, @@ -181,7 +181,7 @@ def list_earnings_route( ): return { "items": [ - serialize_earning(item) for item in wallet_service.list_earnings(db, wallet_id, user["userId"], status) + serialize_earning(item) for item in wallet_service.listEarnings(db, wallet_id, user["userId"], status) ] } @@ -192,7 +192,7 @@ def sync_earnings_route( user: dict = Depends(requireWalletUser), db: Session = Depends(getSession), ): - return wallet_service.sync_earnings(db, payload.wallet_id, user["userId"]) + return wallet_service.syncEarnings(db, payload.wallet_id, user["userId"]) @router.get("/performance", response_class=ORJSONResponse) @@ -209,4 +209,4 @@ def get_performance_route( endDate = dateType.fromisoformat(toIso) except ValueError: raise HTTPException(status_code=422, detail="invalid date, expected YYYY-MM-DD") - return wallet_service.get_performance(db, wallet_id, user["userId"], ticker, startDate, endDate) + return wallet_service.getPerformance(db, wallet_id, user["userId"], ticker, startDate, endDate) From 506db6c0496b6d8437162794bc4497814eb31105 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 23:10:15 -0300 Subject: [PATCH 14/34] add orunmila narrate positions tool --- main/app/orunmila/tools.py | 67 ++++++++++++++++++++++++++++ tests/test_orunmila_wallet_tools.py | 69 +++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 tests/test_orunmila_wallet_tools.py diff --git a/main/app/orunmila/tools.py b/main/app/orunmila/tools.py index baba11c8..6ad94a5f 100644 --- a/main/app/orunmila/tools.py +++ b/main/app/orunmila/tools.py @@ -4,6 +4,7 @@ from typing import Any from urllib.parse import quote +from fastapi import HTTPException from forgevm.exceptions import SandboxNotFound from sqlalchemy.orm import Session @@ -176,6 +177,71 @@ async def serve_file(path: str, **_) -> dict: return {"url": url, "markdown": f"[{host.name}]({url})"} +# +# wallet narration (read-only) +# +async def narrate_positions(wallet_id: int, **_) -> dict: + """Narrate the user's wallet positions in plain language. + + Read-only summary of holdings, allocation vs targets, buy signals, + and pending earnings. Never mutates wallet state. + + Args: + wallet_id: Wallet to narrate (must belong to the caller) + """ + from main.app.wallet.wallet_service import getOwnedWallet, getPositions, getSummary, listEarnings + + user = _.get("user") + if not user: + return {"error": "Authentication required"} + + db: Session | None = _.get("db") + ownSession = not db + if ownSession: + db = SessionLocal() + try: + userId = user["userId"] + try: + getOwnedWallet( + db, # type: ignore[arg-type] + wallet_id, + userId, + ) + except HTTPException: + return {"error": "not-owner"} + positionsView = getPositions( + db, # type: ignore[arg-type] + wallet_id, + userId, + ) + summaryView = getSummary( + db, # type: ignore[arg-type] + wallet_id, + userId, + ) + try: + pendingCount = len( + listEarnings( + db, # type: ignore[arg-type] + wallet_id, + userId, + status="A Receber", + ) + ) + except Exception: + pendingCount = 0 + return { + "wallet_id": wallet_id, + "language": user.get("language", "pt-BR"), + "positions": positionsView.get("items", []), + "summary": summaryView, + "pending_earnings": pendingCount, + } + finally: + if ownSession: + db.close() # type: ignore[union-attr] + + TOOL_REGISTRY: dict[str, Any] = { "search_memory": search_memory, "save_memory": save_memory, @@ -184,6 +250,7 @@ async def serve_file(path: str, **_) -> dict: "write_file": write_file, "list_files": list_files, "serve_file": serve_file, + "narrate_positions": narrate_positions, } diff --git a/tests/test_orunmila_wallet_tools.py b/tests/test_orunmila_wallet_tools.py new file mode 100644 index 00000000..7a98296e --- /dev/null +++ b/tests/test_orunmila_wallet_tools.py @@ -0,0 +1,69 @@ +import asyncio +import inspect + +import requests + +from tests.conftest import make_wallet_client +from main.app.orunmila.tools import TOOL_REGISTRY + + +def test_narrate_positions_registered_and_read_only(dbSession): + assert len(TOOL_REGISTRY) == 8 + assert "narrate_positions" in TOOL_REGISTRY + source = inspect.getsource(TOOL_REGISTRY["narrate_positions"]) + for writer in ("addEntry", "updateEntry", "deleteEntry", "upsertTarget", "setRating", "syncEarnings"): + assert writer not in source + + +def _seed_wallet(dbSession): + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-10", + "quantity": 10, + "price": 10.0, + }, + ) + return walletId + + +def _live_ok(url, params=None, headers=None, timeout=None): + class Resp: + status_code = 200 + + @staticmethod + def json(): + return {"data": [{"TICKER": "PETR4", "PRECO ATUAL": 30.0}]} + + return Resp() + + +def test_narrate_positions_returns_read_view(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_ok) + walletId = _seed_wallet(dbSession) + result = asyncio.run( + TOOL_REGISTRY["narrate_positions"](wallet_id=walletId, user={"userId": 1, "language": "pt-BR"}, db=dbSession) + ) + assert result["wallet_id"] == walletId + assert result["language"] == "pt-BR" + assert result["positions"][0]["ticker"] == "PETR4" + assert "summary" in result and "pending_earnings" in result + + +def test_narrate_positions_cross_user_denied(dbSession): + walletId = _seed_wallet(dbSession) + result = asyncio.run( + TOOL_REGISTRY["narrate_positions"](wallet_id=walletId, user={"userId": 2, "language": "pt-BR"}, db=dbSession) + ) + assert result == {"error": "not-owner"} + + +def test_narrate_positions_no_auth_no_data(): + result = asyncio.run(TOOL_REGISTRY["narrate_positions"](wallet_id=1)) + assert result == {"error": "Authentication required"} From f3f675ffde50fd2f351b2240138aa1d335cb55b6 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 23:12:11 -0300 Subject: [PATCH 15/34] tune buy flag with xango assist --- main/app/wallet/wallet_service.py | 71 ++++++++++++++++++++- tests/test_wallet_buy_flag.py | 102 ++++++++++++++++++++++++++++++ tests/test_wallet_summary.py | 4 +- 3 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 tests/test_wallet_buy_flag.py diff --git a/main/app/wallet/wallet_service.py b/main/app/wallet/wallet_service.py index 9b6b0166..c32f7ecd 100644 --- a/main/app/wallet/wallet_service.py +++ b/main/app/wallet/wallet_service.py @@ -28,6 +28,72 @@ "Rend. Tributado": "RendTributado", } +XANGO_WEIGHTS = {"underweight": 0.45, "rating": 0.25, "xango": 0.20, "momentum": 0.10} +BUY_THRESHOLD = 0.5 + + +@lru_cache(maxsize=1024) +def fetchXangoScores(tickers: tuple[str, ...]) -> dict[str, float | None]: + """XANGO quality score per ticker (0-100 scale). + + Stub: no HTTP score endpoint exists on STOCKS yet, so every ticker + returns None and scoreBuyFlag redistributes the xango weight over the + other inputs (flag degrades, never fails). When a real cached-score + surface lands, only this body changes. Shared lru_cache is the + freshness story; no staleness gate beyond it, YAGNI. + """ + return {ticker: None for ticker in tickers} + + +def scoreBuyFlag( + percentWallet: float, + percentIdeal: float | None, + holdingRating: int | None, + xangoScore: float | None, + appreciation: float | None, +) -> bool: + """XANGO-informed buy flag (pure function, deterministic, no learned params). + + percentIdeal arrives on the 0-100 wire scale and is normalized to a + fraction once at the comparison point. A None/NaN xangoScore is skipped + and its weight redistributed proportionally over the other three inputs. + XANGO informs the flag only — it never writes the manual rating. + """ + if percentIdeal is None: + return False + percentIdealFrac = percentIdeal / 100 + underweight = max(0.0, (percentIdealFrac - percentWallet) / max(percentIdealFrac, 1e-9)) + underweight = min(1.0, underweight) + if holdingRating is None: + ratingInput = 0.5 + else: + ratingInput = min(1.0, max(0.0, (holdingRating - 5) / 5)) + if xangoScore is None or xangoScore != xangoScore: # None or NaN → skip input + xangoInput: float | None = None + else: + xangoInput = min(1.0, max(0.0, xangoScore / 100)) + if appreciation is None: + momentumInput = 0.5 + elif appreciation > 0: + momentumInput = 1.0 + elif appreciation < 0: + momentumInput = 0.0 + else: + momentumInput = 0.5 + weights = XANGO_WEIGHTS + if xangoInput is None: + score = ( + weights["underweight"] * underweight + weights["rating"] * ratingInput + weights["momentum"] * momentumInput + ) / (1.0 - weights["xango"]) + else: + score = ( + weights["underweight"] * underweight + + weights["rating"] * ratingInput + + weights["xango"] * xangoInput + + weights["momentum"] * momentumInput + ) + return score >= BUY_THRESHOLD + def createWallet(db: Session, userId: int, name: str) -> Wallet: wallet = Wallet(userId=userId, name=name) @@ -262,6 +328,7 @@ def getPositions(db: Session, walletId: int, userId: int) -> dict: else: equities[str(holding.ticker)] = holdingQuantity * price equityTotal = sum(equity for equity in equities.values() if equity is not None) + xangoScores = fetchXangoScores(tuple(tickers)) items = [] for holding in holdings: holdingQuantity = float(holding.quantity) @@ -284,8 +351,8 @@ def getPositions(db: Session, walletId: int, userId: int) -> dict: ) percentIdeal = float(target.percentIdeal) if target is not None else None holdingRating = holding.rating - buyFlag = ( - percentIdeal is not None and percentWallet < percentIdeal and (holdingRating is None or holdingRating >= 6) + buyFlag = scoreBuyFlag( + percentWallet, percentIdeal, holdingRating, xangoScores.get(str(holding.ticker)), appreciation ) items.append( { diff --git a/tests/test_wallet_buy_flag.py b/tests/test_wallet_buy_flag.py new file mode 100644 index 00000000..a1d51fd9 --- /dev/null +++ b/tests/test_wallet_buy_flag.py @@ -0,0 +1,102 @@ +import hashlib + +import pytest +import requests + +import main.models.wallet # noqa: F401 +import main.app.wallet.wallet_service as wallet_service +from tests.conftest import make_wallet_client +from tests.test_wallet_positions import _live_ok + +RATINGS_ROUTE_DIGEST = "3a9cfe8d634aa3333c2867ef16e8c943313b5a67b6409043698521d5a2b1e686" # sha256 of set_rating_route handler bytes (main/controller/wallet_controller.py:151-158), recorded at plan-review time + + +def test_buy_flag_scale_fixed_and_weights(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_ok) # PETR4 @ 30.0, Task 7 fake + monkeypatch.setattr(wallet_service, "fetchXangoScores", lambda tickers: {"PETR4": 80.0}) + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-10", + "quantity": 10, + "price": 10.0, + }, + ) + client.put( + "/wallet/targets", + json={"wallet_id": walletId, "key_kind": "ticker", "key_value": "PETR4", "percent_ideal": 50.0}, + ) + item = client.get(f"/wallet/positions?wallet_id={walletId}").json()["items"][0] + assert item["percent_wallet"] == pytest.approx(1.0) + assert item["buy_flag"] is False # 100% held vs 50% ideal → overweight, no buy + + +def test_xango_none_degrades_to_p1_rule(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_ok) + monkeypatch.setattr(wallet_service, "fetchXangoScores", lambda tickers: {"PETR4": None}) + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-10", + "quantity": 10, + "price": 10.0, + }, + ) + client.put( + "/wallet/targets", + json={"wallet_id": walletId, "key_kind": "ticker", "key_value": "PETR4", "percent_ideal": 50.0}, + ) + item = client.get(f"/wallet/positions?wallet_id={walletId}").json()["items"][0] + assert item["buy_flag"] is False # same verdict without XANGO — degradation, not failure + + +def test_backtest_fewer_false_flips_than_p1(): + # Seeded checkpoint series: steady climb, 50% ideal, rating 8, XANGO 80. + # flips = checkpoints emitting True. P1 (scale bug: fraction vs 0-100) is True + # at all 5 checkpoints; the tuned flag clears once overweight and stays clear. + checkpoints = [ + {"percentWallet": 0.10, "percentIdeal": 50.0, "holdingRating": 8, "xangoScore": 80.0, "appreciation": 5.0}, + {"percentWallet": 0.30, "percentIdeal": 50.0, "holdingRating": 8, "xangoScore": 80.0, "appreciation": 15.0}, + {"percentWallet": 0.60, "percentIdeal": 50.0, "holdingRating": 8, "xangoScore": 80.0, "appreciation": 40.0}, + {"percentWallet": 0.90, "percentIdeal": 50.0, "holdingRating": 8, "xangoScore": 80.0, "appreciation": 80.0}, + {"percentWallet": 1.00, "percentIdeal": 50.0, "holdingRating": 8, "xangoScore": 80.0, "appreciation": 100.0}, + ] + p1_flags = [ + checkpoint["percentIdeal"] is not None + and checkpoint["percentWallet"] < checkpoint["percentIdeal"] + and (checkpoint["holdingRating"] is None or checkpoint["holdingRating"] >= 6) + for checkpoint in checkpoints + ] + tuned_flags = [ + wallet_service.scoreBuyFlag( + checkpoint["percentWallet"], + checkpoint["percentIdeal"], + checkpoint["holdingRating"], + checkpoint["xangoScore"], + checkpoint["appreciation"], + ) + for checkpoint in checkpoints + ] + p1_flips = sum(1 for flag in p1_flags if flag) + tuned_flips = sum(1 for flag in tuned_flags if flag) + assert p1_flips == 5 # scale bug: always True + assert tuned_flags == [True, True, False, False, False] + assert tuned_flips < p1_flips + + +def test_ratings_route_untouched(): + raw = open("main/controller/wallet_controller.py", "rb").read().splitlines(keepends=True)[150:158] + digest = hashlib.sha256(b"".join(raw)).hexdigest() + assert digest == RATINGS_ROUTE_DIGEST # any edit to set_rating_route fails loudly diff --git a/tests/test_wallet_summary.py b/tests/test_wallet_summary.py index 11f4d5dc..303f3e32 100644 --- a/tests/test_wallet_summary.py +++ b/tests/test_wallet_summary.py @@ -80,4 +80,6 @@ def test_targets_drive_buy_flag_and_ratings_gate(dbSession, monkeypatch): client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 11}).status_code == 422 ) item = client.get(f"/wallet/positions?wallet_id={walletId}").json()["items"][0] - assert item["percent_ideal"] == 80.0 and item["buy_flag"] is True + # P3-1 scale fix: 100% held vs 80% ideal is overweight → no buy + # (old P1 rule compared fraction 1.0 < 80.0, nearly-always-True). + assert item["percent_ideal"] == 80.0 and item["buy_flag"] is False From cdf48db9241f82a01169e0419d128509a7c72a6d Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 23:18:25 -0300 Subject: [PATCH 16/34] fix buy flag mypy fallout --- main/app/wallet/wallet_service.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/main/app/wallet/wallet_service.py b/main/app/wallet/wallet_service.py index c32f7ecd..51433148 100644 --- a/main/app/wallet/wallet_service.py +++ b/main/app/wallet/wallet_service.py @@ -352,7 +352,11 @@ def getPositions(db: Session, walletId: int, userId: int) -> dict: percentIdeal = float(target.percentIdeal) if target is not None else None holdingRating = holding.rating buyFlag = scoreBuyFlag( - percentWallet, percentIdeal, holdingRating, xangoScores.get(str(holding.ticker)), appreciation + percentWallet, + percentIdeal, + holdingRating, # type: ignore[arg-type] + xangoScores.get(str(holding.ticker)), + appreciation, ) items.append( { From 75abc29668b9813e9335645b4d38eb36452d456c Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Wed, 30 Sep 2026 23:38:16 -0300 Subject: [PATCH 17/34] split wallet service into domain modules with container initializer --- main/app/wallet/earnings.py | 109 ++++ main/app/wallet/entries.py | 187 +++++++ main/app/wallet/market_data.py | 107 ++++ main/app/wallet/performance.py | 177 +++++++ main/app/wallet/positions.py | 147 ++++++ main/app/wallet/summary.py | 159 ++++++ main/app/wallet/wallet_service.py | 831 +++--------------------------- main/app/wallet/wallets.py | 30 ++ main/service/user_service.py | 2 - main/service/wallet_service.py | 13 + run.py | 11 +- 11 files changed, 1011 insertions(+), 762 deletions(-) create mode 100644 main/app/wallet/earnings.py create mode 100644 main/app/wallet/entries.py create mode 100644 main/app/wallet/market_data.py create mode 100644 main/app/wallet/performance.py create mode 100644 main/app/wallet/positions.py create mode 100644 main/app/wallet/summary.py create mode 100644 main/app/wallet/wallets.py create mode 100644 main/service/wallet_service.py diff --git a/main/app/wallet/earnings.py b/main/app/wallet/earnings.py new file mode 100644 index 00000000..3b21ba1b --- /dev/null +++ b/main/app/wallet/earnings.py @@ -0,0 +1,109 @@ +import logging +from datetime import date as dateType +from datetime import datetime + +from sqlalchemy.orm import Session + +from main.app.wallet.entries import positionAtDate +from main.app.wallet.market_data import fetchMarketDividends +from main.app.wallet.wallets import getOwnedWallet +from main.models.wallet import Earning, Holding, Transaction + +logger = logging.getLogger(__name__) + +IR_RATE = {"Div": 0.0, "JSCP": 0.15, "RendTributado": 0.15} + +TIPO_MAP = { + "Dividendo": "Div", + "JCP": "JSCP", + "Juros Sobre Capital Proprio": "JSCP", + "Rend. Tributado": "RendTributado", +} + + +def syncEarnings(db: Session, walletId: int, userId: int) -> dict: + getOwnedWallet(db, walletId, userId) + + today = dateType.today() + accrued = 0 + skippedUnknown: list[str] = [] + + holdings = db.query(Holding).filter(Holding.walletId == walletId).all() + for holding in holdings: + if float(holding.quantity) <= 0: + continue + + holdingTicker = str(holding.ticker) + + ledgerEntries = ( + db.query(Transaction) + .filter(Transaction.walletId == walletId, Transaction.ticker == holdingTicker) + .order_by(Transaction.date, Transaction.entryId) + .all() + ) + + for record in fetchMarketDividends(holdingTicker): + label = str(record.get("TIPO PROVENTO")) + kind = TIPO_MAP.get(label) + + if kind is None: + if label not in skippedUnknown: + skippedUnknown.append(label) + continue + + try: + exDate = datetime.strptime(record["DATA COM"], "%d-%m-%Y").date() + payDate = datetime.strptime(record["DATA PAGAMENTO"], "%d-%m-%Y").date() + perShare = float(record["VALOR AJUSTADO"]) + except Exception: + continue + + quantityAtEx = positionAtDate(ledgerEntries, exDate) + if quantityAtEx <= 0: + continue + + existing = ( + db.query(Earning) + .filter( + Earning.walletId == walletId, + Earning.ticker == holdingTicker, + Earning.exDate == exDate, + Earning.kind == kind, + ) + .first() + ) + + if existing is not None: + continue + + gross = perShare * quantityAtEx + earning = Earning( + walletId=walletId, + ticker=holdingTicker, + kind=kind, + exDate=exDate, + payDate=payDate, + gross=gross, + netIrAdjusted=gross * (1 - IR_RATE[kind]), + status="Recebido" if payDate <= today else "A Receber", + ) + + db.add(earning) + + accrued += 1 + transitioned = 0 + pending = db.query(Earning).filter(Earning.walletId == walletId, Earning.status == "A Receber").all() + for earning in pending: + if str(earning.payDate) <= today.isoformat(): + earning.status = "Recebido" # type: ignore[assignment] + transitioned += 1 + db.commit() + return {"accrued": accrued, "transitioned": transitioned, "skipped_unknown": skippedUnknown} + + +def listEarnings(db: Session, walletId: int, userId: int, status: str | None = None) -> list[Earning]: + getOwnedWallet(db, walletId, userId) + query = db.query(Earning).filter(Earning.walletId == walletId) + if status is not None: + query = query.filter(Earning.status == status) + return query.order_by(Earning.exDate, Earning.earningId).all() diff --git a/main/app/wallet/entries.py b/main/app/wallet/entries.py new file mode 100644 index 00000000..a51fcac8 --- /dev/null +++ b/main/app/wallet/entries.py @@ -0,0 +1,187 @@ +import logging +from datetime import date as dateType +from typing import Literal + +from fastapi import HTTPException +from pydantic import BaseModel, Field +from sqlalchemy.orm import Session + +from main.app.wallet.wallets import getOwnedWallet +from main.models.wallet import Holding, Transaction + +logger = logging.getLogger(__name__) + + +class EntryCreate(BaseModel): + wallet_id: int + side: Literal["Compra", "Venda"] + asset_type: str + ticker: str + date: dateType + quantity: float = Field(gt=0) + price: float = Field(ge=0) + costs: float = Field(default=0.0, ge=0) + + +class EntryUpdate(BaseModel): + date: dateType | None = None + quantity: float | None = Field(default=None, gt=0) + price: float | None = Field(default=None, ge=0) + costs: float | None = Field(default=None, ge=0) + + +def applyEntries(quantity: float, avg: float, entries: list[Transaction]) -> tuple[float, float]: + for entry in entries: + entryQuantity = float(entry.quantity) + entryPrice = float(entry.price) + entryCosts = float(entry.costs) + + if entry.side == "Compra": + total = quantity * avg + entryQuantity * entryPrice + entryCosts + quantity += entryQuantity + avg = total / quantity + + else: + if entryQuantity > quantity: + raise HTTPException(status_code=422, detail="sell exceeds holding") + quantity -= entryQuantity + + return quantity, avg + + +def recalcHolding(db: Session, walletId: int, ticker: str) -> Holding | None: + entries = ( + db.query(Transaction) + .filter(Transaction.walletId == walletId, Transaction.ticker == ticker) + .order_by(Transaction.date, Transaction.entryId) + .all() + ) + + holding = db.query(Holding).filter(Holding.walletId == walletId, Holding.ticker == ticker).first() + + if not entries: + if holding is not None: + db.delete(holding) + return None + + quantity, avg = applyEntries(0.0, 0.0, entries) + if holding is None: + holding = Holding( + walletId=walletId, assetType=entries[0].assetType, ticker=ticker, quantity=quantity, avgPrice=avg + ) + + db.add(holding) + else: + holding.quantity = quantity # type: ignore[assignment] + holding.avgPrice = avg # type: ignore[assignment] + + return holding + + +def addEntry(db: Session, userId: int, data: EntryCreate) -> tuple[Transaction, Holding | None]: + getOwnedWallet(db, data.wallet_id, userId) + if data.side == "Venda": + holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() + if holding is None or data.quantity > float(holding.quantity): + raise HTTPException(status_code=422, detail="sell exceeds holding") + + entry = Transaction( + walletId=data.wallet_id, + side=data.side, + assetType=data.asset_type, + ticker=data.ticker, + date=data.date, + quantity=data.quantity, + price=data.price, + costs=data.costs, + ) + + db.add(entry) + db.flush() + + holding = recalcHolding(db, data.wallet_id, data.ticker) + + db.commit() + db.refresh(entry) + + if holding is not None: + db.refresh(holding) + + return entry, holding + + +def listEntries( + db: Session, userId: int, walletId: int, ticker: str | None = None, limit: int = 20, offset: int = 0 +) -> tuple[int, list[Transaction]]: + getOwnedWallet(db, walletId, userId) + query = db.query(Transaction).filter(Transaction.walletId == walletId) + + if ticker is not None: + query = query.filter(Transaction.ticker == ticker) + + total = query.count() + items = query.order_by(Transaction.date, Transaction.entryId).offset(offset).limit(limit).all() + + return total, items + + +def updateEntry(db: Session, userId: int, entryId: int, patch: EntryUpdate) -> tuple[Transaction, Holding | None]: + entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() + + if entry is None: + raise HTTPException(status_code=404, detail="entry not found") + + getOwnedWallet(db, int(entry.walletId), userId) + + changes = patch.model_dump(exclude_unset=True) + for fieldName, fieldValue in changes.items(): + if fieldValue is not None: + setattr(entry, fieldName, fieldValue) + + db.flush() + + try: + holding = recalcHolding(db, int(entry.walletId), str(entry.ticker)) + except HTTPException: + db.rollback() + raise + + db.commit() + db.refresh(entry) + + if holding is not None: + db.refresh(holding) + + return entry, holding + + +def deleteEntry(db: Session, userId: int, entryId: int) -> tuple[int, Holding | None]: + entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() + + if entry is None: + raise HTTPException(status_code=404, detail="entry not found") + + getOwnedWallet(db, int(entry.walletId), userId) + + walletId = entry.walletId + ticker = entry.ticker + + db.delete(entry) + db.flush() + + try: + holding = recalcHolding(db, int(walletId), str(ticker)) + except HTTPException: + db.rollback() + raise + + db.commit() + + return entryId, holding + + +def positionAtDate(entries: list[Transaction], exDate: dateType) -> float: + datedEntries = [entry for entry in entries if str(entry.date) <= exDate.isoformat()] + quantity, _ = applyEntries(0.0, 0.0, datedEntries) + + return quantity diff --git a/main/app/wallet/market_data.py b/main/app/wallet/market_data.py new file mode 100644 index 00000000..7d5ce822 --- /dev/null +++ b/main/app/wallet/market_data.py @@ -0,0 +1,107 @@ +import logging +import os +from concurrent.futures import ThreadPoolExecutor +from datetime import date as dateType +from datetime import datetime + +import requests + +from config import Config + +logger = logging.getLogger(__name__) + +STOCKS_TIMEOUT = 3 + + +def stocksApiBase() -> str: + return f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}" + + +def stocksApiHeaders() -> dict: + key = os.getenv("STOCKS_API_KEY", "") + return {"X-API-Key": key} if key else {} + + +def fetchLivePrices(tickers: list[str]) -> dict[str, float | None]: + if not tickers: + return {} + + def one(ticker: str) -> tuple[str, float | None]: + try: + resp = requests.get( + f"{stocksApiBase()}/stocks/cotations/live", + params={"search": ticker, "compact": False}, # type: ignore[arg-type] + headers=stocksApiHeaders(), + timeout=STOCKS_TIMEOUT, + ) + if resp.status_code == 429: + logger.warning("Live price quota exhausted for %s", ticker) + return ticker, None + if resp.status_code != 200: + return ticker, None + return ticker, float(resp.json()["data"][0]["PRECO ATUAL"]) + except Exception: + return ticker, None + + with ThreadPoolExecutor(max_workers=min(8, max(1, len(tickers)))) as pool: + return dict(pool.map(one, tickers)) + + +def fetchCachedClose(ticker: str) -> float | None: + try: + resp = requests.get( + f"{stocksApiBase()}/stocks/cotations", + params={"search": ticker}, + headers=stocksApiHeaders(), + timeout=STOCKS_TIMEOUT, + ) + if resp.status_code == 429: + logger.warning("Cached close quota exhausted for %s", ticker) + return None + if resp.status_code != 200: + return None + rows = resp.json()["data"] + latest = max(rows, key=lambda row: datetime.strptime(row["DATA"], "%d-%m-%Y")) + return float(latest["PRECO"]) + except Exception: + return None + + +def fetchMarketDividends(ticker: str) -> list[dict]: + try: + resp = requests.get( + f"{stocksApiBase()}/stocks/fundamental", + params={"search": ticker, "fields": "HISTORICO DIVIDENDOS"}, # type: ignore[arg-type] + headers=stocksApiHeaders(), + timeout=STOCKS_TIMEOUT, + ) + if resp.status_code != 200: + return [] + payload = resp.json()["data"] + if payload and isinstance(payload[0], dict) and "HISTORICO DIVIDENDOS" in payload[0]: + return payload[0]["HISTORICO DIVIDENDOS"] + return payload + except Exception: + return [] + + +def fetchPadraoCloses(ticker: str) -> list[tuple[dateType, float]]: + try: + resp = requests.get( + f"{stocksApiBase()}/stocks/cotations", + params={"search": ticker}, + headers=stocksApiHeaders(), + timeout=STOCKS_TIMEOUT, + ) + if resp.status_code != 200: + return [] + parsedCloses: list[tuple[dateType, float]] = [] + for closeRow in resp.json()["data"]: + try: + parsedCloses.append((datetime.strptime(closeRow["DATA"], "%d-%m-%Y").date(), float(closeRow["PRECO"]))) + except Exception: + continue + parsedCloses.sort(key=lambda closeItem: closeItem[0]) + return parsedCloses + except Exception: + return [] diff --git a/main/app/wallet/performance.py b/main/app/wallet/performance.py new file mode 100644 index 00000000..3534a0fb --- /dev/null +++ b/main/app/wallet/performance.py @@ -0,0 +1,177 @@ +import logging +from datetime import date as dateType +from functools import lru_cache +from math import sqrt +from statistics import stdev +from types import SimpleNamespace + +from sqlalchemy.orm import Session + +from main.app.wallet.entries import applyEntries +from main.app.wallet.market_data import fetchPadraoCloses +from main.app.wallet.wallets import getOwnedWallet +from main.models.wallet import Earning, Transaction + +logger = logging.getLogger(__name__) + +PERFORMANCE_EPOCH = "1970-01-01T00:00:00" + + +@lru_cache(maxsize=1024) +def cachedPerformance( + walletId: int, + tickerKey: str, + fromIso: str, + toIso: str, + recalcKey: str, + entriesSnap: tuple[tuple[str, str, str, float, float, float, int], ...], + earningsSnap: tuple[tuple[str, str, float, float], ...], +) -> dict: + del recalcKey + + if tickerKey: + tickers = [tickerKey] + else: + universe = {entryTicker for entryTicker, _, _, _, _, _, _ in entriesSnap} + universe.update(earnTicker for earnTicker, _, _, _ in earningsSnap) + tickers = sorted(universe) + + perTickerDays: dict[str, dict[str, tuple[float, float, float]]] = {} + + dividendsReceived = 0.0 + for ticker in tickers: + for earnTicker, exIso, _, netValue in earningsSnap: + if earnTicker == ticker and fromIso <= exIso <= toIso: + dividendsReceived += netValue + + series = fetchPadraoCloses(ticker) + + tickerEntries = [ + (entryIso, entrySide, entryQty, entryPrice, entryCosts) + for entryTicker, entryIso, entrySide, entryQty, entryPrice, entryCosts, _ in entriesSnap + if entryTicker == ticker + ] + + baselineRows = [ + SimpleNamespace(side=entrySide, quantity=entryQty, price=entryPrice, costs=entryCosts) + for entryIso, entrySide, entryQty, entryPrice, entryCosts in tickerEntries + if entryIso < fromIso + ] + + positionQty, positionAvg = applyEntries(0.0, 0.0, baselineRows) # type: ignore[arg-type] + + entriesByDay: dict[str, list] = {} + for entryIso, entrySide, entryQty, entryPrice, entryCosts in tickerEntries: + if fromIso <= entryIso <= toIso: + entriesByDay.setdefault(entryIso, []).append( + SimpleNamespace(side=entrySide, quantity=entryQty, price=entryPrice, costs=entryCosts) + ) + + closeByIso = { + closeDay.isoformat(): closePrice + for closeDay, closePrice in series + if fromIso <= closeDay.isoformat() <= toIso + } + + windowDays = sorted(closeByIso) + prevClose = None + for seriesDay, seriesClose in series: + if seriesDay.isoformat() < fromIso: + prevClose = seriesClose + else: + break + + dayMap: dict[str, tuple[float, float, float]] = {} + for dayIso in windowDays: + for datedRow in entriesByDay.get(dayIso, []): + positionQty, positionAvg = applyEntries(positionQty, positionAvg, [datedRow]) # type: ignore[arg-type] + dayClose = closeByIso[dayIso] + + if positionQty > 0 and prevClose: + priceDay = (dayClose - prevClose) / prevClose + dividendYield = 0.0 + + for earnTicker, exIso, grossValue, _ in earningsSnap: + if earnTicker == ticker and exIso == dayIso: + dividendYield += (grossValue / positionQty) / prevClose + dayMap[dayIso] = (priceDay + dividendYield, priceDay, positionQty * prevClose) + + prevClose = dayClose + perTickerDays[ticker] = dayMap + + allDays = sorted({dayIso for dayMap in perTickerDays.values() for dayIso in dayMap}) + + dailyTotal: list[float] = [] + dailyPrice: list[float] = [] + for dayIso in allDays: + weightTotal = sum(dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) + if weightTotal > 0: + dailyTotal.append( + sum(dayMap[dayIso][0] * dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) + / weightTotal + ) + dailyPrice.append( + sum(dayMap[dayIso][1] * dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) + / weightTotal + ) + + twrValue = 1.0 + for dayReturn in dailyTotal: + twrValue *= 1 + dayReturn + + twrValue -= 1 + priceValue = 1.0 + for priceDay in dailyPrice: + priceValue *= 1 + priceDay + + priceValue -= 1 + spanDays = (dateType.fromisoformat(toIso) - dateType.fromisoformat(fromIso)).days + if spanDays <= 0: + annualizedValue = 0.0 + else: + annualizedValue = (1 + twrValue) ** (365 / spanDays) - 1 + + volatilityValue = stdev(dailyTotal) * sqrt(252) if len(dailyTotal) >= 2 else 0.0 + + return { + "twr": twrValue, + "twr_annualized": annualizedValue, + "volatility": volatilityValue, + "dividends_received": dividendsReceived, + "price_return": priceValue, + } + + +def getPerformance( + db: Session, walletId: int, userId: int, ticker: str | None, startDate: dateType, endDate: dateType +) -> dict: + wallet = getOwnedWallet(db, walletId, userId) + recalcStamp = wallet.lastRecalc + recalcKey = str(recalcStamp) if recalcStamp is not None else PERFORMANCE_EPOCH + ledgerQuery = db.query(Transaction).filter(Transaction.walletId == walletId) + if ticker: + ledgerQuery = ledgerQuery.filter(Transaction.ticker == ticker) + ledgerRows = ledgerQuery.order_by(Transaction.date, Transaction.entryId).all() + entriesSnap = tuple( + ( + str(ledgerRow.ticker), + str(ledgerRow.date), + str(ledgerRow.side), + float(ledgerRow.quantity), + float(ledgerRow.price), + float(ledgerRow.costs), + int(ledgerRow.entryId), + ) + for ledgerRow in ledgerRows + ) + earningQuery = db.query(Earning).filter(Earning.walletId == walletId) + if ticker: + earningQuery = earningQuery.filter(Earning.ticker == ticker) + earningRows = earningQuery.all() + earningsSnap = tuple( + (str(earningRow.ticker), str(earningRow.exDate), float(earningRow.gross), float(earningRow.netIrAdjusted)) + for earningRow in earningRows + ) + return cachedPerformance( + walletId, ticker or "", startDate.isoformat(), endDate.isoformat(), recalcKey, entriesSnap, earningsSnap + ) diff --git a/main/app/wallet/positions.py b/main/app/wallet/positions.py new file mode 100644 index 00000000..a3a1a84f --- /dev/null +++ b/main/app/wallet/positions.py @@ -0,0 +1,147 @@ +import logging +from functools import lru_cache + +from sqlalchemy.orm import Session + +from main.app.wallet.market_data import fetchCachedClose, fetchLivePrices +from main.app.wallet.wallets import getOwnedWallet +from main.models.wallet import Holding, Target + +logger = logging.getLogger(__name__) + +XANGO_WEIGHTS = {"underweight": 0.45, "rating": 0.25, "xango": 0.20, "momentum": 0.10} +BUY_THRESHOLD = 0.5 + + +@lru_cache(maxsize=1024) +def fetchXangoScores(tickers: tuple[str, ...]) -> dict[str, float | None]: + """XANGO quality score per ticker (0-100 scale). + + Stub: no HTTP score endpoint exists on STOCKS yet, so every ticker + returns None and scoreBuyFlag redistributes the xango weight over the + other inputs (flag degrades, never fails). When a real cached-score + surface lands, only this body changes. Shared lru_cache is the + freshness story; no staleness gate beyond it, YAGNI. + """ + return {ticker: None for ticker in tickers} + + +def scoreBuyFlag( + percentWallet: float, + percentIdeal: float | None, + holdingRating: int | None, + xangoScore: float | None, + appreciation: float | None, +) -> bool: + """XANGO-informed buy flag (pure function, deterministic, no learned params). + + percentIdeal arrives on the 0-100 wire scale and is normalized to a + fraction once at the comparison point. A None/NaN xangoScore is skipped + and its weight redistributed proportionally over the other three inputs. + XANGO informs the flag only — it never writes the manual rating. + """ + if percentIdeal is None: + return False + percentIdealFrac = percentIdeal / 100 + underweight = max(0.0, (percentIdealFrac - percentWallet) / max(percentIdealFrac, 1e-9)) + underweight = min(1.0, underweight) + if holdingRating is None: + ratingInput = 0.5 + else: + ratingInput = min(1.0, max(0.0, (holdingRating - 5) / 5)) + if xangoScore is None or xangoScore != xangoScore: # None or NaN → skip input + xangoInput: float | None = None + else: + xangoInput = min(1.0, max(0.0, xangoScore / 100)) + if appreciation is None: + momentumInput = 0.5 + elif appreciation > 0: + momentumInput = 1.0 + elif appreciation < 0: + momentumInput = 0.0 + else: + momentumInput = 0.5 + weights = XANGO_WEIGHTS + if xangoInput is None: + score = ( + weights["underweight"] * underweight + weights["rating"] * ratingInput + weights["momentum"] * momentumInput + ) / (1.0 - weights["xango"]) + else: + score = ( + weights["underweight"] * underweight + + weights["rating"] * ratingInput + + weights["xango"] * xangoInput + + weights["momentum"] * momentumInput + ) + return score >= BUY_THRESHOLD + + +def getPositions(db: Session, walletId: int, userId: int) -> dict: + getOwnedWallet(db, walletId, userId) + holdings = db.query(Holding).filter(Holding.walletId == walletId).all() + + tickers = [str(holding.ticker) for holding in holdings] + prices = fetchLivePrices(tickers) + for ticker, price in list(prices.items()): + if price is None: + prices[ticker] = fetchCachedClose(ticker) + + equities: dict[str, float | None] = {} + for holding in holdings: + holdingQuantity = float(holding.quantity) + holdingAvg = float(holding.avgPrice) + price = prices.get(str(holding.ticker)) + + if price is None: + equities[str(holding.ticker)] = None + else: + equities[str(holding.ticker)] = holdingQuantity * price + + equityTotal = sum(equity for equity in equities.values() if equity is not None) + xangoScores = fetchXangoScores(tuple(tickers)) + + items = [] + for holding in holdings: + holdingQuantity = float(holding.quantity) + holdingAvg = float(holding.avgPrice) + price = prices.get(str(holding.ticker)) + equity = equities[str(holding.ticker)] + + if price is None or equity is None: + currentPrice = None + equityValue = None + appreciation = None + else: + currentPrice = price + equityValue = equity + appreciation = equity - holdingQuantity * holdingAvg + + percentWallet = (equity / equityTotal) if equity is not None and equityTotal else 0 + target = ( + db.query(Target) + .filter(Target.walletId == walletId, Target.keyKind == "ticker", Target.keyValue == holding.ticker) + .first() + ) + percentIdeal = float(target.percentIdeal) if target is not None else None + holdingRating = holding.rating + buyFlag = scoreBuyFlag( + percentWallet, + percentIdeal, + holdingRating, # type: ignore[arg-type] + xangoScores.get(str(holding.ticker)), + appreciation, + ) + items.append( + { + "ticker": holding.ticker, + "quantity": holdingQuantity, + "avgPrice": holdingAvg, + "current_price": currentPrice, + "equity": equityValue, + "appreciation": appreciation, + "percent_wallet": percentWallet, + "percent_ideal": percentIdeal, + "buy_flag": buyFlag, + } + ) + return {"items": items, "equity_total": equityTotal} diff --git a/main/app/wallet/summary.py b/main/app/wallet/summary.py new file mode 100644 index 00000000..4b671f95 --- /dev/null +++ b/main/app/wallet/summary.py @@ -0,0 +1,159 @@ +import logging +from datetime import date as dateType +from datetime import datetime +from typing import Literal + +from fastapi import HTTPException +from pydantic import BaseModel, Field +from sqlalchemy.orm import Session + +from main.app.wallet.market_data import fetchCachedClose, fetchLivePrices +from main.app.wallet.wallets import getOwnedWallet +from main.models.wallet import Holding, Snapshot, Target + +logger = logging.getLogger(__name__) + + +class TargetUpsert(BaseModel): + wallet_id: int + key_kind: Literal["ticker", "group"] + key_value: str + percent_ideal: float = Field(ge=0, le=100) + + +class RatingUpsert(BaseModel): + wallet_id: int + ticker: str + rating: int = Field(ge=0, le=10) + + +def getSummary(db: Session, walletId: int, userId: int) -> dict: + wallet = getOwnedWallet(db, walletId, userId) + holdings = db.query(Holding).filter(Holding.walletId == walletId).all() + applied = sum(float(holding.quantity) * float(holding.avgPrice) for holding in holdings) + tickers = [str(holding.ticker) for holding in holdings] + prices = fetchLivePrices(tickers) + + for ticker, price in list(prices.items()): + if price is None: + prices[ticker] = fetchCachedClose(ticker) + + equity = 0.0 + for holding in holdings: + price = prices.get(str(holding.ticker)) + if price is not None: + equity += float(holding.quantity) * price + variation = equity - applied + + today = dateType.today() + + snapshot = db.query(Snapshot).filter(Snapshot.walletId == walletId, Snapshot.date == today).first() + if snapshot is None: + snapshot = Snapshot( + walletId=walletId, + date=today, + applied=applied, + equity=equity, + variation=variation, + profitTwr=None, + profitAmount=variation, + profitTwr12m=None, + profitTwr12mAmount=variation, + ) + db.add(snapshot) + else: + snapshot.applied = applied # type: ignore[assignment] + snapshot.equity = equity # type: ignore[assignment] + snapshot.variation = variation # type: ignore[assignment] + snapshot.profitTwr = None # type: ignore[assignment] + snapshot.profitAmount = variation # type: ignore[assignment] + snapshot.profitTwr12m = None # type: ignore[assignment] + snapshot.profitTwr12mAmount = variation # type: ignore[assignment] + + wallet.lastRecalc = datetime.now() + + db.commit() + + return { + "applied": applied, + "equity": equity, + "variation": variation, + "profit_twr": None, + "profit_amount": variation, + "profit_twr_12m": None, + "profit_twr_12m_amount": variation, + } + + +def getAllocation(db: Session, walletId: int, userId: int, groupBy: str) -> dict: + getOwnedWallet(db, walletId, userId) + holdings = db.query(Holding).filter(Holding.walletId == walletId).all() + + tickers = [str(holding.ticker) for holding in holdings] + prices = fetchLivePrices(tickers) + for ticker, price in list(prices.items()): + if price is None: + prices[ticker] = fetchCachedClose(ticker) + + groupEquity: dict[str, float] = {} + for holding in holdings: + price = prices.get(str(holding.ticker)) + holdingEquity = float(holding.quantity) * price if price is not None else 0.0 + groupKey = str(holding.ticker) if groupBy == "ticker" else str(holding.assetType) + groupEquity[groupKey] = groupEquity.get(groupKey, 0.0) + holdingEquity + + equityTotal = sum(groupEquity.values()) + items = [ + { + "key": groupKey, + "equity": groupValue, + "pct": (groupValue / equityTotal) if equityTotal else 0, + } + for groupKey, groupValue in groupEquity.items() + ] + + return {"items": items, "equity_total": equityTotal} + + +def upsertTarget(db: Session, userId: int, data: TargetUpsert) -> Target: + getOwnedWallet(db, data.wallet_id, userId) + target = ( + db.query(Target) + .filter( + Target.walletId == data.wallet_id, + Target.keyKind == data.key_kind, + Target.keyValue == data.key_value, + ) + .first() + ) + + if target is None: + target = Target( + walletId=data.wallet_id, + keyKind=data.key_kind, + keyValue=data.key_value, + percentIdeal=data.percent_ideal, + ) + db.add(target) + else: + target.percentIdeal = data.percent_ideal # type: ignore[assignment] + + db.commit() + db.refresh(target) + + return target + + +def set_rating(db: Session, userId: int, data: RatingUpsert) -> Holding: + getOwnedWallet(db, data.wallet_id, userId) + holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() + + if holding is None: + raise HTTPException(status_code=404, detail="holding not found") + + holding.rating = data.rating # type: ignore[assignment] + + db.commit() + db.refresh(holding) + + return holding diff --git a/main/app/wallet/wallet_service.py b/main/app/wallet/wallet_service.py index 51433148..a75169f1 100644 --- a/main/app/wallet/wallet_service.py +++ b/main/app/wallet/wallet_service.py @@ -1,765 +1,78 @@ import logging -import os -from concurrent.futures import ThreadPoolExecutor from datetime import date as dateType -from datetime import datetime -from functools import lru_cache -from math import sqrt -from statistics import stdev -from types import SimpleNamespace -from typing import Literal -import requests -from fastapi import HTTPException -from pydantic import BaseModel, Field -from sqlalchemy.orm import Session - -from config import Config -from main.models.wallet import Earning, Holding, Snapshot, Target, Transaction, Wallet +from main.app.wallet.earnings import IR_RATE, TIPO_MAP, listEarnings, syncEarnings +from main.app.wallet.entries import ( + EntryCreate, + EntryUpdate, + addEntry, + applyEntries, + deleteEntry, + listEntries, + positionAtDate, + recalcHolding, + updateEntry, +) +from main.app.wallet.market_data import ( + STOCKS_TIMEOUT, + fetchCachedClose, + fetchLivePrices, + fetchMarketDividends, + fetchPadraoCloses, + stocksApiBase, + stocksApiHeaders, +) +from main.app.wallet.performance import PERFORMANCE_EPOCH, cachedPerformance, getPerformance +from main.app.wallet.positions import BUY_THRESHOLD, XANGO_WEIGHTS, fetchXangoScores, getPositions, scoreBuyFlag +from main.app.wallet.summary import ( + RatingUpsert, + TargetUpsert, + getAllocation, + getSummary, + set_rating, + upsertTarget, +) +from main.app.wallet.wallets import createWallet, getOwnedWallet, listWallets logger = logging.getLogger(__name__) -IR_RATE = {"Div": 0.0, "JSCP": 0.15, "RendTributado": 0.15} - -TIPO_MAP = { - "Dividendo": "Div", - "JCP": "JSCP", - "Juros Sobre Capital Proprio": "JSCP", - "Rend. Tributado": "RendTributado", -} - -XANGO_WEIGHTS = {"underweight": 0.45, "rating": 0.25, "xango": 0.20, "momentum": 0.10} -BUY_THRESHOLD = 0.5 - - -@lru_cache(maxsize=1024) -def fetchXangoScores(tickers: tuple[str, ...]) -> dict[str, float | None]: - """XANGO quality score per ticker (0-100 scale). - - Stub: no HTTP score endpoint exists on STOCKS yet, so every ticker - returns None and scoreBuyFlag redistributes the xango weight over the - other inputs (flag degrades, never fails). When a real cached-score - surface lands, only this body changes. Shared lru_cache is the - freshness story; no staleness gate beyond it, YAGNI. - """ - return {ticker: None for ticker in tickers} - - -def scoreBuyFlag( - percentWallet: float, - percentIdeal: float | None, - holdingRating: int | None, - xangoScore: float | None, - appreciation: float | None, -) -> bool: - """XANGO-informed buy flag (pure function, deterministic, no learned params). - - percentIdeal arrives on the 0-100 wire scale and is normalized to a - fraction once at the comparison point. A None/NaN xangoScore is skipped - and its weight redistributed proportionally over the other three inputs. - XANGO informs the flag only — it never writes the manual rating. - """ - if percentIdeal is None: - return False - percentIdealFrac = percentIdeal / 100 - underweight = max(0.0, (percentIdealFrac - percentWallet) / max(percentIdealFrac, 1e-9)) - underweight = min(1.0, underweight) - if holdingRating is None: - ratingInput = 0.5 - else: - ratingInput = min(1.0, max(0.0, (holdingRating - 5) / 5)) - if xangoScore is None or xangoScore != xangoScore: # None or NaN → skip input - xangoInput: float | None = None - else: - xangoInput = min(1.0, max(0.0, xangoScore / 100)) - if appreciation is None: - momentumInput = 0.5 - elif appreciation > 0: - momentumInput = 1.0 - elif appreciation < 0: - momentumInput = 0.0 - else: - momentumInput = 0.5 - weights = XANGO_WEIGHTS - if xangoInput is None: - score = ( - weights["underweight"] * underweight + weights["rating"] * ratingInput + weights["momentum"] * momentumInput - ) / (1.0 - weights["xango"]) - else: - score = ( - weights["underweight"] * underweight - + weights["rating"] * ratingInput - + weights["xango"] * xangoInput - + weights["momentum"] * momentumInput - ) - return score >= BUY_THRESHOLD - - -def createWallet(db: Session, userId: int, name: str) -> Wallet: - wallet = Wallet(userId=userId, name=name) - db.add(wallet) - db.commit() - db.refresh(wallet) - return wallet - - -def listWallets(db: Session, userId: int) -> list[Wallet]: - return db.query(Wallet).filter(Wallet.userId == userId).all() - - -class EntryCreate(BaseModel): - wallet_id: int - side: Literal["Compra", "Venda"] - asset_type: str - ticker: str - date: dateType - quantity: float = Field(gt=0) - price: float = Field(ge=0) - costs: float = Field(default=0.0, ge=0) - - -class EntryUpdate(BaseModel): - date: dateType | None = None - quantity: float | None = Field(default=None, gt=0) - price: float | None = Field(default=None, ge=0) - costs: float | None = Field(default=None, ge=0) - - -def getOwnedWallet(db: Session, walletId: int, userId: int): - from main.app.wallet.auth import requireWalletOwnership - - wallet = db.query(Wallet).filter(Wallet.walletId == walletId).first() - if wallet is None: - raise HTTPException(status_code=404, detail="wallet not found") - requireWalletOwnership(int(wallet.userId), {"userId": userId}) - return wallet - - -def applyEntries(quantity: float, avg: float, entries: list[Transaction]) -> tuple[float, float]: - for entry in entries: - entryQuantity = float(entry.quantity) - entryPrice = float(entry.price) - entryCosts = float(entry.costs) - if entry.side == "Compra": - total = quantity * avg + entryQuantity * entryPrice + entryCosts - quantity += entryQuantity - avg = total / quantity - else: - if entryQuantity > quantity: - raise HTTPException(status_code=422, detail="sell exceeds holding") - quantity -= entryQuantity - return quantity, avg - - -def recalcHolding(db: Session, walletId: int, ticker: str) -> Holding | None: - entries = ( - db.query(Transaction) - .filter(Transaction.walletId == walletId, Transaction.ticker == ticker) - .order_by(Transaction.date, Transaction.entryId) - .all() - ) - holding = db.query(Holding).filter(Holding.walletId == walletId, Holding.ticker == ticker).first() - if not entries: - if holding is not None: - db.delete(holding) - return None - quantity, avg = applyEntries(0.0, 0.0, entries) - if holding is None: - holding = Holding( - walletId=walletId, assetType=entries[0].assetType, ticker=ticker, quantity=quantity, avgPrice=avg - ) - db.add(holding) - else: - holding.quantity = quantity # type: ignore[assignment] - holding.avgPrice = avg # type: ignore[assignment] - return holding - - -def addEntry(db: Session, userId: int, data: EntryCreate) -> tuple[Transaction, Holding | None]: - getOwnedWallet(db, data.wallet_id, userId) - if data.side == "Venda": - holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() - if holding is None or data.quantity > float(holding.quantity): - raise HTTPException(status_code=422, detail="sell exceeds holding") - entry = Transaction( - walletId=data.wallet_id, - side=data.side, - assetType=data.asset_type, - ticker=data.ticker, - date=data.date, - quantity=data.quantity, - price=data.price, - costs=data.costs, - ) - db.add(entry) - db.flush() - holding = recalcHolding(db, data.wallet_id, data.ticker) - db.commit() - db.refresh(entry) - if holding is not None: - db.refresh(holding) - return entry, holding - - -def listEntries( - db: Session, userId: int, walletId: int, ticker: str | None = None, limit: int = 20, offset: int = 0 -) -> tuple[int, list[Transaction]]: - getOwnedWallet(db, walletId, userId) - query = db.query(Transaction).filter(Transaction.walletId == walletId) - if ticker is not None: - query = query.filter(Transaction.ticker == ticker) - total = query.count() - items = query.order_by(Transaction.date, Transaction.entryId).offset(offset).limit(limit).all() - return total, items - - -def updateEntry(db: Session, userId: int, entryId: int, patch: EntryUpdate) -> tuple[Transaction, Holding | None]: - entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() - if entry is None: - raise HTTPException(status_code=404, detail="entry not found") - getOwnedWallet(db, int(entry.walletId), userId) - changes = patch.model_dump(exclude_unset=True) - for fieldName, fieldValue in changes.items(): - if fieldValue is not None: - setattr(entry, fieldName, fieldValue) - db.flush() - try: - holding = recalcHolding(db, int(entry.walletId), str(entry.ticker)) - except HTTPException: - db.rollback() - raise - db.commit() - db.refresh(entry) - if holding is not None: - db.refresh(holding) - return entry, holding - - -def deleteEntry(db: Session, userId: int, entryId: int) -> tuple[int, Holding | None]: - entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() - if entry is None: - raise HTTPException(status_code=404, detail="entry not found") - getOwnedWallet(db, int(entry.walletId), userId) - walletId = entry.walletId - ticker = entry.ticker - db.delete(entry) - db.flush() - try: - holding = recalcHolding(db, int(walletId), str(ticker)) - except HTTPException: - db.rollback() - raise - db.commit() - return entryId, holding - - -STOCKS_TIMEOUT = 3 - - -def stocksApiBase() -> str: - return f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}" - - -def stocksApiHeaders() -> dict: - key = os.getenv("STOCKS_API_KEY", "") - return {"X-API-Key": key} if key else {} - - -def fetchLivePrices(tickers: list[str]) -> dict[str, float | None]: - if not tickers: - return {} - - def one(ticker: str) -> tuple[str, float | None]: - try: - resp = requests.get( - f"{stocksApiBase()}/stocks/cotations/live", - params={"search": ticker, "compact": False}, # type: ignore[arg-type] - headers=stocksApiHeaders(), - timeout=STOCKS_TIMEOUT, - ) - if resp.status_code == 429: - logger.warning("Live price quota exhausted for %s", ticker) - return ticker, None - if resp.status_code != 200: - return ticker, None - return ticker, float(resp.json()["data"][0]["PRECO ATUAL"]) - except Exception: - return ticker, None - - with ThreadPoolExecutor(max_workers=min(8, max(1, len(tickers)))) as pool: - return dict(pool.map(one, tickers)) - - -def fetchCachedClose(ticker: str) -> float | None: - try: - resp = requests.get( - f"{stocksApiBase()}/stocks/cotations", - params={"search": ticker}, - headers=stocksApiHeaders(), - timeout=STOCKS_TIMEOUT, - ) - if resp.status_code == 429: - logger.warning("Cached close quota exhausted for %s", ticker) - return None - if resp.status_code != 200: - return None - rows = resp.json()["data"] - latest = max(rows, key=lambda row: datetime.strptime(row["DATA"], "%d-%m-%Y")) - return float(latest["PRECO"]) - except Exception: - return None - - -def getPositions(db: Session, walletId: int, userId: int) -> dict: - getOwnedWallet(db, walletId, userId) - holdings = db.query(Holding).filter(Holding.walletId == walletId).all() - tickers = [str(holding.ticker) for holding in holdings] - prices = fetchLivePrices(tickers) - for ticker, price in list(prices.items()): - if price is None: - prices[ticker] = fetchCachedClose(ticker) - equities: dict[str, float | None] = {} - for holding in holdings: - holdingQuantity = float(holding.quantity) - holdingAvg = float(holding.avgPrice) - price = prices.get(str(holding.ticker)) - if price is None: - equities[str(holding.ticker)] = None - else: - equities[str(holding.ticker)] = holdingQuantity * price - equityTotal = sum(equity for equity in equities.values() if equity is not None) - xangoScores = fetchXangoScores(tuple(tickers)) - items = [] - for holding in holdings: - holdingQuantity = float(holding.quantity) - holdingAvg = float(holding.avgPrice) - price = prices.get(str(holding.ticker)) - equity = equities[str(holding.ticker)] - if price is None or equity is None: - currentPrice = None - equityValue = None - appreciation = None - else: - currentPrice = price - equityValue = equity - appreciation = equity - holdingQuantity * holdingAvg - percentWallet = (equity / equityTotal) if equity is not None and equityTotal else 0 - target = ( - db.query(Target) - .filter(Target.walletId == walletId, Target.keyKind == "ticker", Target.keyValue == holding.ticker) - .first() - ) - percentIdeal = float(target.percentIdeal) if target is not None else None - holdingRating = holding.rating - buyFlag = scoreBuyFlag( - percentWallet, - percentIdeal, - holdingRating, # type: ignore[arg-type] - xangoScores.get(str(holding.ticker)), - appreciation, - ) - items.append( - { - "ticker": holding.ticker, - "quantity": holdingQuantity, - "avgPrice": holdingAvg, - "current_price": currentPrice, - "equity": equityValue, - "appreciation": appreciation, - "percent_wallet": percentWallet, - "percent_ideal": percentIdeal, - "buy_flag": buyFlag, - } - ) - return {"items": items, "equity_total": equityTotal} - - -class TargetUpsert(BaseModel): - wallet_id: int - key_kind: Literal["ticker", "group"] - key_value: str - percent_ideal: float = Field(ge=0, le=100) - - -class RatingUpsert(BaseModel): - wallet_id: int - ticker: str - rating: int = Field(ge=0, le=10) - - -def getSummary(db: Session, walletId: int, userId: int) -> dict: - wallet = getOwnedWallet(db, walletId, userId) - holdings = db.query(Holding).filter(Holding.walletId == walletId).all() - applied = sum(float(holding.quantity) * float(holding.avgPrice) for holding in holdings) - tickers = [str(holding.ticker) for holding in holdings] - prices = fetchLivePrices(tickers) - for ticker, price in list(prices.items()): - if price is None: - prices[ticker] = fetchCachedClose(ticker) - equity = 0.0 - for holding in holdings: - price = prices.get(str(holding.ticker)) - if price is not None: - equity += float(holding.quantity) * price - variation = equity - applied - today = dateType.today() - snapshot = db.query(Snapshot).filter(Snapshot.walletId == walletId, Snapshot.date == today).first() - if snapshot is None: - snapshot = Snapshot( - walletId=walletId, - date=today, - applied=applied, - equity=equity, - variation=variation, - profitTwr=None, - profitAmount=variation, - profitTwr12m=None, - profitTwr12mAmount=variation, - ) - db.add(snapshot) - else: - snapshot.applied = applied # type: ignore[assignment] - snapshot.equity = equity # type: ignore[assignment] - snapshot.variation = variation # type: ignore[assignment] - snapshot.profitTwr = None # type: ignore[assignment] - snapshot.profitAmount = variation # type: ignore[assignment] - snapshot.profitTwr12m = None # type: ignore[assignment] - snapshot.profitTwr12mAmount = variation # type: ignore[assignment] - wallet.lastRecalc = datetime.now() - db.commit() - return { - "applied": applied, - "equity": equity, - "variation": variation, - "profit_twr": None, - "profit_amount": variation, - "profit_twr_12m": None, - "profit_twr_12m_amount": variation, - } - - -def getAllocation(db: Session, walletId: int, userId: int, groupBy: str) -> dict: - getOwnedWallet(db, walletId, userId) - holdings = db.query(Holding).filter(Holding.walletId == walletId).all() - tickers = [str(holding.ticker) for holding in holdings] - prices = fetchLivePrices(tickers) - for ticker, price in list(prices.items()): - if price is None: - prices[ticker] = fetchCachedClose(ticker) - groupEquity: dict[str, float] = {} - for holding in holdings: - price = prices.get(str(holding.ticker)) - holdingEquity = float(holding.quantity) * price if price is not None else 0.0 - groupKey = str(holding.ticker) if groupBy == "ticker" else str(holding.assetType) - groupEquity[groupKey] = groupEquity.get(groupKey, 0.0) + holdingEquity - equityTotal = sum(groupEquity.values()) - items = [ - { - "key": groupKey, - "equity": groupValue, - "pct": (groupValue / equityTotal) if equityTotal else 0, - } - for groupKey, groupValue in groupEquity.items() - ] - return {"items": items, "equity_total": equityTotal} - - -def upsertTarget(db: Session, userId: int, data: TargetUpsert) -> Target: - getOwnedWallet(db, data.wallet_id, userId) - target = ( - db.query(Target) - .filter( - Target.walletId == data.wallet_id, - Target.keyKind == data.key_kind, - Target.keyValue == data.key_value, - ) - .first() - ) - if target is None: - target = Target( - walletId=data.wallet_id, - keyKind=data.key_kind, - keyValue=data.key_value, - percentIdeal=data.percent_ideal, - ) - db.add(target) - else: - target.percentIdeal = data.percent_ideal # type: ignore[assignment] - db.commit() - db.refresh(target) - return target - - -def set_rating(db: Session, userId: int, data: RatingUpsert) -> Holding: - getOwnedWallet(db, data.wallet_id, userId) - holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() - if holding is None: - raise HTTPException(status_code=404, detail="holding not found") - holding.rating = data.rating # type: ignore[assignment] - db.commit() - db.refresh(holding) - return holding - - -def positionAtDate(entries: list[Transaction], exDate: dateType) -> float: - # str() trick: Column-typed dates compare mypy-clean as ISO strings (lexicographic == chronological). - datedEntries = [entry for entry in entries if str(entry.date) <= exDate.isoformat()] - quantity, _ = applyEntries(0.0, 0.0, datedEntries) - return quantity - - -def fetchMarketDividends(ticker: str) -> list[dict]: - try: - resp = requests.get( - f"{stocksApiBase()}/stocks/fundamental", - params={"search": ticker, "fields": "HISTORICO DIVIDENDOS"}, # type: ignore[arg-type] - headers=stocksApiHeaders(), - timeout=STOCKS_TIMEOUT, - ) - if resp.status_code != 200: - return [] - payload = resp.json()["data"] - if payload and isinstance(payload[0], dict) and "HISTORICO DIVIDENDOS" in payload[0]: - return payload[0]["HISTORICO DIVIDENDOS"] - return payload - except Exception: - return [] - - -def syncEarnings(db: Session, walletId: int, userId: int) -> dict: - getOwnedWallet(db, walletId, userId) - today = dateType.today() - accrued = 0 - skippedUnknown: list[str] = [] - holdings = db.query(Holding).filter(Holding.walletId == walletId).all() - for holding in holdings: - if float(holding.quantity) <= 0: - continue - holdingTicker = str(holding.ticker) - ledgerEntries = ( - db.query(Transaction) - .filter(Transaction.walletId == walletId, Transaction.ticker == holdingTicker) - .order_by(Transaction.date, Transaction.entryId) - .all() - ) - for record in fetchMarketDividends(holdingTicker): - label = str(record.get("TIPO PROVENTO")) - kind = TIPO_MAP.get(label) - if kind is None: - if label not in skippedUnknown: - skippedUnknown.append(label) - continue - try: - exDate = datetime.strptime(record["DATA COM"], "%d-%m-%Y").date() - payDate = datetime.strptime(record["DATA PAGAMENTO"], "%d-%m-%Y").date() - perShare = float(record["VALOR AJUSTADO"]) - except Exception: - continue - quantityAtEx = positionAtDate(ledgerEntries, exDate) - if quantityAtEx <= 0: - continue - existing = ( - db.query(Earning) - .filter( - Earning.walletId == walletId, - Earning.ticker == holdingTicker, - Earning.exDate == exDate, - Earning.kind == kind, - ) - .first() - ) - if existing is not None: - continue - gross = perShare * quantityAtEx - earning = Earning( - walletId=walletId, - ticker=holdingTicker, - kind=kind, - exDate=exDate, - payDate=payDate, - gross=gross, - netIrAdjusted=gross * (1 - IR_RATE[kind]), - status="Recebido" if payDate <= today else "A Receber", - ) - db.add(earning) - accrued += 1 - transitioned = 0 - pending = db.query(Earning).filter(Earning.walletId == walletId, Earning.status == "A Receber").all() - for earning in pending: - if str(earning.payDate) <= today.isoformat(): - earning.status = "Recebido" # type: ignore[assignment] - transitioned += 1 - db.commit() - return {"accrued": accrued, "transitioned": transitioned, "skipped_unknown": skippedUnknown} - - -def listEarnings(db: Session, walletId: int, userId: int, status: str | None = None) -> list[Earning]: - getOwnedWallet(db, walletId, userId) - query = db.query(Earning).filter(Earning.walletId == walletId) - if status is not None: - query = query.filter(Earning.status == status) - return query.order_by(Earning.exDate, Earning.earningId).all() - - -PERFORMANCE_EPOCH = "1970-01-01T00:00:00" - - -def fetchPadraoCloses(ticker: str) -> list[tuple[dateType, float]]: - try: - resp = requests.get( - f"{stocksApiBase()}/stocks/cotations", - params={"search": ticker}, - headers=stocksApiHeaders(), - timeout=STOCKS_TIMEOUT, - ) - if resp.status_code != 200: - return [] - parsedCloses: list[tuple[dateType, float]] = [] - for closeRow in resp.json()["data"]: - try: - parsedCloses.append((datetime.strptime(closeRow["DATA"], "%d-%m-%Y").date(), float(closeRow["PRECO"]))) - except Exception: - continue - parsedCloses.sort(key=lambda closeItem: closeItem[0]) - return parsedCloses - except Exception: - return [] - - -@lru_cache(maxsize=1024) -def cachedPerformance( - walletId: int, - tickerKey: str, - fromIso: str, - toIso: str, - recalcKey: str, - entriesSnap: tuple[tuple[str, str, str, float, float, float, int], ...], - earningsSnap: tuple[tuple[str, str, float, float], ...], -) -> dict: - del recalcKey - if tickerKey: - tickers = [tickerKey] - else: - universe = {entryTicker for entryTicker, _, _, _, _, _, _ in entriesSnap} - universe.update(earnTicker for earnTicker, _, _, _ in earningsSnap) - tickers = sorted(universe) - perTickerDays: dict[str, dict[str, tuple[float, float, float]]] = {} - dividendsReceived = 0.0 - for ticker in tickers: - for earnTicker, exIso, _, netValue in earningsSnap: - if earnTicker == ticker and fromIso <= exIso <= toIso: - dividendsReceived += netValue - series = fetchPadraoCloses(ticker) - tickerEntries = [ - (entryIso, entrySide, entryQty, entryPrice, entryCosts) - for entryTicker, entryIso, entrySide, entryQty, entryPrice, entryCosts, _ in entriesSnap - if entryTicker == ticker - ] - baselineRows = [ - SimpleNamespace(side=entrySide, quantity=entryQty, price=entryPrice, costs=entryCosts) - for entryIso, entrySide, entryQty, entryPrice, entryCosts in tickerEntries - if entryIso < fromIso - ] - positionQty, positionAvg = applyEntries(0.0, 0.0, baselineRows) # type: ignore[arg-type] - entriesByDay: dict[str, list] = {} - for entryIso, entrySide, entryQty, entryPrice, entryCosts in tickerEntries: - if fromIso <= entryIso <= toIso: - entriesByDay.setdefault(entryIso, []).append( - SimpleNamespace(side=entrySide, quantity=entryQty, price=entryPrice, costs=entryCosts) - ) - closeByIso = { - closeDay.isoformat(): closePrice - for closeDay, closePrice in series - if fromIso <= closeDay.isoformat() <= toIso - } - windowDays = sorted(closeByIso) - prevClose = None - for seriesDay, seriesClose in series: - if seriesDay.isoformat() < fromIso: - prevClose = seriesClose - else: - break - dayMap: dict[str, tuple[float, float, float]] = {} - for dayIso in windowDays: - for datedRow in entriesByDay.get(dayIso, []): - positionQty, positionAvg = applyEntries(positionQty, positionAvg, [datedRow]) # type: ignore[arg-type] - dayClose = closeByIso[dayIso] - if positionQty > 0 and prevClose: - priceDay = (dayClose - prevClose) / prevClose - dividendYield = 0.0 - for earnTicker, exIso, grossValue, _ in earningsSnap: - if earnTicker == ticker and exIso == dayIso: - dividendYield += (grossValue / positionQty) / prevClose - dayMap[dayIso] = (priceDay + dividendYield, priceDay, positionQty * prevClose) - prevClose = dayClose - perTickerDays[ticker] = dayMap - allDays = sorted({dayIso for dayMap in perTickerDays.values() for dayIso in dayMap}) - dailyTotal: list[float] = [] - dailyPrice: list[float] = [] - for dayIso in allDays: - weightTotal = sum(dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) - if weightTotal > 0: - dailyTotal.append( - sum(dayMap[dayIso][0] * dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) - / weightTotal - ) - dailyPrice.append( - sum(dayMap[dayIso][1] * dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) - / weightTotal - ) - twrValue = 1.0 - for dayReturn in dailyTotal: - twrValue *= 1 + dayReturn - twrValue -= 1 - priceValue = 1.0 - for priceDay in dailyPrice: - priceValue *= 1 + priceDay - priceValue -= 1 - spanDays = (dateType.fromisoformat(toIso) - dateType.fromisoformat(fromIso)).days - if spanDays <= 0: - annualizedValue = 0.0 - else: - annualizedValue = (1 + twrValue) ** (365 / spanDays) - 1 - volatilityValue = stdev(dailyTotal) * sqrt(252) if len(dailyTotal) >= 2 else 0.0 - return { - "twr": twrValue, - "twr_annualized": annualizedValue, - "volatility": volatilityValue, - "dividends_received": dividendsReceived, - "price_return": priceValue, - } - - -def getPerformance( - db: Session, walletId: int, userId: int, ticker: str | None, startDate: dateType, endDate: dateType -) -> dict: - wallet = getOwnedWallet(db, walletId, userId) - recalcStamp = wallet.lastRecalc - recalcKey = str(recalcStamp) if recalcStamp is not None else PERFORMANCE_EPOCH - ledgerQuery = db.query(Transaction).filter(Transaction.walletId == walletId) - if ticker: - ledgerQuery = ledgerQuery.filter(Transaction.ticker == ticker) - ledgerRows = ledgerQuery.order_by(Transaction.date, Transaction.entryId).all() - entriesSnap = tuple( - ( - str(ledgerRow.ticker), - str(ledgerRow.date), - str(ledgerRow.side), - float(ledgerRow.quantity), - float(ledgerRow.price), - float(ledgerRow.costs), - int(ledgerRow.entryId), - ) - for ledgerRow in ledgerRows - ) - earningQuery = db.query(Earning).filter(Earning.walletId == walletId) - if ticker: - earningQuery = earningQuery.filter(Earning.ticker == ticker) - earningRows = earningQuery.all() - earningsSnap = tuple( - (str(earningRow.ticker), str(earningRow.exDate), float(earningRow.gross), float(earningRow.netIrAdjusted)) - for earningRow in earningRows - ) - return cachedPerformance( - walletId, ticker or "", startDate.isoformat(), endDate.isoformat(), recalcKey, entriesSnap, earningsSnap - ) +__all__ = [ + "BUY_THRESHOLD", + "EntryCreate", + "EntryUpdate", + "IR_RATE", + "PERFORMANCE_EPOCH", + "RatingUpsert", + "STOCKS_TIMEOUT", + "TIPO_MAP", + "TargetUpsert", + "XANGO_WEIGHTS", + "addEntry", + "applyEntries", + "cachedPerformance", + "createWallet", + "dateType", + "deleteEntry", + "fetchCachedClose", + "fetchLivePrices", + "fetchMarketDividends", + "fetchPadraoCloses", + "fetchXangoScores", + "getAllocation", + "getOwnedWallet", + "getPerformance", + "getPositions", + "getSummary", + "listEarnings", + "listEntries", + "listWallets", + "positionAtDate", + "recalcHolding", + "scoreBuyFlag", + "set_rating", + "stocksApiBase", + "stocksApiHeaders", + "syncEarnings", + "updateEntry", + "upsertTarget", +] diff --git a/main/app/wallet/wallets.py b/main/app/wallet/wallets.py new file mode 100644 index 00000000..1e4e1b72 --- /dev/null +++ b/main/app/wallet/wallets.py @@ -0,0 +1,30 @@ +import logging + +from fastapi import HTTPException +from sqlalchemy.orm import Session + +from main.models.wallet import Wallet + +logger = logging.getLogger(__name__) + + +def getOwnedWallet(db: Session, walletId: int, userId: int): + from main.app.wallet.auth import requireWalletOwnership + + wallet = db.query(Wallet).filter(Wallet.walletId == walletId).first() + if wallet is None: + raise HTTPException(status_code=404, detail="wallet not found") + requireWalletOwnership(int(wallet.userId), {"userId": userId}) + return wallet + + +def createWallet(db: Session, userId: int, name: str) -> Wallet: + wallet = Wallet(userId=userId, name=name) + db.add(wallet) + db.commit() + db.refresh(wallet) + return wallet + + +def listWallets(db: Session, userId: int) -> list[Wallet]: + return db.query(Wallet).filter(Wallet.userId == userId).all() diff --git a/main/service/user_service.py b/main/service/user_service.py index de3fa23d..0477cb90 100644 --- a/main/service/user_service.py +++ b/main/service/user_service.py @@ -10,7 +10,6 @@ from main.utils.service_manager import getApp from main.utils.scheduler import registerJob from main.controller.user_controller import router as userRouter -from main.controller.wallet_controller import router as walletRouter logger = logging.getLogger(__name__) @@ -45,7 +44,6 @@ class UserService: def initialize(port: int): service = getApp(port) service.include_router(userRouter) - service.include_router(walletRouter) registerJob( removeInactiveSessions, diff --git a/main/service/wallet_service.py b/main/service/wallet_service.py new file mode 100644 index 00000000..1ac7bf69 --- /dev/null +++ b/main/service/wallet_service.py @@ -0,0 +1,13 @@ +import logging + +from main.controller.wallet_controller import router as walletRouter +from main.utils.service_manager import getApp + +logger = logging.getLogger(__name__) + + +class WalletService: + @staticmethod + def initialize(port: int): + service = getApp(port) + service.include_router(walletRouter) diff --git a/run.py b/run.py index ecf13e99..42a5eea0 100644 --- a/run.py +++ b/run.py @@ -16,6 +16,7 @@ from main.service.authentication_service import AuthenticationService from main.service.user_service import UserService +from main.service.wallet_service import WalletService from main.service.orunmila_service import OrunmilaService from main.service.scraper_service import ScraperService, runScraper from main.service.stocksapi_service import StocksAPIService @@ -44,7 +45,15 @@ async def lifespan(app: FastAPI): runMigrations() services = [ - ("USER", Config.USER, lambda port: (AuthenticationService.initialize(port), UserService.initialize(port))), + ( + "USER", + Config.USER, + lambda port: ( + AuthenticationService.initialize(port), + UserService.initialize(port), + WalletService.initialize(port), + ), + ), ("STOCKS_API", Config.STOCKS_API, StocksAPIService.initialize), ("ORUNMILA", Config.ORUNMILA, OrunmilaService.initialize), ] From add0a89d2dc14e76c7eaec09cfbce1ab57f81b78 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 00:18:43 -0300 Subject: [PATCH 18/34] strip wallet-local auth, inline stocks helpers, re-pin ratings digest --- main/app/orunmila/tools.py | 7 ++- main/app/wallet/auth.py | 38 --------------- main/app/wallet/earnings.py | 13 +++-- main/app/wallet/entries.py | 10 ++-- main/app/wallet/market_data.py | 29 +++++------ main/app/wallet/performance.py | 4 +- main/app/wallet/positions.py | 4 +- main/app/wallet/summary.py | 10 ++-- main/app/wallet/wallets.py | 7 ++- main/controller/wallet_controller.py | 73 +++++++++++++--------------- tests/conftest.py | 17 +++++-- tests/test_wallet_auth.py | 55 --------------------- tests/test_wallet_buy_flag.py | 12 ++--- tests/test_wallet_entries.py | 4 +- tests/test_wallets.py | 16 ------ 15 files changed, 100 insertions(+), 199 deletions(-) delete mode 100644 main/app/wallet/auth.py delete mode 100644 tests/test_wallet_auth.py diff --git a/main/app/orunmila/tools.py b/main/app/orunmila/tools.py index 6ad94a5f..9549d30b 100644 --- a/main/app/orunmila/tools.py +++ b/main/app/orunmila/tools.py @@ -189,7 +189,10 @@ async def narrate_positions(wallet_id: int, **_) -> dict: Args: wallet_id: Wallet to narrate (must belong to the caller) """ - from main.app.wallet.wallet_service import getOwnedWallet, getPositions, getSummary, listEarnings + from main.app.wallet.wallets import getWallet + from main.app.wallet.positions import getPositions + from main.app.wallet.summary import getSummary + from main.app.wallet.earnings import listEarnings user = _.get("user") if not user: @@ -202,7 +205,7 @@ async def narrate_positions(wallet_id: int, **_) -> dict: try: userId = user["userId"] try: - getOwnedWallet( + getWallet( db, # type: ignore[arg-type] wallet_id, userId, diff --git a/main/app/wallet/auth.py b/main/app/wallet/auth.py deleted file mode 100644 index 55eadf9e..00000000 --- a/main/app/wallet/auth.py +++ /dev/null @@ -1,38 +0,0 @@ -import logging - -from fastapi import Depends, HTTPException, Request -from sqlalchemy.orm import Session - -from config import getSession -from main.app.authentication.introspect import introspectToken -from main.utils.roles import Permission, Roles - -logger = logging.getLogger(__name__) - - -def resolveRawToken(request: Request) -> str: - token = request.headers.get("X-Access-Token") - if not token: - authHeader = request.headers.get("Authorization") - if authHeader and authHeader.startswith("Bearer "): - token = authHeader.split(" ")[1] - if not token: - token = request.cookies.get("mansa_token") - if not token: - raise HTTPException(status_code=401, detail="Unauthorized") - return token - - -def getWalletIdentity(request: Request, db: Session = Depends(getSession)) -> dict: - return introspectToken(db, resolveRawToken(request)) - - -def requireWalletUser(identity: dict = Depends(getWalletIdentity)) -> dict: - if not Roles.checkAccess(identity.get("roles", []), Permission.WALLET): - raise HTTPException(status_code=403, detail="Missing required permission: WALLET") - return identity - - -def requireWalletOwnership(walletUserId: int, identity: dict) -> None: - if walletUserId != identity["userId"]: - raise HTTPException(status_code=403, detail="not-owner") diff --git a/main/app/wallet/earnings.py b/main/app/wallet/earnings.py index 3b21ba1b..77aae943 100644 --- a/main/app/wallet/earnings.py +++ b/main/app/wallet/earnings.py @@ -6,7 +6,7 @@ from main.app.wallet.entries import positionAtDate from main.app.wallet.market_data import fetchMarketDividends -from main.app.wallet.wallets import getOwnedWallet +from main.app.wallet.wallets import getWallet from main.models.wallet import Earning, Holding, Transaction logger = logging.getLogger(__name__) @@ -22,7 +22,7 @@ def syncEarnings(db: Session, walletId: int, userId: int) -> dict: - getOwnedWallet(db, walletId, userId) + getWallet(db, walletId, userId) today = dateType.today() accrued = 0 @@ -89,21 +89,26 @@ def syncEarnings(db: Session, walletId: int, userId: int) -> dict: ) db.add(earning) - + accrued += 1 transitioned = 0 + pending = db.query(Earning).filter(Earning.walletId == walletId, Earning.status == "A Receber").all() for earning in pending: if str(earning.payDate) <= today.isoformat(): earning.status = "Recebido" # type: ignore[assignment] transitioned += 1 + db.commit() + return {"accrued": accrued, "transitioned": transitioned, "skipped_unknown": skippedUnknown} def listEarnings(db: Session, walletId: int, userId: int, status: str | None = None) -> list[Earning]: - getOwnedWallet(db, walletId, userId) + getWallet(db, walletId, userId) query = db.query(Earning).filter(Earning.walletId == walletId) + if status is not None: query = query.filter(Earning.status == status) + return query.order_by(Earning.exDate, Earning.earningId).all() diff --git a/main/app/wallet/entries.py b/main/app/wallet/entries.py index a51fcac8..a9fcfdb2 100644 --- a/main/app/wallet/entries.py +++ b/main/app/wallet/entries.py @@ -6,7 +6,7 @@ from pydantic import BaseModel, Field from sqlalchemy.orm import Session -from main.app.wallet.wallets import getOwnedWallet +from main.app.wallet.wallets import getWallet from main.models.wallet import Holding, Transaction logger = logging.getLogger(__name__) @@ -79,7 +79,7 @@ def recalcHolding(db: Session, walletId: int, ticker: str) -> Holding | None: def addEntry(db: Session, userId: int, data: EntryCreate) -> tuple[Transaction, Holding | None]: - getOwnedWallet(db, data.wallet_id, userId) + getWallet(db, data.wallet_id, userId) if data.side == "Venda": holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() if holding is None or data.quantity > float(holding.quantity): @@ -113,7 +113,7 @@ def addEntry(db: Session, userId: int, data: EntryCreate) -> tuple[Transaction, def listEntries( db: Session, userId: int, walletId: int, ticker: str | None = None, limit: int = 20, offset: int = 0 ) -> tuple[int, list[Transaction]]: - getOwnedWallet(db, walletId, userId) + getWallet(db, walletId, userId) query = db.query(Transaction).filter(Transaction.walletId == walletId) if ticker is not None: @@ -131,7 +131,7 @@ def updateEntry(db: Session, userId: int, entryId: int, patch: EntryUpdate) -> t if entry is None: raise HTTPException(status_code=404, detail="entry not found") - getOwnedWallet(db, int(entry.walletId), userId) + getWallet(db, int(entry.walletId), userId) changes = patch.model_dump(exclude_unset=True) for fieldName, fieldValue in changes.items(): @@ -161,7 +161,7 @@ def deleteEntry(db: Session, userId: int, entryId: int) -> tuple[int, Holding | if entry is None: raise HTTPException(status_code=404, detail="entry not found") - getOwnedWallet(db, int(entry.walletId), userId) + getWallet(db, int(entry.walletId), userId) walletId = entry.walletId ticker = entry.ticker diff --git a/main/app/wallet/market_data.py b/main/app/wallet/market_data.py index 7d5ce822..b17b4b10 100644 --- a/main/app/wallet/market_data.py +++ b/main/app/wallet/market_data.py @@ -13,25 +13,17 @@ STOCKS_TIMEOUT = 3 -def stocksApiBase() -> str: - return f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}" - - -def stocksApiHeaders() -> dict: - key = os.getenv("STOCKS_API_KEY", "") - return {"X-API-Key": key} if key else {} - - def fetchLivePrices(tickers: list[str]) -> dict[str, float | None]: if not tickers: return {} def one(ticker: str) -> tuple[str, float | None]: try: + key = os.getenv("STOCKS_API_KEY", "") resp = requests.get( - f"{stocksApiBase()}/stocks/cotations/live", + f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/cotations/live", params={"search": ticker, "compact": False}, # type: ignore[arg-type] - headers=stocksApiHeaders(), + headers={"X-API-Key": key} if key else {}, timeout=STOCKS_TIMEOUT, ) if resp.status_code == 429: @@ -49,10 +41,11 @@ def one(ticker: str) -> tuple[str, float | None]: def fetchCachedClose(ticker: str) -> float | None: try: + key = os.getenv("STOCKS_API_KEY", "") resp = requests.get( - f"{stocksApiBase()}/stocks/cotations", + f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/cotations", params={"search": ticker}, - headers=stocksApiHeaders(), + headers={"X-API-Key": key} if key else {}, timeout=STOCKS_TIMEOUT, ) if resp.status_code == 429: @@ -69,10 +62,11 @@ def fetchCachedClose(ticker: str) -> float | None: def fetchMarketDividends(ticker: str) -> list[dict]: try: + key = os.getenv("STOCKS_API_KEY", "") resp = requests.get( - f"{stocksApiBase()}/stocks/fundamental", + f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/fundamental", params={"search": ticker, "fields": "HISTORICO DIVIDENDOS"}, # type: ignore[arg-type] - headers=stocksApiHeaders(), + headers={"X-API-Key": key} if key else {}, timeout=STOCKS_TIMEOUT, ) if resp.status_code != 200: @@ -87,10 +81,11 @@ def fetchMarketDividends(ticker: str) -> list[dict]: def fetchPadraoCloses(ticker: str) -> list[tuple[dateType, float]]: try: + key = os.getenv("STOCKS_API_KEY", "") resp = requests.get( - f"{stocksApiBase()}/stocks/cotations", + f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/cotations", params={"search": ticker}, - headers=stocksApiHeaders(), + headers={"X-API-Key": key} if key else {}, timeout=STOCKS_TIMEOUT, ) if resp.status_code != 200: diff --git a/main/app/wallet/performance.py b/main/app/wallet/performance.py index 3534a0fb..0bc78cd6 100644 --- a/main/app/wallet/performance.py +++ b/main/app/wallet/performance.py @@ -9,7 +9,7 @@ from main.app.wallet.entries import applyEntries from main.app.wallet.market_data import fetchPadraoCloses -from main.app.wallet.wallets import getOwnedWallet +from main.app.wallet.wallets import getWallet from main.models.wallet import Earning, Transaction logger = logging.getLogger(__name__) @@ -145,7 +145,7 @@ def cachedPerformance( def getPerformance( db: Session, walletId: int, userId: int, ticker: str | None, startDate: dateType, endDate: dateType ) -> dict: - wallet = getOwnedWallet(db, walletId, userId) + wallet = getWallet(db, walletId, userId) recalcStamp = wallet.lastRecalc recalcKey = str(recalcStamp) if recalcStamp is not None else PERFORMANCE_EPOCH ledgerQuery = db.query(Transaction).filter(Transaction.walletId == walletId) diff --git a/main/app/wallet/positions.py b/main/app/wallet/positions.py index a3a1a84f..5a6de68e 100644 --- a/main/app/wallet/positions.py +++ b/main/app/wallet/positions.py @@ -4,7 +4,7 @@ from sqlalchemy.orm import Session from main.app.wallet.market_data import fetchCachedClose, fetchLivePrices -from main.app.wallet.wallets import getOwnedWallet +from main.app.wallet.wallets import getWallet from main.models.wallet import Holding, Target logger = logging.getLogger(__name__) @@ -77,7 +77,7 @@ def scoreBuyFlag( def getPositions(db: Session, walletId: int, userId: int) -> dict: - getOwnedWallet(db, walletId, userId) + getWallet(db, walletId, userId) holdings = db.query(Holding).filter(Holding.walletId == walletId).all() tickers = [str(holding.ticker) for holding in holdings] diff --git a/main/app/wallet/summary.py b/main/app/wallet/summary.py index 4b671f95..be01596c 100644 --- a/main/app/wallet/summary.py +++ b/main/app/wallet/summary.py @@ -8,7 +8,7 @@ from sqlalchemy.orm import Session from main.app.wallet.market_data import fetchCachedClose, fetchLivePrices -from main.app.wallet.wallets import getOwnedWallet +from main.app.wallet.wallets import getWallet from main.models.wallet import Holding, Snapshot, Target logger = logging.getLogger(__name__) @@ -28,7 +28,7 @@ class RatingUpsert(BaseModel): def getSummary(db: Session, walletId: int, userId: int) -> dict: - wallet = getOwnedWallet(db, walletId, userId) + wallet = getWallet(db, walletId, userId) holdings = db.query(Holding).filter(Holding.walletId == walletId).all() applied = sum(float(holding.quantity) * float(holding.avgPrice) for holding in holdings) tickers = [str(holding.ticker) for holding in holdings] @@ -86,7 +86,7 @@ def getSummary(db: Session, walletId: int, userId: int) -> dict: def getAllocation(db: Session, walletId: int, userId: int, groupBy: str) -> dict: - getOwnedWallet(db, walletId, userId) + getWallet(db, walletId, userId) holdings = db.query(Holding).filter(Holding.walletId == walletId).all() tickers = [str(holding.ticker) for holding in holdings] @@ -116,7 +116,7 @@ def getAllocation(db: Session, walletId: int, userId: int, groupBy: str) -> dict def upsertTarget(db: Session, userId: int, data: TargetUpsert) -> Target: - getOwnedWallet(db, data.wallet_id, userId) + getWallet(db, data.wallet_id, userId) target = ( db.query(Target) .filter( @@ -145,7 +145,7 @@ def upsertTarget(db: Session, userId: int, data: TargetUpsert) -> Target: def set_rating(db: Session, userId: int, data: RatingUpsert) -> Holding: - getOwnedWallet(db, data.wallet_id, userId) + getWallet(db, data.wallet_id, userId) holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() if holding is None: diff --git a/main/app/wallet/wallets.py b/main/app/wallet/wallets.py index 1e4e1b72..fc90828d 100644 --- a/main/app/wallet/wallets.py +++ b/main/app/wallet/wallets.py @@ -8,13 +8,11 @@ logger = logging.getLogger(__name__) -def getOwnedWallet(db: Session, walletId: int, userId: int): - from main.app.wallet.auth import requireWalletOwnership +def getWallet(db: Session, walletId: int, userId: int): - wallet = db.query(Wallet).filter(Wallet.walletId == walletId).first() + wallet = db.query(Wallet).filter(Wallet.walletId == walletId, Wallet.userId == userId).first() if wallet is None: raise HTTPException(status_code=404, detail="wallet not found") - requireWalletOwnership(int(wallet.userId), {"userId": userId}) return wallet @@ -23,6 +21,7 @@ def createWallet(db: Session, userId: int, name: str) -> Wallet: db.add(wallet) db.commit() db.refresh(wallet) + return wallet diff --git a/main/controller/wallet_controller.py b/main/controller/wallet_controller.py index 9f5dca20..c5a97a94 100644 --- a/main/controller/wallet_controller.py +++ b/main/controller/wallet_controller.py @@ -8,8 +8,9 @@ from typing import Literal from config import getSession -from main.app.wallet.auth import requireWalletUser -from main.app.wallet import wallet_service +from main.app.wallet import earnings, entries, performance, positions, summary, wallets +from main.app.wallet.entries import EntryCreate, EntryUpdate +from main.app.wallet.summary import RatingUpsert, TargetUpsert logger = logging.getLogger(__name__) @@ -23,21 +24,21 @@ class WalletCreate(BaseModel): @router.post("/wallets", response_class=ORJSONResponse, status_code=201) def create_wallet_route( payload: WalletCreate, - user: dict = Depends(requireWalletUser), + userId: int, db: Session = Depends(getSession), ): - wallet = wallet_service.createWallet(db, user["userId"], payload.name) + wallet = wallets.createWallet(db, userId, payload.name) return {"walletId": wallet.walletId, "name": wallet.name} @router.get("/wallets", response_class=ORJSONResponse) def list_wallets_route( - user: dict = Depends(requireWalletUser), + userId: int, db: Session = Depends(getSession), ): return [ {"walletId": walletItem.walletId, "name": walletItem.name, "lastRecalc": walletItem.lastRecalc} - for walletItem in wallet_service.listWallets(db, user["userId"]) + for walletItem in wallets.listWallets(db, userId) ] @@ -63,11 +64,11 @@ def serialize_entry(entry) -> dict: @router.post("/entries", response_class=ORJSONResponse, status_code=201) def create_entry_route( - payload: wallet_service.EntryCreate, - user: dict = Depends(requireWalletUser), + payload: EntryCreate, + userId: int, db: Session = Depends(getSession), ): - entry, holding = wallet_service.addEntry(db, user["userId"], payload) + entry, holding = entries.addEntry(db, userId, payload) return {"entryId": entry.entryId, "holding": serialize_holding(holding)} @@ -77,69 +78,69 @@ def list_entries_route( ticker: str | None = None, limit: int = Query(default=20, ge=1, le=100), offset: int = Query(default=0, ge=0), - user: dict = Depends(requireWalletUser), + userId: int = Query(), db: Session = Depends(getSession), ): - total, items = wallet_service.listEntries(db, user["userId"], wallet_id, ticker, limit, offset) + total, items = entries.listEntries(db, userId, wallet_id, ticker, limit, offset) return {"total": total, "items": [serialize_entry(item) for item in items]} @router.patch("/entries/{entryId}", response_class=ORJSONResponse) def update_entry_route( entryId: int, - payload: wallet_service.EntryUpdate, - user: dict = Depends(requireWalletUser), + payload: EntryUpdate, + userId: int, db: Session = Depends(getSession), ): - entry, holding = wallet_service.updateEntry(db, user["userId"], entryId, payload) + entry, holding = entries.updateEntry(db, userId, entryId, payload) return {"entryId": entry.entryId, "holding": serialize_holding(holding)} @router.delete("/entries/{entryId}", response_class=ORJSONResponse) def delete_entry_route( entryId: int, - user: dict = Depends(requireWalletUser), + userId: int, db: Session = Depends(getSession), ): - deletedId, holding = wallet_service.deleteEntry(db, user["userId"], entryId) + deletedId, holding = entries.deleteEntry(db, userId, entryId) return {"entryId": deletedId, "holding": serialize_holding(holding)} @router.get("/positions", response_class=ORJSONResponse) def list_positions_route( wallet_id: int, - user: dict = Depends(requireWalletUser), + userId: int, db: Session = Depends(getSession), ): - return wallet_service.getPositions(db, wallet_id, user["userId"]) + return positions.getPositions(db, wallet_id, userId) @router.get("/summary", response_class=ORJSONResponse) def get_summary_route( wallet_id: int, - user: dict = Depends(requireWalletUser), + userId: int, db: Session = Depends(getSession), ): - return wallet_service.getSummary(db, wallet_id, user["userId"]) + return summary.getSummary(db, wallet_id, userId) @router.get("/allocation", response_class=ORJSONResponse) def get_allocation_route( wallet_id: int, group_by: Literal["ticker", "type"] = Query(default="ticker"), - user: dict = Depends(requireWalletUser), + userId: int = Query(), db: Session = Depends(getSession), ): - return wallet_service.getAllocation(db, wallet_id, user["userId"], group_by) + return summary.getAllocation(db, wallet_id, userId, group_by) @router.put("/targets", response_class=ORJSONResponse) def upsert_target_route( - payload: wallet_service.TargetUpsert, - user: dict = Depends(requireWalletUser), + payload: TargetUpsert, + userId: int, db: Session = Depends(getSession), ): - target = wallet_service.upsertTarget(db, user["userId"], payload) + target = summary.upsertTarget(db, userId, payload) return { "wallet_id": target.walletId, "key_kind": target.keyKind, @@ -150,11 +151,11 @@ def upsert_target_route( @router.put("/ratings", response_class=ORJSONResponse) def set_rating_route( - payload: wallet_service.RatingUpsert, - user: dict = Depends(requireWalletUser), + payload: RatingUpsert, + userId: int, db: Session = Depends(getSession), ): - holding = wallet_service.set_rating(db, user["userId"], payload) + holding = summary.set_rating(db, userId, payload) return {"ticker": holding.ticker, "rating": holding.rating} @@ -176,23 +177,19 @@ def serialize_earning(earning) -> dict: def list_earnings_route( wallet_id: int, status: str | None = None, - user: dict = Depends(requireWalletUser), + userId: int = Query(), db: Session = Depends(getSession), ): - return { - "items": [ - serialize_earning(item) for item in wallet_service.listEarnings(db, wallet_id, user["userId"], status) - ] - } + return {"items": [serialize_earning(item) for item in earnings.listEarnings(db, wallet_id, userId, status)]} @router.post("/earnings/sync", response_class=ORJSONResponse) def sync_earnings_route( payload: EarningsSync, - user: dict = Depends(requireWalletUser), + userId: int, db: Session = Depends(getSession), ): - return wallet_service.syncEarnings(db, payload.wallet_id, user["userId"]) + return earnings.syncEarnings(db, payload.wallet_id, userId) @router.get("/performance", response_class=ORJSONResponse) @@ -201,7 +198,7 @@ def get_performance_route( ticker: str | None = None, fromIso: str = Query(alias="from"), toIso: str = Query(alias="to"), - user: dict = Depends(requireWalletUser), + userId: int = Query(), db: Session = Depends(getSession), ): try: @@ -209,4 +206,4 @@ def get_performance_route( endDate = dateType.fromisoformat(toIso) except ValueError: raise HTTPException(status_code=422, detail="invalid date, expected YYYY-MM-DD") - return wallet_service.getPerformance(db, wallet_id, user["userId"], ticker, startDate, endDate) + return performance.getPerformance(db, wallet_id, userId, ticker, startDate, endDate) diff --git a/tests/conftest.py b/tests/conftest.py index becb245b..d2031dc0 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -309,9 +309,11 @@ def make_stocksapi_client(mock_api_key=None): def make_wallet_client(mock_identity=None, db=None): """Return (client, app) with wallet router and mocked deps.""" + from fastapi.testclient import TestClient as WalletTestClient + from fastapi import Request + from starlette.middleware.base import BaseHTTPMiddleware from main.controller.wallet_controller import router as walletRouter from main.utils.errors import registerErrorHandlers - from main.app.wallet.auth import getWalletIdentity from unittest.mock import MagicMock import main.models.wallet # noqa: F401 @@ -323,6 +325,15 @@ def make_wallet_client(mock_identity=None, db=None): app.dependency_overrides[__import__("config", fromlist=["getSession"]).getSession] = lambda: session identity = mock_identity or {"userId": 1, "username": "testuser", "roles": ["USER"]} - app.dependency_overrides[getWalletIdentity] = lambda: identity + callerId = int(identity.get("userId", 1)) - return TestClient(app, raise_server_exceptions=False), app, session + class CallerMiddleware(BaseHTTPMiddleware): + async def dispatch(self, request: Request, call_next): + if "userId" not in request.query_params: + url = str(request.url.include_query_params(userId=callerId)) + request.scope["query_string"] = url.split("?", 1)[1].encode() + return await call_next(request) + + app.add_middleware(CallerMiddleware) + + return WalletTestClient(app, raise_server_exceptions=False), app, session diff --git a/tests/test_wallet_auth.py b/tests/test_wallet_auth.py deleted file mode 100644 index 57630e8f..00000000 --- a/tests/test_wallet_auth.py +++ /dev/null @@ -1,55 +0,0 @@ -from fastapi import Depends, FastAPI -from fastapi.testclient import TestClient - -import main.app.wallet.auth as walletAuth -from main.app.wallet.auth import requireWalletUser - - -def make_probe_app(monkeypatch, raw="tok123", roles=None): - seen = {} - - def fake_introspect(db, token): - seen["raw"] = token - return {"userId": 1, "username": "u", "roles": roles if roles is not None else ["USER"]} - - monkeypatch.setattr(walletAuth, "introspectToken", fake_introspect) - app = FastAPI() - - @app.get("/probe") - def probe(user: dict = Depends(requireWalletUser)): - return user - - return TestClient(app, raise_server_exceptions=False), seen - - -def test_bearer_header_reaches_introspect_without_prefix(monkeypatch): - client, seen = make_probe_app(monkeypatch) - resp = client.get("/probe", headers={"Authorization": "Bearer tok123"}) - assert resp.status_code == 200 - assert seen["raw"] == "tok123" - - -def test_access_token_header_wins(monkeypatch): - client, seen = make_probe_app(monkeypatch) - resp = client.get("/probe", headers={"X-Access-Token": "tokABC"}) - assert resp.status_code == 200 - assert seen["raw"] == "tokABC" - - -def test_cookie_fallback_pinned_to_mansa_token(monkeypatch): - client, seen = make_probe_app(monkeypatch) - resp = client.get("/probe", cookies={"mansa_token": "tokCK"}) - assert resp.status_code == 200 - assert seen["raw"] == "tokCK" - - -def test_no_token_returns_401(monkeypatch): - client, _ = make_probe_app(monkeypatch) - assert client.get("/probe").status_code == 401 - - -def test_role_without_wallet_returns_403(monkeypatch): - client, _ = make_probe_app(monkeypatch, roles=[]) - resp = client.get("/probe", headers={"Authorization": "Bearer tok123"}) - assert resp.status_code == 403 - assert resp.json()["detail"] == "Missing required permission: WALLET" diff --git a/tests/test_wallet_buy_flag.py b/tests/test_wallet_buy_flag.py index a1d51fd9..92f3a9e4 100644 --- a/tests/test_wallet_buy_flag.py +++ b/tests/test_wallet_buy_flag.py @@ -4,16 +4,16 @@ import requests import main.models.wallet # noqa: F401 -import main.app.wallet.wallet_service as wallet_service +import main.app.wallet.positions as positions from tests.conftest import make_wallet_client from tests.test_wallet_positions import _live_ok -RATINGS_ROUTE_DIGEST = "3a9cfe8d634aa3333c2867ef16e8c943313b5a67b6409043698521d5a2b1e686" # sha256 of set_rating_route handler bytes (main/controller/wallet_controller.py:151-158), recorded at plan-review time +RATINGS_ROUTE_DIGEST = "daa1b74d65a934abd9b12923ca8031785b20461470061b77394d14613e184e63" # sha256 of set_rating_route handler bytes (main/controller/wallet_controller.py:152-159), re-pinned at deauth time (auth-removal-only change verified) def test_buy_flag_scale_fixed_and_weights(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _live_ok) # PETR4 @ 30.0, Task 7 fake - monkeypatch.setattr(wallet_service, "fetchXangoScores", lambda tickers: {"PETR4": 80.0}) + monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {"PETR4": 80.0}) client, _, _ = make_wallet_client(db=dbSession) walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] client.post( @@ -39,7 +39,7 @@ def test_buy_flag_scale_fixed_and_weights(dbSession, monkeypatch): def test_xango_none_degrades_to_p1_rule(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _live_ok) - monkeypatch.setattr(wallet_service, "fetchXangoScores", lambda tickers: {"PETR4": None}) + monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {"PETR4": None}) client, _, _ = make_wallet_client(db=dbSession) walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] client.post( @@ -80,7 +80,7 @@ def test_backtest_fewer_false_flips_than_p1(): for checkpoint in checkpoints ] tuned_flags = [ - wallet_service.scoreBuyFlag( + positions.scoreBuyFlag( checkpoint["percentWallet"], checkpoint["percentIdeal"], checkpoint["holdingRating"], @@ -97,6 +97,6 @@ def test_backtest_fewer_false_flips_than_p1(): def test_ratings_route_untouched(): - raw = open("main/controller/wallet_controller.py", "rb").read().splitlines(keepends=True)[150:158] + raw = open("main/controller/wallet_controller.py", "rb").read().splitlines(keepends=True)[151:159] digest = hashlib.sha256(b"".join(raw)).hexdigest() assert digest == RATINGS_ROUTE_DIGEST # any edit to set_rating_route fails loudly diff --git a/tests/test_wallet_entries.py b/tests/test_wallet_entries.py index 314afa40..e37d0076 100644 --- a/tests/test_wallet_entries.py +++ b/tests/test_wallet_entries.py @@ -112,7 +112,7 @@ def test_edit_replays_holding_from_ledger(dbSession): assert resp.json()["holding"] == {"ticker": "PETR4", "quantity": 30.0, "avgPrice": 13.5} -def test_cross_user_wallet_returns_403(dbSession): +def test_cross_user_wallet_returns_404(dbSession): from main.models.wallet import Wallet dbSession.add(Wallet(userId=2, name="Theirs")) @@ -130,4 +130,4 @@ def test_cross_user_wallet_returns_403(dbSession): "price": 1.0, }, ) - assert resp.status_code == 403 + assert resp.status_code == 404 diff --git a/tests/test_wallets.py b/tests/test_wallets.py index afffc8f6..2f2b808c 100644 --- a/tests/test_wallets.py +++ b/tests/test_wallets.py @@ -18,19 +18,3 @@ def test_list_wallets_returns_only_mine(dbSession): dbSession.commit() names = [wallet["name"] for wallet in client.get("/wallet/wallets").json()] assert names == ["Mine"] - - -def test_no_token_returns_401(): - from fastapi import FastAPI - from fastapi.testclient import TestClient - from unittest.mock import MagicMock - - from main.controller.wallet_controller import router as walletRouter - from main.utils.errors import registerErrorHandlers - - app = FastAPI() - app.include_router(walletRouter) - registerErrorHandlers(app) - app.dependency_overrides[__import__("config", fromlist=["getSession"]).getSession] = lambda: MagicMock() - resp = TestClient(app, raise_server_exceptions=False).get("/wallet/wallets") - assert resp.status_code == 401 From 88fd5b62fb509696027524e6ca3bda441efc37d4 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 00:34:52 -0300 Subject: [PATCH 19/34] fetch real xango scores from fundamental api --- main/app/wallet/positions.py | 33 ++++++++++++++++++++++++++++----- tests/test_wallet_buy_flag.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 5 deletions(-) diff --git a/main/app/wallet/positions.py b/main/app/wallet/positions.py index 5a6de68e..d7ba350e 100644 --- a/main/app/wallet/positions.py +++ b/main/app/wallet/positions.py @@ -1,8 +1,11 @@ import logging +import os from functools import lru_cache +import requests from sqlalchemy.orm import Session +from config import Config from main.app.wallet.market_data import fetchCachedClose, fetchLivePrices from main.app.wallet.wallets import getWallet from main.models.wallet import Holding, Target @@ -17,13 +20,33 @@ def fetchXangoScores(tickers: tuple[str, ...]) -> dict[str, float | None]: """XANGO quality score per ticker (0-100 scale). - Stub: no HTTP score endpoint exists on STOCKS yet, so every ticker - returns None and scoreBuyFlag redistributes the xango weight over the - other inputs (flag degrades, never fails). When a real cached-score - surface lands, only this body changes. Shared lru_cache is the + One fundamental read per ticker; any per-ticker failure degrades to + None and scoreBuyFlag redistributes the xango weight over the other + inputs (flag degrades, never fails). Shared lru_cache is the freshness story; no staleness gate beyond it, YAGNI. """ - return {ticker: None for ticker in tickers} + scores: dict[str, float | None] = {} + for ticker in tickers: + try: + key = os.getenv("STOCKS_API_KEY", "") + resp = requests.get( + f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/fundamental", + params={"search": ticker, "fields": "XANGO INVESTING SCORE", "compact": False}, # type: ignore[arg-type] + headers={"X-API-Key": key} if key else {}, + timeout=3, + ) + if resp.status_code != 200: + scores[ticker] = None + continue + payload = resp.json()["data"] + row = payload[0] if payload else None + if isinstance(row, dict) and "XANGO INVESTING SCORE" in row: + scores[ticker] = float(row["XANGO INVESTING SCORE"]) + else: + scores[ticker] = None + except Exception: + scores[ticker] = None + return scores def scoreBuyFlag( diff --git a/tests/test_wallet_buy_flag.py b/tests/test_wallet_buy_flag.py index 92f3a9e4..e2961d46 100644 --- a/tests/test_wallet_buy_flag.py +++ b/tests/test_wallet_buy_flag.py @@ -96,6 +96,34 @@ def test_backtest_fewer_false_flips_than_p1(): assert tuned_flips < p1_flips +def test_fetch_xango_scores_parses_fundamental(monkeypatch): + positions.fetchXangoScores.cache_clear() + + def fundamental_ok(url, params=None, headers=None, timeout=None): + assert url.endswith("/stocks/fundamental") + assert params["search"] == "PETR4" + assert params["fields"] == "XANGO INVESTING SCORE" + + class Resp: + status_code = 200 + + @staticmethod + def json(): + return {"data": [{"TICKER": "PETR4", "XANGO INVESTING SCORE": 80.0}]} + + return Resp() + + def boom(url, params=None, headers=None, timeout=None): + raise requests.Timeout() + + monkeypatch.setattr(requests, "get", fundamental_ok) + assert positions.fetchXangoScores(("PETR4",)) == {"PETR4": 80.0} + positions.fetchXangoScores.cache_clear() + monkeypatch.setattr(requests, "get", boom) + assert positions.fetchXangoScores(("PETR4",)) == {"PETR4": None} + positions.fetchXangoScores.cache_clear() + + def test_ratings_route_untouched(): raw = open("main/controller/wallet_controller.py", "rb").read().splitlines(keepends=True)[151:159] digest = hashlib.sha256(b"".join(raw)).hexdigest() From 5f6a9589ec29c6af12d284a4fe1d2a4ef4aab7d5 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 00:50:16 -0300 Subject: [PATCH 20/34] replace buy flag with weight-share rebalance model --- main/app/wallet/entries.py | 10 +- main/app/wallet/positions.py | 139 +++++++++--------- main/app/wallet/summary.py | 2 +- main/controller/wallet_controller.py | 9 ++ tests/test_wallet_buy_flag.py | 212 ++++++++++++++++++++------- tests/test_wallet_summary.py | 8 +- 6 files changed, 257 insertions(+), 123 deletions(-) diff --git a/main/app/wallet/entries.py b/main/app/wallet/entries.py index a9fcfdb2..b007cdd5 100644 --- a/main/app/wallet/entries.py +++ b/main/app/wallet/entries.py @@ -66,8 +66,16 @@ def recalcHolding(db: Session, walletId: int, ticker: str) -> Holding | None: quantity, avg = applyEntries(0.0, 0.0, entries) if holding is None: + from main.app.wallet import positions as positionsModule + + xangoScore = positionsModule.fetchXangoScores((ticker,)).get(ticker) holding = Holding( - walletId=walletId, assetType=entries[0].assetType, ticker=ticker, quantity=quantity, avgPrice=avg + walletId=walletId, + assetType=entries[0].assetType, + ticker=ticker, + quantity=quantity, + avgPrice=avg, + rating=xangoScore if xangoScore is not None else 10.0, # type: ignore[assignment] ) db.add(holding) diff --git a/main/app/wallet/positions.py b/main/app/wallet/positions.py index d7ba350e..1aeb7acd 100644 --- a/main/app/wallet/positions.py +++ b/main/app/wallet/positions.py @@ -8,13 +8,10 @@ from config import Config from main.app.wallet.market_data import fetchCachedClose, fetchLivePrices from main.app.wallet.wallets import getWallet -from main.models.wallet import Holding, Target +from main.models.wallet import Holding logger = logging.getLogger(__name__) -XANGO_WEIGHTS = {"underweight": 0.45, "rating": 0.25, "xango": 0.20, "momentum": 0.10} -BUY_THRESHOLD = 0.5 - @lru_cache(maxsize=1024) def fetchXangoScores(tickers: tuple[str, ...]) -> dict[str, float | None]: @@ -49,57 +46,14 @@ def fetchXangoScores(tickers: tuple[str, ...]) -> dict[str, float | None]: return scores -def scoreBuyFlag( - percentWallet: float, - percentIdeal: float | None, - holdingRating: int | None, - xangoScore: float | None, - appreciation: float | None, -) -> bool: - """XANGO-informed buy flag (pure function, deterministic, no learned params). - - percentIdeal arrives on the 0-100 wire scale and is normalized to a - fraction once at the comparison point. A None/NaN xangoScore is skipped - and its weight redistributed proportionally over the other three inputs. - XANGO informs the flag only — it never writes the manual rating. - """ - if percentIdeal is None: - return False - percentIdealFrac = percentIdeal / 100 - underweight = max(0.0, (percentIdealFrac - percentWallet) / max(percentIdealFrac, 1e-9)) - underweight = min(1.0, underweight) - if holdingRating is None: - ratingInput = 0.5 - else: - ratingInput = min(1.0, max(0.0, (holdingRating - 5) / 5)) - if xangoScore is None or xangoScore != xangoScore: # None or NaN → skip input - xangoInput: float | None = None - else: - xangoInput = min(1.0, max(0.0, xangoScore / 100)) - if appreciation is None: - momentumInput = 0.5 - elif appreciation > 0: - momentumInput = 1.0 - elif appreciation < 0: - momentumInput = 0.0 - else: - momentumInput = 0.5 - weights = XANGO_WEIGHTS - if xangoInput is None: - score = ( - weights["underweight"] * underweight + weights["rating"] * ratingInput + weights["momentum"] * momentumInput - ) / (1.0 - weights["xango"]) - else: - score = ( - weights["underweight"] * underweight - + weights["rating"] * ratingInput - + weights["xango"] * xangoInput - + weights["momentum"] * momentumInput - ) - return score >= BUY_THRESHOLD +def weightOf(holding: Holding) -> float: + return float(holding.rating) if holding.rating is not None else 0.0 -def getPositions(db: Session, walletId: int, userId: int) -> dict: +def pricePass( + db: Session, walletId: int, userId: int +) -> tuple[list[Holding], dict[str, float | None], dict[str, float | None], float]: + """Shared live-price/equity pass for positions + rebalance (single source, no duplication).""" getWallet(db, walletId, userId) holdings = db.query(Holding).filter(Holding.walletId == walletId).all() @@ -111,17 +65,34 @@ def getPositions(db: Session, walletId: int, userId: int) -> dict: equities: dict[str, float | None] = {} for holding in holdings: - holdingQuantity = float(holding.quantity) - holdingAvg = float(holding.avgPrice) price = prices.get(str(holding.ticker)) + equities[str(holding.ticker)] = float(holding.quantity) * price if price is not None else None - if price is None: - equities[str(holding.ticker)] = None + equityTotal = sum(equity for equity in equities.values() if equity is not None) + return holdings, prices, equities, equityTotal + + +def rebalanceDeltas( + holdings: list[Holding], equities: dict[str, float | None], equityTotal: float +) -> dict[str, float | None]: + """Weight-share deltas on backend floats: target_i = w_i/Σw, targetEquity = target_i × equityTotal, delta = targetEquity − equity. Σw=0 → all deltas null.""" + weightTotal = sum(weightOf(holding) for holding in holdings) + deltas: dict[str, float | None] = {} + for holding in holdings: + ticker = str(holding.ticker) + equity = equities.get(ticker) + if not weightTotal or equity is None: + deltas[ticker] = None else: - equities[str(holding.ticker)] = holdingQuantity * price + deltas[ticker] = weightOf(holding) / weightTotal * equityTotal - equity + return deltas - equityTotal = sum(equity for equity in equities.values() if equity is not None) - xangoScores = fetchXangoScores(tuple(tickers)) + +def getPositions(db: Session, walletId: int, userId: int) -> dict: + from main.models.wallet import Target + + holdings, prices, equities, equityTotal = pricePass(db, walletId, userId) + deltas = rebalanceDeltas(holdings, equities, equityTotal) items = [] for holding in holdings: @@ -146,14 +117,8 @@ def getPositions(db: Session, walletId: int, userId: int) -> dict: .first() ) percentIdeal = float(target.percentIdeal) if target is not None else None - holdingRating = holding.rating - buyFlag = scoreBuyFlag( - percentWallet, - percentIdeal, - holdingRating, # type: ignore[arg-type] - xangoScores.get(str(holding.ticker)), - appreciation, - ) + delta = deltas[str(holding.ticker)] + buyFlag = delta is not None and delta > 0 items.append( { "ticker": holding.ticker, @@ -168,3 +133,41 @@ def getPositions(db: Session, walletId: int, userId: int) -> dict: } ) return {"items": items, "equity_total": equityTotal} + + +def getRebalance(db: Session, walletId: int, userId: int) -> dict: + holdings, prices, equities, equityTotal = pricePass(db, walletId, userId) + deltas = rebalanceDeltas(holdings, equities, equityTotal) + weightTotal = sum(weightOf(holding) for holding in holdings) + + items = [] + for holding in holdings: + ticker = str(holding.ticker) + weightFloat = weightOf(holding) + # Display rounds to int; all math above stays on backend floats. + weight = int(round(weightFloat)) + targetPct = (weightFloat / weightTotal) if weightTotal else 0.0 + equity = equities[ticker] + currentPct = (equity / equityTotal) if equity is not None and equityTotal else 0.0 + delta = deltas[ticker] + price = prices.get(ticker) + if delta is None or price is None: + deltaEquity = None + deltaQty = None + side = "hold" + else: + deltaEquity = delta + deltaQty = delta / price + side = "buy" if delta > 0 else "sell" if delta < 0 else "hold" + items.append( + { + "ticker": holding.ticker, + "weight": weight, + "target_pct": targetPct, + "current_pct": currentPct, + "delta_equity": deltaEquity, + "delta_qty": deltaQty, + "side": side, + } + ) + return {"items": items, "equity_total": equityTotal} diff --git a/main/app/wallet/summary.py b/main/app/wallet/summary.py index be01596c..974bf30a 100644 --- a/main/app/wallet/summary.py +++ b/main/app/wallet/summary.py @@ -24,7 +24,7 @@ class TargetUpsert(BaseModel): class RatingUpsert(BaseModel): wallet_id: int ticker: str - rating: int = Field(ge=0, le=10) + rating: float = Field(ge=0, le=100) def getSummary(db: Session, walletId: int, userId: int) -> dict: diff --git a/main/controller/wallet_controller.py b/main/controller/wallet_controller.py index c5a97a94..b43b0372 100644 --- a/main/controller/wallet_controller.py +++ b/main/controller/wallet_controller.py @@ -115,6 +115,15 @@ def list_positions_route( return positions.getPositions(db, wallet_id, userId) +@router.get("/rebalance", response_class=ORJSONResponse) +def get_rebalance_route( + wallet_id: int, + userId: int, + db: Session = Depends(getSession), +): + return positions.getRebalance(db, wallet_id, userId) + + @router.get("/summary", response_class=ORJSONResponse) def get_summary_route( wallet_id: int, diff --git a/tests/test_wallet_buy_flag.py b/tests/test_wallet_buy_flag.py index e2961d46..e9136660 100644 --- a/tests/test_wallet_buy_flag.py +++ b/tests/test_wallet_buy_flag.py @@ -5,14 +5,124 @@ import main.models.wallet # noqa: F401 import main.app.wallet.positions as positions +from main.models.wallet import Holding from tests.conftest import make_wallet_client from tests.test_wallet_positions import _live_ok -RATINGS_ROUTE_DIGEST = "daa1b74d65a934abd9b12923ca8031785b20461470061b77394d14613e184e63" # sha256 of set_rating_route handler bytes (main/controller/wallet_controller.py:152-159), re-pinned at deauth time (auth-removal-only change verified) +RATINGS_ROUTE_DIGEST = "3a050b055866190a8142ddaca2ce916efd864d31496d90b959043c4ba484e334" -def test_buy_flag_scale_fixed_and_weights(dbSession, monkeypatch): - monkeypatch.setattr(requests, "get", _live_ok) # PETR4 @ 30.0, Task 7 fake +def _live_two(url, params=None, headers=None, timeout=None): + quotes = {"PETR4": 30.0, "VALE3": 10.0} + + class Resp: + status_code = 200 + + @staticmethod + def json(): + return {"data": [{"TICKER": params["search"], "PRECO ATUAL": quotes[params["search"]]}]} + + assert params["search"] in quotes + return Resp() + + +def _seed_two(client, walletId): + for ticker in ("PETR4", "VALE3"): + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": ticker, + "date": "2026-01-10", + "quantity": 10, + "price": 10.0, + }, + ) + + +def test_buy_flag_follows_delta_sign(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_two) + monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {ticker: 50.0 for ticker in tickers}) + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + _seed_two(client, walletId) + # Equities: PETR4 300, VALE3 100, total 400. Ratings 75/25 → targets 300/100 → flat. + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 75}) + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "VALE3", "rating": 25}) + byTicker = {item["ticker"]: item for item in client.get(f"/wallet/positions?wallet_id={walletId}").json()["items"]} + assert byTicker["PETR4"]["buy_flag"] is False + assert byTicker["VALE3"]["buy_flag"] is False + # Re-rate VALE3 to 50 → targets PETR4 240 / VALE3 160 → sell PETR4, buy VALE3. + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "VALE3", "rating": 50}) + byTicker = {item["ticker"]: item for item in client.get(f"/wallet/positions?wallet_id={walletId}").json()["items"]} + assert byTicker["PETR4"]["buy_flag"] is False + assert byTicker["VALE3"]["buy_flag"] is True + + +def test_zero_weights_all_hold(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_two) + monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {ticker: None for ticker in tickers}) + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + _seed_two(client, walletId) + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 0}) + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "VALE3", "rating": 0}) + body = client.get(f"/wallet/rebalance?wallet_id={walletId}").json() + for item in body["items"]: + assert item["delta_equity"] is None + assert item["delta_qty"] is None + assert item["side"] == "hold" + for item in client.get(f"/wallet/positions?wallet_id={walletId}").json()["items"]: + assert item["buy_flag"] is False + + +def test_rebalance_weight_share_math(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_two) + monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {ticker: 50.0 for ticker in tickers}) + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + _seed_two(client, walletId) + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 75}) + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "VALE3", "rating": 50}) + body = client.get(f"/wallet/rebalance?wallet_id={walletId}").json() + assert body["equity_total"] == pytest.approx(400.0) + byTicker = {item["ticker"]: item for item in body["items"]} + assert byTicker["PETR4"]["weight"] == 75 + assert byTicker["PETR4"]["target_pct"] == pytest.approx(0.6) + assert byTicker["PETR4"]["current_pct"] == pytest.approx(0.75) + assert byTicker["PETR4"]["delta_equity"] == pytest.approx(-60.0) + assert byTicker["PETR4"]["delta_qty"] == pytest.approx(-2.0) + assert byTicker["PETR4"]["side"] == "sell" + assert byTicker["VALE3"]["weight"] == 50 + assert byTicker["VALE3"]["target_pct"] == pytest.approx(0.4) + assert byTicker["VALE3"]["current_pct"] == pytest.approx(0.25) + assert byTicker["VALE3"]["delta_equity"] == pytest.approx(60.0) + assert byTicker["VALE3"]["delta_qty"] == pytest.approx(6.0) + assert byTicker["VALE3"]["side"] == "buy" + + +def test_rebalance_deterministic(dbSession, monkeypatch): + # Weight-share is a pure function of ratings + prices: same inputs → same outputs. + monkeypatch.setattr(requests, "get", _live_two) + monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {ticker: 50.0 for ticker in tickers}) + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + _seed_two(client, walletId) + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 75}) + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "VALE3", "rating": 50}) + first = client.get(f"/wallet/rebalance?wallet_id={walletId}").json() + second = client.get(f"/wallet/rebalance?wallet_id={walletId}").json() + assert first == second + assert sum(item["target_pct"] for item in first["items"]) == pytest.approx(1.0) + assert sum(item["delta_equity"] for item in first["items"] if item["delta_equity"] is not None) == pytest.approx( + 0.0 + ) + + +def test_new_holding_seeds_xango_score(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_ok) monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {"PETR4": 80.0}) client, _, _ = make_wallet_client(db=dbSession) walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] @@ -28,16 +138,28 @@ def test_buy_flag_scale_fixed_and_weights(dbSession, monkeypatch): "price": 10.0, }, ) - client.put( - "/wallet/targets", - json={"wallet_id": walletId, "key_kind": "ticker", "key_value": "PETR4", "percent_ideal": 50.0}, + holding = dbSession.query(Holding).filter(Holding.walletId == walletId, Holding.ticker == "PETR4").first() + assert float(holding.rating) == pytest.approx(80.0) + # Later entries never touch the rating: manual 42 survives another Compra. + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 42}) + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-11", + "quantity": 5, + "price": 12.0, + }, ) - item = client.get(f"/wallet/positions?wallet_id={walletId}").json()["items"][0] - assert item["percent_wallet"] == pytest.approx(1.0) - assert item["buy_flag"] is False # 100% held vs 50% ideal → overweight, no buy + dbSession.expire_all() + holding = dbSession.query(Holding).filter(Holding.walletId == walletId, Holding.ticker == "PETR4").first() + assert float(holding.rating) == pytest.approx(42.0) -def test_xango_none_degrades_to_p1_rule(dbSession, monkeypatch): +def test_new_holding_defaults_ten_without_xango(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _live_ok) monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {"PETR4": None}) client, _, _ = make_wallet_client(db=dbSession) @@ -54,46 +176,36 @@ def test_xango_none_degrades_to_p1_rule(dbSession, monkeypatch): "price": 10.0, }, ) - client.put( - "/wallet/targets", - json={"wallet_id": walletId, "key_kind": "ticker", "key_value": "PETR4", "percent_ideal": 50.0}, + holding = dbSession.query(Holding).filter(Holding.walletId == walletId, Holding.ticker == "PETR4").first() + assert float(holding.rating) == pytest.approx(10.0) + + +def test_ratings_accept_zero_to_hundred(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_ok) + client, _, _ = make_wallet_client(db=dbSession) + walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] + client.post( + "/wallet/entries", + json={ + "wallet_id": walletId, + "side": "Compra", + "asset_type": "Stock", + "ticker": "PETR4", + "date": "2026-01-10", + "quantity": 10, + "price": 10.0, + }, + ) + assert client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 100}).json() == { + "ticker": "PETR4", + "rating": 100, + } + assert ( + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 0}).status_code == 200 + ) + assert ( + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 101}).status_code == 422 ) - item = client.get(f"/wallet/positions?wallet_id={walletId}").json()["items"][0] - assert item["buy_flag"] is False # same verdict without XANGO — degradation, not failure - - -def test_backtest_fewer_false_flips_than_p1(): - # Seeded checkpoint series: steady climb, 50% ideal, rating 8, XANGO 80. - # flips = checkpoints emitting True. P1 (scale bug: fraction vs 0-100) is True - # at all 5 checkpoints; the tuned flag clears once overweight and stays clear. - checkpoints = [ - {"percentWallet": 0.10, "percentIdeal": 50.0, "holdingRating": 8, "xangoScore": 80.0, "appreciation": 5.0}, - {"percentWallet": 0.30, "percentIdeal": 50.0, "holdingRating": 8, "xangoScore": 80.0, "appreciation": 15.0}, - {"percentWallet": 0.60, "percentIdeal": 50.0, "holdingRating": 8, "xangoScore": 80.0, "appreciation": 40.0}, - {"percentWallet": 0.90, "percentIdeal": 50.0, "holdingRating": 8, "xangoScore": 80.0, "appreciation": 80.0}, - {"percentWallet": 1.00, "percentIdeal": 50.0, "holdingRating": 8, "xangoScore": 80.0, "appreciation": 100.0}, - ] - p1_flags = [ - checkpoint["percentIdeal"] is not None - and checkpoint["percentWallet"] < checkpoint["percentIdeal"] - and (checkpoint["holdingRating"] is None or checkpoint["holdingRating"] >= 6) - for checkpoint in checkpoints - ] - tuned_flags = [ - positions.scoreBuyFlag( - checkpoint["percentWallet"], - checkpoint["percentIdeal"], - checkpoint["holdingRating"], - checkpoint["xangoScore"], - checkpoint["appreciation"], - ) - for checkpoint in checkpoints - ] - p1_flips = sum(1 for flag in p1_flags if flag) - tuned_flips = sum(1 for flag in tuned_flags if flag) - assert p1_flips == 5 # scale bug: always True - assert tuned_flags == [True, True, False, False, False] - assert tuned_flips < p1_flips def test_fetch_xango_scores_parses_fundamental(monkeypatch): @@ -125,6 +237,6 @@ def boom(url, params=None, headers=None, timeout=None): def test_ratings_route_untouched(): - raw = open("main/controller/wallet_controller.py", "rb").read().splitlines(keepends=True)[151:159] + raw = open("main/controller/wallet_controller.py", "rb").read().splitlines(keepends=True)[161:169] digest = hashlib.sha256(b"".join(raw)).hexdigest() assert digest == RATINGS_ROUTE_DIGEST # any edit to set_rating_route fails loudly diff --git a/tests/test_wallet_summary.py b/tests/test_wallet_summary.py index 303f3e32..8da8abc0 100644 --- a/tests/test_wallet_summary.py +++ b/tests/test_wallet_summary.py @@ -77,9 +77,11 @@ def test_targets_drive_buy_flag_and_ratings_gate(dbSession, monkeypatch): "rating": 8, } assert ( - client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 11}).status_code == 422 + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 100}).status_code == 200 + ) + assert ( + client.put("/wallet/ratings", json={"wallet_id": walletId, "ticker": "PETR4", "rating": 101}).status_code == 422 ) item = client.get(f"/wallet/positions?wallet_id={walletId}").json()["items"][0] - # P3-1 scale fix: 100% held vs 80% ideal is overweight → no buy - # (old P1 rule compared fraction 1.0 < 80.0, nearly-always-True). + # Weight-share: single holding owns 100% of both weight and equity → delta 0 → hold. assert item["percent_ideal"] == 80.0 and item["buy_flag"] is False From 78e03c4da0e2a364385de9972f6d49f87a3d004f Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 00:52:06 -0300 Subject: [PATCH 21/34] !! --- TODO.md | 4 + graphify-out/.graphify_labels.json | 16 +- graphify-out/GRAPH_REPORT.md | 522 +- graphify-out/graph.json | 22198 ++++++++++++++++++--------- graphify-out/manifest.json | 135 +- main/app/scraper_b3/scraper.py | 11 +- main/app/stocks_api/sync_cache.py | 3 +- main/app/wallet/market_data.py | 10 +- main/app/wallet/wallet_service.py | 78 - main/app/wallet/wallets.py | 2 - 10 files changed, 15297 insertions(+), 7682 deletions(-) delete mode 100644 main/app/wallet/wallet_service.py diff --git a/TODO.md b/TODO.md index 06ef7a4d..e4182662 100644 --- a/TODO.md +++ b/TODO.md @@ -12,6 +12,10 @@ - [ ] the scraper rentability should be calculated based on the COTACOA 10Y AJUSTADA instead of the tradingview endpoint - [ ] add MACD, RSI and other metrics +- [ ] notification system (redis!!!!) +- [ ] beta and alpha measurements in the wallet (possible advanced mode setting for quant bros and fin bros) +- [ ] wallet asset correlation + - [ ] Use the ForgeVM architecture to expose MetaTrader5 terminals - [ ] Abacate Pay diff --git a/graphify-out/.graphify_labels.json b/graphify-out/.graphify_labels.json index cb727242..8839fa49 100644 --- a/graphify-out/.graphify_labels.json +++ b/graphify-out/.graphify_labels.json @@ -619,7 +619,21 @@ "617": "Community 617", "618": "Community 618", "619": "Community 619", + "620": "Community 620", "621": "Community 621", + "622": "Community 622", "623": "Community 623", - "624": "Community 624" + "624": "Community 624", + "625": "Community 625", + "626": "Community 626", + "627": "Community 627", + "628": "Community 628", + "629": "Community 629", + "630": "Community 630", + "631": "Community 631", + "632": "Community 632", + "633": "Community 633", + "634": "Community 634", + "635": "Community 635", + "636": "Community 636" } diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md index f75b4f62..877a9982 100644 --- a/graphify-out/GRAPH_REPORT.md +++ b/graphify-out/GRAPH_REPORT.md @@ -1,16 +1,16 @@ -# Graph Report - server (2026-09-30) +# Graph Report - server (2026-10-01) ## Corpus Check -- 137 files · ~103,322 words +- 153 files · ~122,017 words - Verdict: corpus is large enough that graph structure adds value. ## Summary -- 6650 nodes · 8904 edges · 623 communities (380 shown, 243 thin omitted) -- Extraction: 85% EXTRACTED · 15% INFERRED · 0% AMBIGUOUS · INFERRED: 1335 edges (avg confidence: 0.69) +- 6906 nodes · 9406 edges · 637 communities (400 shown, 237 thin omitted) +- Extraction: 84% EXTRACTED · 16% INFERRED · 0% AMBIGUOUS · INFERRED: 1475 edges (avg confidence: 0.68) - Token cost: 0 input · 0 output ## Graph Freshness -- Built from commit: `9cfa467f` +- Built from commit: `5f6a9589` - Run `git rev-parse HEAD` and compare to check if the graph is stale. - Run `graphify update .` after code changes (no API cost). @@ -621,9 +621,23 @@ - [[_COMMUNITY_Community 617|Community 617]] - [[_COMMUNITY_Community 618|Community 618]] - [[_COMMUNITY_Community 619|Community 619]] +- [[_COMMUNITY_Community 620|Community 620]] - [[_COMMUNITY_Community 621|Community 621]] +- [[_COMMUNITY_Community 622|Community 622]] - [[_COMMUNITY_Community 623|Community 623]] - [[_COMMUNITY_Community 624|Community 624]] +- [[_COMMUNITY_Community 625|Community 625]] +- [[_COMMUNITY_Community 626|Community 626]] +- [[_COMMUNITY_Community 627|Community 627]] +- [[_COMMUNITY_Community 628|Community 628]] +- [[_COMMUNITY_Community 629|Community 629]] +- [[_COMMUNITY_Community 630|Community 630]] +- [[_COMMUNITY_Community 631|Community 631]] +- [[_COMMUNITY_Community 632|Community 632]] +- [[_COMMUNITY_Community 633|Community 633]] +- [[_COMMUNITY_Community 634|Community 634]] +- [[_COMMUNITY_Community 635|Community 635]] +- [[_COMMUNITY_Community 636|Community 636]] ## God Nodes (most connected - your core abstractions) 1. `vocab` - 456 edges @@ -657,7 +671,7 @@ - **Configuration & Database Infrastructure** — config_Config, config_engine, config_stocksEngine [INFERRED] - **User Authentication & Authorization** — user_service, authentication, user_roles, permission_system [INFERRED] -## Communities (623 total, 243 thin omitted) +## Communities (637 total, 237 thin omitted) ### Community 0 - "Stocks API Endpoints" Cohesion: 0.0 @@ -716,20 +730,16 @@ Cohesion: 0.06 Nodes (31): code:python ("""Measure whether the stocks query hot path is GIL-bound.), code:bash (git add main/utils/migrator.py tests/test_migrator_guard.py), code:python (import importlib), code:python (DB_POOL_SIZE = int(os.getenv("DB_POOL_SIZE", "20"))), code:bash (git add config.py tests/test_config_pools.py), code:python (import importlib), code:python (if __name__ == "__main__":), code:python (if len(instances) > 1 and fcntl is None: # pragma: no cover) (+23 more) ### Community 14 - "User Roles & Permissions" -Cohesion: 0.05 -Nodes (35): _make_stocksapi_client(), Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental. (+27 more) +Cohesion: 0.06 +Nodes (30): _make_stocksapi_client(), Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont, Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont, Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont (+22 more) ### Community 15 - "Community 15" Cohesion: 0.05 Nodes (38): code:block1 (User 123: "Analyze PETR4 vs VALE3 correlation"), code:python (from main.app.prometheus.sandbox import SandboxManager), code:python (TOOL_REGISTRY: dict[str, Any] = {), code:bash (git add main/app/prometheus/tools.py tests/test_sandbox_tool), code:python (import pytest), code:python (from main.app.prometheus.sandbox import SandboxManager), code:python (async def streamMessage(self, query=None, sessionId=None, db), code:python (## Code Sandbox (On-Demand)) (+30 more) -### Community 16 - "Community 16" -Cohesion: 0.15 -Nodes (18): executeStateTool(), get_state(), Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, test_dispatch_get_state(), test_dispatch_set_state() (+10 more) - ### Community 17 - "Community 17" -Cohesion: 0.05 -Nodes (40): Invalid date -> inner 400 passes through (not wrapped as 500)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., search.strip() == '' should still dedup (line 181)., search.strip() == '' should still dedup (line 181)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500. (+32 more) +Cohesion: 0.07 +Nodes (26): Two dates in the range, both valid., Two dates in the range, both valid., Two dates in the range, both valid., Two dates in the range, both valid., Search with no index match falls back to string startswith., Search with no index match falls back to string startswith., search.strip() == '' should still dedup (line 181)., Search with no index match falls back to string startswith. (+18 more) ### Community 18 - "Community 18" Cohesion: 0.07 @@ -744,12 +754,12 @@ Cohesion: 0.06 Nodes (35): 1. Memory System (B+), 2. Summarizer/Episodes (B), 3. Loop Events (A-), 4. Core Architecture (B+), 5. Security (B+), 6. Performance (B), 7. Code Quality (B), After (B+) (+27 more) ### Community 21 - "Community 21" -Cohesion: 0.1 -Nodes (9): B3Scraper, getCurrentSelic(), getInitialData(), calculateInvestingScore(), initialize(), P5: register the scraper cron jobs on the shared scheduler. Kept in this, registerScraperJobs(), runScraper() (+1 more) +Cohesion: 0.15 +Nodes (13): benchOnce(), main(), batchCosineSimilarity(), decodeEmbeddings(), normalizeRows(), Empty matrix → empty array., Single row matches cosine_similarity., Multiple rows ranked correctly. (+5 more) ### Community 22 - "Community 22" -Cohesion: 0.14 -Nodes (7): filterCotationColumn(), Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., TestQueryLiveCotation +Cohesion: 0.07 +Nodes (19): filterCotationColumn(), Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., GET /stocks/realtime-cotation without search returns 422., GET /cotations without search returns 422. (+11 more) ### Community 23 - "Community 23" Cohesion: 0.07 @@ -760,16 +770,16 @@ Cohesion: 0.09 Nodes (5): Tests for agent <-> persistent sandbox integration (Task 3)., Verify the agent uses getOrCreate + syncToSandbox/syncFromSandbox., Test the premium gating logic used in streamMessage., TestPersistentSandboxLifecycle, TestPremiumCheck ### Community 25 - "Community 25" -Cohesion: 0.12 -Nodes (7): Tests for input validation via HTTP endpoints. Validation is now inline via Bod, PUT /prometheus/sessions/{sessionId} — validates title via Body(...), Test that endpoints reject requests with missing required fields., POST /prometheus/sessions — validates title via Body(...), TestMissingBody, TestPrometheusSessionValidation, TestUpdateTitleValidation +Cohesion: 0.06 +Nodes (13): Tests for input validation via HTTP endpoints. Validation is now inline via Bod, PUT /prometheus/sessions/{sessionId} — validates title via Body(...), POST /prometheus/chat/stream — validates query via Body(...), POST /auth/register — validates username, email, password via Body(...), Test that endpoints reject requests with missing required fields., POST /auth/login — validates username, password via Body(...), POST /prometheus/sessions — validates title via Body(...), TestChatValidation (+5 more) ### Community 26 - "Community 26" -Cohesion: 0.11 -Nodes (21): generateKey(), createKey(), _hash_key(), hashKey(), Return SHA-256 hex digest of the given key., Test that concurrent requests are properly serialized at DB level. Th, Test edge case: request exactly at quota limit., Test edge case: request exactly at quota limit. (+13 more) +Cohesion: 0.09 +Nodes (24): createKey(), _hash_key(), hashKey(), Return SHA-256 hex digest of the given key., Test that concurrent requests are properly serialized at DB level. Th, Test edge case: request exactly at quota limit., Test edge case: request exactly at quota limit., Test that invalid API key returns zero rows affected. (+16 more) ### Community 27 - "Community 27" -Cohesion: 0.16 -Nodes (14): getRelevanceScore(), _FakeMemory, A memory with no lastAccessedAt should use baseScore as-is., Scores are deterministic — no cron mutation needed., Same memory at different points in time yields different scores., A memory accessed 10x (baseScore 1.0) should still outrank a memory acce, A rarely-used old memory should lose to a popular fresh one., With same access time, higher baseScore always wins. (+6 more) +Cohesion: 0.15 +Nodes (15): getUserMemories(), getRelevanceScore(), _FakeMemory, A memory with no lastAccessedAt should use baseScore as-is., Scores are deterministic — no cron mutation needed., Same memory at different points in time yields different scores., A memory accessed 10x (baseScore 1.0) should still outrank a memory acce, A rarely-used old memory should lose to a popular fresh one. (+7 more) ### Community 28 - "Community 28" Cohesion: 0.05 @@ -816,8 +826,8 @@ Cohesion: 0.07 Nodes (27): code:json ([), code:javascript (const loadHistory = async (sid) => {), code:jsx (export default function MessageList({ messages, toolEvents, ), code:javascript (const loadHistory = async (sid) => {), code:jsx (export default function AgentLoop({ toolEvents, turnMetrics ), code:bash (git add frontend/src/App.jsx frontend/src/components/Message), code:bash (docker-compose up -d --build), code:sql (SELECT COUNT(*) FROM prometheus WHERE JSON_CONTAINS_PATH(his) (+19 more) ### Community 39 - "Community 39" -Cohesion: 0.11 -Nodes (17): Multiple search terms with tickerIndex., Multiple search terms with tickerIndex., Multiple search terms with tickerIndex., Search with no index match falls back to string startswith., Search with no index match falls back to string startswith., Search with no index match falls back to string startswith., Multiple search terms with tickerIndex., Multiple search terms with tickerIndex. (+9 more) +Cohesion: 0.06 +Nodes (31): Invalid date -> inner 400 passes through (not wrapped as 500)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., search.strip() == '' should still dedup (line 181)., search.strip() == '' should still dedup (line 181)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500. (+23 more) ### Community 40 - "Community 40" Cohesion: 0.12 @@ -828,20 +838,20 @@ Cohesion: 0.07 Nodes (32): API endpoints, Authentication Management, code:bash (curl http://localhost:3200/auth/health), code:bash (curl -X POST "http://localhost:3200/auth/register" \), code:bash (curl -X POST "http://localhost:3200/auth/login" \), code:bash (curl -X POST "http://localhost:3200/auth/logout" \), code:bash (# Browser redirect; redirect_url optional, else Referer head), code:mermaid (graph TD) (+24 more) ### Community 42 - "Community 42" -Cohesion: 0.09 -Nodes (16): StocksCacheManager, Tests for dynamic ticker index feature, Ticker index should be built when cache is loaded, Ticker index should contain all tickers from cache, Ticker index should be case-insensitive, Looking up ticker should return valid row index, Ticker index should be rebuilt when cache refreshes, TestTickerIndex (+8 more) +Cohesion: 0.06 +Nodes (23): StocksCacheManager, Tests for dynamic ticker index feature, Ticker index should be built when cache is loaded, Ticker index should contain all tickers from cache, Ticker index should be case-insensitive, Looking up ticker should return valid row index, Ticker index should be rebuilt when cache refreshes, TestTickerIndex (+15 more) ### Community 43 - "Community 43" Cohesion: 0.15 -Nodes (5): authenticateUser(), hashPassword(), verifyPassword(), TestAuthUtil, TestAuthUtilEdgeCases +Nodes (6): authenticateUser(), createUserAccount(), hashPassword(), verifyPassword(), TestAuthUtil, TestAuthUtilEdgeCases ### Community 44 - "Community 44" Cohesion: 0.14 Nodes (3): UserSession, TestSessionExpiration, TestUserSessionModel ### Community 45 - "Community 45" -Cohesion: 0.05 -Nodes (58): BaseModel, IntFlag, OrunmilaMemory, Orunmila, OrunmilaChatManager, MemoryCandidate, OrunmilaMemory, SandboxManager (+50 more) +Cohesion: 0.07 +Nodes (24): Covers line 28: GET /auth/health., Covers line 28: GET /auth/health., Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers line 13: UserManager.__init__., Covers line 13: UserManager.__init__. (+16 more) ### Community 46 - "Community 46" Cohesion: 0.09 @@ -872,12 +882,12 @@ Cohesion: 0.08 Nodes (7): Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., TestPrometheusChatManager ### Community 53 - "Community 53" -Cohesion: 0.11 -Nodes (29): charCount(), countTokens(), getTokenizer(), applyUpdate(), archiveDead(), clearAll(), clearAllAsync(), count_memories() (+21 more) +Cohesion: 0.13 +Nodes (25): archiveDead(), clearAll(), clearAllAsync(), count_memories(), decayScores(), deleteMemory(), deleteMemoryAsync(), _fulltext_search() (+17 more) ### Community 54 - "Community 54" -Cohesion: 0.38 -Nodes (9): compactCotations(), compactRow(), compactValue(), compressResponse(), fixHeaders(), getAbbr(), getNest(), toColumnar() (+1 more) +Cohesion: 0.17 +Nodes (25): add_entry(), _apply_entries(), _cachedPerformance(), create_wallet(), delete_entry(), fetchCachedClose(), fetchLivePrices(), fetchMarketDividends() (+17 more) ### Community 55 - "Community 55" Cohesion: 0.11 @@ -892,8 +902,8 @@ Cohesion: 0.09 Nodes (15): Performance benchmark tests for stocks API, Performance benchmark tests for stocks API, Ticker index lookup should be O(1) - very fast, Ticker index lookup should be O(1) - very fast, Prefix scan should be much slower than index lookup, Prefix scan should be much slower than index lookup, Index lookup should be significantly faster than scan, Index lookup should be significantly faster than scan (+7 more) ### Community 58 - "Community 58" -Cohesion: 0.15 -Nodes (17): getGoogleSSO(), createAccessToken(), googleCallback(), googleLogin(), isSecureScheme(), issueSessionCookie(), login(), logout() (+9 more) +Cohesion: 0.22 +Nodes (13): createAccessToken(), googleCallback(), isSecureScheme(), issueSessionCookie(), login(), logout(), register(), requireServiceToken() (+5 more) ### Community 59 - "Community 59" Cohesion: 0.17 @@ -903,17 +913,13 @@ Nodes (20): Tests for main/utils/connectivity.py — covers all branches., test_ Cohesion: 0.09 Nodes (7): Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., TestSessionManager -### Community 61 - "Community 61" -Cohesion: 0.13 -Nodes (4): PrometheusSession, User, TestPrometheusSessionModel, TestUserModel - ### Community 62 - "Community 62" Cohesion: 0.1 Nodes (20): architectures, attention_probs_dropout_prob, gradient_checkpointing, hidden_act, hidden_dropout_prob, hidden_size, initializer_range, intermediate_size (+12 more) ### Community 63 - "Community 63" -Cohesion: 0.21 -Nodes (6): normalizeKey(), Store a value in state. Marks state as changed for context injection., Shared query pipeline for historical and fundamental endpoints., Fetch live prices for B3 tickers via yfinance. B3 tickers must match, sanitizeNanValues(), StocksQueryManager +Cohesion: 0.19 +Nodes (7): Shared query pipeline for historical and fundamental endpoints., Fetch live prices for B3 tickers via yfinance. B3 tickers must match, sanitizeNanValues(), StocksQueryManager, Tests for lazy JSON deserialization, Query manager should have deserialize method, TestLazyDeserialization ### Community 64 - "Community 64" Cohesion: 0.06 @@ -928,12 +934,12 @@ Cohesion: 0.1 Nodes (19): 1. Explore Agent — Prometheus Architecture, 2. MySQL Vector Storage (Researcher), 3. Memory Patterns (Researcher), A. Vector Embedding Integration, B. Pandas-First Vector Cache, C. Search Upgrade, code:python (class MemoryCache:), code:python (def searchMemories(cls, db, userId, query, embedding=None, l) (+11 more) ### Community 67 - "Community 67" -Cohesion: 0.17 -Nodes (7): Verify memory endpoints exist and are wired correctly., GET /prometheus/memories exists., POST /prometheus/memories exists., DELETE /prometheus/memories/{id} exists., GET /memories requires authentication., GET /memories requires USE_PROMETHEUS (basic USER role denied)., TestMemoryControllerRoutes +Cohesion: 0.12 +Nodes (15): execute_code(), list_files(), Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, List files in the workspace directory. Args: path: Directory pat, List files in the workspace directory. Args: path: Directory pat (+7 more) ### Community 68 - "Community 68" -Cohesion: 0.23 -Nodes (6): chat_stream(), downloadWorkspaceFile(), getHistory(), resumeChatStream(), updateSessionTitle(), verifySessionOwnsership() +Cohesion: 0.14 +Nodes (30): narrate_positions(), Narrate the user's wallet positions in plain language. Read-only summary, addEntry(), applyEntries(), cachedPerformance(), createWallet(), deleteEntry(), fetchCachedClose() (+22 more) ### Community 69 - "Community 69" Cohesion: 0.22 @@ -948,8 +954,8 @@ Cohesion: 0.11 Nodes (19): API Key System, B3 Scraper, Fundamental Data, Gemini Model, Historical Data, Ma'at Stock Algorithm, Mansa Server, MySQL Database (+11 more) ### Community 72 - "Community 72" -Cohesion: 0.13 -Nodes (16): pack → unpack preserves values., Empty list roundtrips., 384-dim vector packs to 1536 bytes., Empty matrix → empty array., Single row matches cosine_similarity., Multiple rows ranked correctly., Zero query → all zeros., TestBatchCosineSimilarity (+8 more) +Cohesion: 0.24 +Nodes (5): lifespan(), status(), checkDatabaseConnection(), checkSingleDb(), runMigrations() ### Community 73 - "Community 73" Cohesion: 0.16 @@ -980,24 +986,24 @@ Cohesion: 0.05 Nodes (44): cn(), AlertDialogAction(), AlertDialogCancel(), AlertDialogContent(), AlertDialogDescription(), AlertDialogFooter(), AlertDialogHeader(), AlertDialogMedia() (+36 more) ### Community 80 - "Community 80" -Cohesion: 0.15 -Nodes (16): buildSummary(), dedup(), extractDecisions(), extractMetrics(), extractSnapshots(), extractTickers(), extractToolCalls(), fetchFieldsPayload() (+8 more) +Cohesion: 0.21 +Nodes (15): buildSummary(), dedup(), extractDecisions(), extractMetrics(), extractSnapshots(), extractTickers(), extractToolCalls(), fetchFieldsPayload() (+7 more) ### Community 81 - "Community 81" -Cohesion: 0.09 -Nodes (17): getLiveCotation(), JSONBytesResponse, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Sends pre-serialized JSON bytes without re-encoding (cache-friendly)., Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th (+9 more) +Cohesion: 0.14 +Nodes (14): getLiveCotation(), Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th (+6 more) ### Community 82 - "Community 82" -Cohesion: 0.09 -Nodes (27): buildFeatherCache(), Feather build / read helpers for the stocks cache. Owns the on-disk layout (CAC, Return (engine, featherPath, nestedPath), preferring live values on the cach, Return (engine, featherPath, nestedPath), preferring live values on the cach, readFeatherDataFrame(), _runtimeConf(), tryBuildLock(), arrowTypeFor() (+19 more) +Cohesion: 0.13 +Nodes (16): arrowTypeFor(), buildCotationDateIndex(), buildFeatherCache(), buildTickerIndex(), optimizeDtypes(), P1: establish the sorted-cache invariant once at load/refresh. Sorts by (, P1: first-occurrence index over a sortCacheFrame-sorted frame. The cache, Get cached stocks data with optional column filtering. (+8 more) ### Community 83 - "Community 83" Cohesion: 0.1 Nodes (21): B3 Market Scraper, Brazilian Stocks Market Scraper, code:env (SCRAPER_ENABLED=FALSE # default False), code:json ({), Configuration Parameters, Constraint Engine ($\Lambda$), Engines, Fundamental Engine ($\Phi$) (+13 more) ### Community 84 - "Community 84" -Cohesion: 0.14 -Nodes (12): chat(), chat_stream(), createSession(), downloadWorkspaceFile(), _forward(), getHistory(), Verify the user owns the session, raise 403 otherwise., Verify the user owns the session, raise 403 otherwise. (+4 more) +Cohesion: 0.11 +Nodes (16): chat(), chat_stream(), create_memory(), createMemory(), createSession(), downloadWorkspaceFile(), _forward(), getHistory() (+8 more) ### Community 85 - "Community 85" Cohesion: 0.21 @@ -1040,8 +1046,8 @@ Cohesion: 0.12 Nodes (16): 10. Splits — served prices are RAW by default (verified verdict, encode as-is), 11. Dividends — no dedicated endpoint (verified verdict, encode as-is), 12. Corporate actions — splits and grupamentos via one read-time mechanism, 13. Dividend methodology — ex-date smoothing check (both branches, test decides), 1. Context, 2. Decision: Design A — pure event log, derive at read time, 3. Data model (user_db, alembic), 4. Derivations (all at read time, date order) (+8 more) ### Community 95 - "Community 95" -Cohesion: 0.17 -Nodes (5): Tests for StocksCacheManager queryCache LRU eviction., Create a StocksCacheManager with a mock DB engine., When columns is None, cache key should be None., TestCacheLRUEviction, TestCacheTTLLogic +Cohesion: 0.15 +Nodes (9): memoryMaintenance(), Decay applies to ALL active memories, not just accessed ones., Decay applies to ALL active memories, not just accessed ones., baseScore should never reach exactly 0 from decay alone., baseScore should never reach exactly 0 from decay alone., TestDecay, _create(), After 10 cycles, preference (0.99^10) > context (0.90^10). (+1 more) ### Community 96 - "Community 96" Cohesion: 0.2 @@ -1052,36 +1058,36 @@ Cohesion: 0.15 Nodes (16): AuthenticationManager, AuthenticationService, PrometheusChatManager, PrometheusGenerator, PrometheusService, SessionManager, UserManager, UserService (+8 more) ### Community 98 - "Community 98" -Cohesion: 0.28 +Cohesion: 0.25 Nodes (6): extractTokenPayload(), Tests for extractTokenPayload — the standalone token extraction dependency., Create a mock Starlette Request with given headers., Authorization: Bearer (empty) — no token after Bearer., Authorization: Basic xxx — not Bearer, so no token found., TestExtractTokenPayload ### Community 99 - "Community 99" -Cohesion: 0.04 -Nodes (47): _make_prometheus_client(), Covers lines 95-98: session deleted., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 95-98: DELETE /prometheus/sessions/{sessionId}., Covers lines 95-98: session deleted., Covers lines 96-97: session not found. (+39 more) +Cohesion: 0.06 +Nodes (29): _make_prometheus_client(), Return (client, app) with prometheus router and mocked deps., Covers lines 33-36: GET /prometheus/sessions., Covers lines 33-36: GET /prometheus/sessions., Covers lines 33-36: GET /prometheus/sessions., Covers line 52: POST /prometheus/sessions., Covers line 52: POST /prometheus/sessions., Covers line 52: POST /prometheus/sessions. (+21 more) ### Community 100 - "Community 100" Cohesion: 0.16 Nodes (6): _assert_gemini_safe(), Assert a tool function has only Gemini-compatible parameter types., Assert a tool function has only Gemini-compatible parameter types., test_get_state_no_state_returns_error(), test_tool_has_gemini_safe_signature(), TestStateToolFunctions ### Community 101 - "Community 101" -Cohesion: 0.07 -Nodes (18): Different query parameters should not share cache, Cache should expire after TTL, Tests for connection pool configuration, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Query manager should have deserialize method, Performance tests for query operations, Query should respond within 1 second (+10 more) +Cohesion: 0.17 +Nodes (7): Different query parameters should not share cache, Cache should expire after TTL, Tests for query result caching, CacheManager should track cached queries, Query cache should have configurable TTL, getCachedStocks should support column filtering, TestQueryCaching ### Community 102 - "Community 102" -Cohesion: 0.15 -Nodes (8): BaseSettings, BaseMansaSettings, DiscordSettings, MysqlSettings, OrunmilaSettings, ScraperSettings, StocksApiSettings, UserSettings +Cohesion: 0.11 +Nodes (11): BaseSettings, BaseMansaSettings, DiscordSettings, MysqlSettings, OrunmilaSettings, PrometheusSettings, ScraperSettings, StocksApiSettings (+3 more) ### Community 103 - "Community 103" Cohesion: 0.13 Nodes (14): 10. Performance, 11. Testing, 12. Risks, 13. Out of Scope (YAGNI), 14. Open Questions, 1. Executive Summary, 2. Context & Motivation, 5. Architecture Decision (+6 more) ### Community 104 - "Community 104" -Cohesion: 0.2 -Nodes (14): benchOnce(), main(), _fulltext_search(), fullTextSearch(), minMax(), scoreCandidates(), scoreRecency(), scoreRow() (+6 more) +Cohesion: 0.12 +Nodes (14): code:python (XANGO_WEIGHTS = {"underweight": 0.45, "rating": 0.25, "xango), code:python (import hashlib), code:bash (git add main/app/wallet/wallet_service.py tests/test_wallet_), code:python (async def narrate_positions(wallet_id: int, **_) -> dict:), code:python (import asyncio), code:bash (git add main/app/orunmila/tools.py tests/test_orunmila_walle), Finding-(9) charter-gap note, Global Constraints (+6 more) ### Community 105 - "Community 105" -Cohesion: 0.21 -Nodes (7): ResultCache — SHA256-keyed file-based cache for computed results., File-based cache keyed by SHA256 of code. Stores results as JSON under:, Return cached result dict or None if miss., Store result with timestamp., Delete all cached results for a session., Check if a result exists for the given code., ResultCache +Cohesion: 0.29 +Nodes (5): buildClient(), connect(), ensureFastmcp(), MCPClientPool, _parseServers() ### Community 106 - "Community 106" Cohesion: 0.22 @@ -1125,7 +1131,7 @@ Nodes (11): dateOnly(), EditDividendDialog(), EditLotDialog(), fmtBRL(), fmtMone ### Community 116 - "Community 116" Cohesion: 0.13 -Nodes (16): _build_system_prompt(), buildSystemPrompt(), chatSession(), _execute_memory_tool(), _get_client(), _get_memory_tools(), getClient(), openMCPClients() (+8 more) +Nodes (17): _build_system_prompt(), buildSystemPrompt(), chatSession(), _execute_memory_tool(), executeMemoryTool(), _get_client(), _get_memory_tools(), getClient() (+9 more) ### Community 117 - "Community 117" Cohesion: 0.15 @@ -1140,8 +1146,8 @@ Cohesion: 0.07 Nodes (26): code:python ("""Tests for SandboxManager file mutation helpers (delete_fi), code:python (from main.app.prometheus.sandbox import SandboxManager, host), code:python (@router.post("/workspace/upload")), code:bash (git add main/controller/prometheus_controller.py tests/test_), code:python (from unittest.mock import patch, MagicMock), code:python (from main.app.prometheus.sandbox import SandboxManager, host), code:python (async def serve_file(path: str, **_) -> dict:), code:python ("serve_file": serve_file,) (+18 more) ### Community 120 - "Community 120" -Cohesion: 0.07 -Nodes (44): _make_auth_client(), Tests to cover uncovered lines across controllers, UserManager, and auth util., Return (client, app) with auth + user routers and mocked getSession., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 126, 131, 135-136., Covers lines 126-136: DELETE /user/sessions/{sessionId}. (+36 more) +Cohesion: 0.1 +Nodes (32): _make_auth_client(), Tests to cover uncovered lines across controllers, UserManager, and auth util., Covers lines 44-54, 63, 66-71: register success, ValueError, generic Exception., Covers lines 44-54, 63, 66-71: register success, ValueError, generic Exception., Covers lines 87-93, 102: login success and failure paths., Covers lines 87-93, 102: login success and failure paths., Return (client, app) with auth + user routers and mocked getSession., Covers lines 107, 109-130, 133: logout token extraction and revocation. (+24 more) ### Community 121 - "Community 121" Cohesion: 0.21 @@ -1159,9 +1165,13 @@ Nodes (12): Appendix A: Codebase Findings, code:block6 (D:\Repositories\server\) Cohesion: 0.07 Nodes (27): code:python (# tests/test_stocks_payload_cache.py), code:python (pc = self.cacheManager.tickerPayloads), code:python (# tests/test_stocks_sync_handlers.py), code:bash (git add main/controller/stocksapi_controller.py main/app/sto), code:python (def test_payload_cache_cotation_index():), code:python (self._cotations: dict[str, bytes] = {}), code:python (cotationCols = ["TICKER", "NOME", "TIME", "COTACAO 10Y PADRA), code:python (self._cotations = cot) (+19 more) +### Community 125 - "Community 125" +Cohesion: 0.13 +Nodes (3): PrometheusSession, createSession(), TestPrometheusSessionModel + ### Community 126 - "Community 126" Cohesion: 0.07 -Nodes (26): code:powershell (netstat -ano | findstr ":80 " # must be empty; if not, ), code:powershell ($U = "http://localhost/stocks/cotations?search=PETR4"), code:nginx (proxy_pass http://stocks_api;), code:nginx (# Exact-match on purpose: a prefix match on /stocks/cotation), code:powershell (docker exec nginx nginx -t; if ($?) { docker exec nginx ngin), code:bash (git add nginx/conf.d/20-stocks.conf nginx/snippets/stocks-pr), code:powershell (docker stats --no-stream --format "{{.Name}},{{.CPUPerc}},{{), code:powershell ($U = "http://localhost/stocks/cotations?search=PETR4") (+18 more) +Nodes (26): code:powershell (netstat -ano | findstr ":80 " # must be empty; if not, ), code:powershell ($U = "http://localhost/stocks/cotations?search=PETR4"), code:nginx (proxy_pass http://stocks_api;), code:nginx (# Exact-match on purpose: a prefix match on /stocks/cotation), code:powershell (docker exec nginx nginx -t; if ($?) { docker exec nginx ngin), code:bash (git add nginx/conf.d/20-stocks.conf nginx/snippets/stocks-pr), code:powershell (docker stats --no-stream --format "{{.Name}},{{.CPUPerc}},{{), code:powershell ($env:PERF_API_KEY="sk-..." # all three make targets below ) (+18 more) ### Community 127 - "Community 127" Cohesion: 0.2 @@ -1176,12 +1186,12 @@ Cohesion: 0.2 Nodes (10): Tests for stocks API field validation — verifies the fields parameter accepts a, Integration: /stocks/fundamental must accept slash and dot fields., Minimal TestClient with just the stocks router for validation tests., GET /fundamental?fields=P/L must not return 422 (validation error)., GET /fundamental?fields=P/L must not return 422 (validation error)., Integration: /stocks/fundamental must accept slash and dot fields., GET /fundamental?fields=P/L must not return 422 (validation error)., GET /historical?fields=P/L must not return 422. (+2 more) ### Community 130 - "Community 130" -Cohesion: 0.08 -Nodes (25): 1.1 Functional (per surface; tags: EXISTS = build on it, PARTIAL = half reusable, MISSING = greenfield), 1.2 Non-functional, 1. Requirements, 2. Domain model, 3. API contracts (all under `/api/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout), 3. API contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout), 4. Phased build plan (writing-plans: each phase independently reviewable; reviewer PASS per phase), 5. Risks / assumptions (honest flags carried over — do not treat as fact) (+17 more) +Cohesion: 0.07 +Nodes (27): 1.1 Functional (per surface; tags: EXISTS = build on it, PARTIAL = half reusable, MISSING = greenfield), 1.2 Non-functional, 1. Requirements, 2. Domain model, 3. API contracts (all under `/api/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout), 3. API contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout), 3. API contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth = wallet-local dependency on the **introspect contract** (user directive 2026-09-30): resolve the raw token (`X-Access-Token` → `Authorization: Bearer` → `mansa_token` cookie, order per `main/app/authentication/util.py:54-66`) → `introspectToken(db, raw)` (`main/app/authentication/introspect.py:14`) → `{userId, username, roles}` → `Roles.checkAccess(roles, Permission.WALLET)` (`main/utils/roles.py:29-39`) → `403` if absent; `Depends(getSession)` for the DB session), 4. Phased build plan (writing-plans: each phase independently reviewable; reviewer PASS per phase) (+19 more) ### Community 131 - "Community 131" -Cohesion: 0.14 -Nodes (13): Same input → same hash., Different inputs → different hashes., Returns 32-char hex string., TestContentHash, ALL(), _extractCredential(), _introspectUrl(), introspectUser() (+5 more) +Cohesion: 0.11 +Nodes (17): Same input → same hash., Different inputs → different hashes., Returns 32-char hex string., pack → unpack preserves values., Empty list roundtrips., 384-dim vector packs to 1536 bytes., TestContentHash, TestPackUnpack (+9 more) ### Community 132 - "Community 132" Cohesion: 0.25 @@ -1196,16 +1206,16 @@ Cohesion: 0.18 Nodes (11): code:yaml (volumes:), code:bash (git add config.py docker-compose.yml), code:python (import pytest), code:python (import logging), code:bash (git add main/app/prometheus/sandbox.py tests/test_sandbox.py), code:python (class PrometheusSettings(BaseMansaSettings):), code:yaml (environment:), code:yaml (sandbox:) (+3 more) ### Community 135 - "Community 135" -Cohesion: 0.11 -Nodes (4): cache(), Tests for ResultCache., TestColumnValidator, TestResultCache +Cohesion: 0.05 +Nodes (16): ResultCache — SHA256-keyed file-based cache for computed results., File-based cache keyed by SHA256 of code. Stores results as JSON under:, Return cached result dict or None if miss., Store result with timestamp., Delete all cached results for a session., Check if a result exists for the given code., ResultCache, cache() (+8 more) ### Community 136 - "Community 136" -Cohesion: 0.12 -Nodes (10): Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Tests covering query.py lines 50-67., Tests covering query.py lines 50-67., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Tests covering query.py lines 50-67., Tests covering query.py lines 50-67. (+2 more) +Cohesion: 0.18 +Nodes (12): _getDb(), Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use (+4 more) ### Community 137 - "Community 137" -Cohesion: 0.18 -Nodes (20): countMemories(), deleteMemory(), extract(), findSimilarKey(), fullTextSearch(), getClient(), getMatrix(), getMemoryLimit() (+12 more) +Cohesion: 0.05 +Nodes (50): OrunmilaSession, buildSystemPrompt(), getClient(), Orunmila, persistEvent(), createSession(), buildSummary(), countTokens() (+42 more) ### Community 138 - "Community 138" Cohesion: 0.18 @@ -1216,8 +1226,8 @@ Cohesion: 0.24 Nodes (6): Dataset, produce_data(), Train script for a single file Need to set the TPU address first: export XRT_TP, A class that handles the reddit data files, A class that handles one dataset, RedditDataset ### Community 140 - "Community 140" -Cohesion: 0.04 -Nodes (51): Base, PrometheusMemory, PrometheusMemory, OrunmilaSandbox, MemoryManager, PrometheusMemory, All memory operations. Stateless class methods., PrometheusService (+43 more) +Cohesion: 0.07 +Nodes (36): PrometheusMemory, PrometheusMemory, MemoryManager, PrometheusMemory, All memory operations. Stateless class methods., PrometheusService, TestDifferentKeysNoMerge, TestExactSameKeyUpdates (+28 more) ### Community 141 - "Community 141" Cohesion: 0.24 @@ -1260,8 +1270,8 @@ Cohesion: 0.2 Nodes (3): MEMORY_TOOLS must be defined as a Tool wrapping FunctionDeclarations., MEMORY_TOOLS must be a list of callables with proper signatures., TestMemoryToolsDefinition ### Community 152 - "Community 152" -Cohesion: 0.18 -Nodes (12): _getDb(), Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use (+4 more) +Cohesion: 0.14 +Nodes (25): FastAPI, listEarnings(), syncEarnings(), addEntry(), applyEntries(), deleteEntry(), listEntries(), positionAtDate() (+17 more) ### Community 153 - "Community 153" Cohesion: 0.11 @@ -1300,8 +1310,8 @@ Cohesion: 0.11 Nodes (18): Category 2: Async/Sync Inconsistencies (MEDIUM), Category 4: Caching & Memory (MEDIUM), Category 6: Configuration & Environment (LOW), Category 7: Code Quality (LOW), Executive Summary, Full Code Review Report, Issue 2.1 — All route handlers are synchronous, Issue 2.2 — ServiceManager runs uvicorn in daemon threads (+10 more) ### Community 162 - "Community 162" -Cohesion: 0.24 -Nodes (14): buildSummary(), countTokens(), dedup(), extractDecisions(), extractMetrics(), extractSnapshots(), extractTickers(), extractToolCalls() (+6 more) +Cohesion: 0.12 +Nodes (10): Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Tests covering query.py lines 50-67., Tests covering query.py lines 50-67., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Tests covering query.py lines 50-67., Tests covering query.py lines 50-67. (+2 more) ### Community 163 - "Community 163" Cohesion: 0.22 @@ -1336,7 +1346,7 @@ Cohesion: 0.25 Nodes (8): padding, direction, pad_id, pad_to_multiple_of, pad_token, pad_type_id, strategy, Fixed ### Community 172 - "Community 172" -Cohesion: 0.14 +Cohesion: 0.12 Nodes (19): AuthenticationManager, SessionManager, PrometheusChatManager, Cover getGoogleSSO (lines 6-14)., Cover getGoogleSSO (lines 6-14)., Cover __init__ and updateDates., Cover __init__ and updateDates (lines 22-37)., Cover streamMessage in agent.py. (+11 more) ### Community 173 - "Community 173" @@ -1380,13 +1390,17 @@ Cohesion: 0.14 Nodes (14): 3.0 Verified ground truth, 3.10 Migration sequence + verification, 3.1 Target topology, 3.2 Worker-container extraction, 3.3 nginx upstream evolution — validated against the user's plan, 3.4 TODO 13 migration — drop `{service}_HOST`/`{service}_PORT`, 3.5 Redis — exactly two jobs, 3.6 Cache strategy across boxes (+6 more) ### Community 184 - "Community 184" -Cohesion: 0.33 -Nodes (4): Integration tests for all query optimizations, All optimizations should be implemented, Query filter should use ticker index, TestQueryOptimization +Cohesion: 0.14 +Nodes (9): Verify that getSession() returns per-thread Session instances., Calling getSession() twice in the same thread returns the same object., Two threads must NOT share a Session object., With 20 concurrent threads, every thread must get its own Session., The returned object must be a real requests.Session., TestGetSession, get_session(), Return a requests.Session for the current thread. Sessions are created la (+1 more) ### Community 185 - "Community 185" Cohesion: 0.38 Nodes (7): code:python (import pytest), code:python (from __future__ import annotations), code:bash (git add main/app/prometheus/context.py tests/test_context.py), Phase 4: ToolContext (Bundled Dispatch Dependencies), Phase 4: ToolContext (Replace God Function), Task 5: ToolContext — Dataclass for Agent Use, Task 5: ToolContext — Single Dispatch Object +### Community 186 - "Community 186" +Cohesion: 0.07 +Nodes (4): Tests for inline pagination params (used in user + prometheus controllers)., TestInlinePagination, TestPaginationParams, PaginationParams + ### Community 187 - "Community 187" Cohesion: 0.25 Nodes (7): DEVELOPER:, PREMIUM:, Priorities (active order, 2026-09-29), Prometheus, STOCKS_API, USER:, User structure defined by string roles: @@ -1396,8 +1410,8 @@ Cohesion: 0.11 Nodes (6): Tests for run.py /status endpoint — covers status response structure., Create a test client for the status endpoint without running lifespan., Create a test client for the status endpoint without running lifespan., statusClient(), TestScraperTrigger, TestStatusEndpoint ### Community 189 - "Community 189" -Cohesion: 0.36 -Nodes (4): countTokens(), getTokenizer(), PrometheusSummarizer, smartTruncate() +Cohesion: 0.33 +Nodes (3): buildClient(), connect(), MCPClientPool ### Community 190 - "Community 190" Cohesion: 0.29 @@ -1416,8 +1430,8 @@ Cohesion: 0.33 Nodes (6): normalizer, clean_text, handle_chinese_chars, lowercase, strip_accents, type ### Community 194 - "Community 194" -Cohesion: 0.21 -Nodes (15): compactCotations(), compactRow(), compactValue(), compressResponse(), fixHeaders(), getAbbr(), getNest(), Abbreviation map for a frame (dependency-injected; no cache import). Result (+7 more) +Cohesion: 0.18 +Nodes (11): listFields(), Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental. (+3 more) ### Community 195 - "Community 195" Cohesion: 0.33 @@ -1520,12 +1534,12 @@ Cohesion: 0.4 Nodes (5): model, continuing_subword_prefix, max_input_chars_per_word, type, unk_token ### Community 221 - "Community 221" -Cohesion: 0.2 -Nodes (9): Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148. (+1 more) +Cohesion: 0.16 +Nodes (14): execute_code(), Store a value in the harness state for this session. Use this to save inter, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis, (+6 more) ### Community 222 - "Community 222" -Cohesion: 0.18 -Nodes (11): listFields(), Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental. (+3 more) +Cohesion: 0.19 +Nodes (17): charCount(), countTokens(), getTokenizer(), applyUpdate(), countMemories(), countTokensCached(), extract(), findSimilarKey() (+9 more) ### Community 223 - "Community 223" Cohesion: 0.4 @@ -1559,6 +1573,10 @@ Nodes (5): code:python (import pytest), code:python (import hashlib), code:bash Cohesion: 0.18 Nodes (11): 2.2.1 Complexity hotspots table (H1–H17 condensed to P0/P1/P2), 2.2.2 Blob inventory (LOC table + SRP evidence), 2.2.3 Mass data loads, 2.2.4 Phased fix roadmap (P0/P1/P2), §2.2 CODE EFFICIENCY — O(n²), Complexity & Blob Anti-Patterns, code:block4 (scraper.py:44 671 LOC — mass loads: SELECT * fetchma), code:powershell (ruff check . && ruff format --check .), code:powershell (pytest tests/test_stocks_cache_concurrency.py -v # ThreadPo) (+3 more) +### Community 231 - "Community 231" +Cohesion: 0.15 +Nodes (11): _count_memories(), _create_memory(), _get_memory(), Keys with Jaccard > 0.8 should merge., Keys with Jaccard > 0.8 should merge., Keys with low similarity should not merge., Keys with low similarity should not merge., Keys with low similarity should not merge. (+3 more) + ### Community 232 - "Community 232" Cohesion: 0.4 Nodes (5): Bucket A: Security Fixes (quick wins, 30 min), Bucket B: DB Session Cleanup (medium, 1-2 hrs), Bucket C: Testing (medium, 2-3 hrs), Bucket D: Infrastructure (large, 4+ hrs), Recommended Delegation Buckets @@ -1568,8 +1586,8 @@ Cohesion: 0.4 Nodes (5): 8. Build Sequence (4 phases, each independently shippable), Phase 0 — Sandbox foundation (1-2 days, no user-facing change), Phase 1 — MCP exposure of STOCKS_API (1 day), Phase 2 — Refactor PROMETHEUS to agentic (3-5 days, the big one), Phase 3 — Hardening (1-2 days, can ship incrementally) ### Community 234 - "Community 234" -Cohesion: 0.32 -Nodes (14): create(), delete_file(), destroy(), execute(), getClient(), getOrCreate(), hostPath(), list_files() (+6 more) +Cohesion: 0.11 +Nodes (25): chat_stream(), downloadWorkspaceFile(), getHistory(), resumeChatStream(), updateSessionTitle(), verifySessionOwnsership(), OrunmilaSandbox, create() (+17 more) ### Community 236 - "Community 236" Cohesion: 0.5 @@ -1616,8 +1634,8 @@ Cohesion: 0.5 Nodes (4): Category 5: Error Handling Gaps (MEDIUM), Issue 5.1 — Generic exception handler swallows traceback in production, Issue 5.2 — DiscordHandler sends only message, not traceback, Issue 5.3 — `_build_error_response` ignores `status_code` parameter ### Community 251 - "Community 251" -Cohesion: 0.17 -Nodes (6): pytest_configure(), Set required env vars before test collection. config.py eagerly instantia, Reset slowapi in-memory rate limiter between every test., Set required env vars before test collection. config.py eagerly instantia, Set required env vars before test collection. config.py eagerly instantia, _reset_rate_limiter() +Cohesion: 0.29 +Nodes (11): compactCotations(), compactRow(), compactValue(), compressResponse(), fixHeaders(), getAbbr(), getNest(), Abbreviation map for a frame (dependency-injected; no cache import). Result (+3 more) ### Community 252 - "Community 252" Cohesion: 0.5 @@ -1660,8 +1678,8 @@ Cohesion: 0.22 Nodes (8): 1. Prime owns the goal, lanes own the work, 2. Dispatch: `delegate()`, one per lane, one turn, 3. Delegate toolsets vary — verify each lane, 4. Trust nothing — verify everything, 5. Windows PowerShell survival, 6. Finish per lane, not per swarm, 7. Standing bans (this repo), SWARMS.md — subagent swarm playbook (OpenCode / Hermes) ### Community 474 - "Community 474" -Cohesion: 0.17 -Nodes (4): POST /memories rejects missing key., POST /memories rejects missing value., Full integration tests using mocked MemoryManager., TestMemoryEndpointsIntegration +Cohesion: 0.1 +Nodes (9): B3Scraper, getCurrentSelic(), getInitialData(), calculateInvestingScore(), initialize(), P5: register the scraper cron jobs on the shared scheduler. Kept in this, registerScraperJobs(), runScraper() (+1 more) ### Community 475 - "Community 475" Cohesion: 0.15 @@ -1691,6 +1709,10 @@ Nodes (4): code:python (def test_extract_temporal_info():), code:python (# main/ Cohesion: 0.5 Nodes (4): code:python (def test_session_scoped_memory(db_session, sample_user):), code:python (# Add to main/models/memory.py), code:bash (git add main/models/memory.py main/app/prometheus/memory.py ), Task 8: Session Scoping +### Community 482 - "Community 482" +Cohesion: 0.23 +Nodes (13): fetchXangoScores(), getPositions(), getRebalance(), pricePass(), XANGO quality score per ticker (0-100 scale). One fundamental read per tick, XANGO quality score per ticker (0-100 scale). One fundamental read per tick, XANGO-informed buy flag (pure function, deterministic, no learned params)., Shared live-price/equity pass for positions + rebalance (single source, no dupli (+5 more) + ### Community 483 - "Community 483" Cohesion: 0.5 Nodes (4): code:python (def test_consolidation_preserves_decisions():), code:python (# Add to main/app/prometheus/summarizer.py), code:bash (git add main/app/prometheus/summarizer.py tests/test_consoli), Task 9: Memory Consolidation @@ -1720,16 +1742,16 @@ Cohesion: 0.22 Nodes (8): API Endpoints, code:env (ORUNMILA_ENABLED=TRUE), code:bash (python run.py), code:mermaid (graph TD), License, Orunmila, Usage, Workflow ### Community 491 - "Community 491" -Cohesion: 0.1 -Nodes (4): Tests for main/utils/roles.py — covers requirePermission and edge cases., TestCheckAccess, TestRequirePermission, TestRolesHierarchy +Cohesion: 0.08 +Nodes (6): Pytest Testing, Tests for main/utils/roles.py — covers requirePermission and edge cases., TestCheckAccess, TestPermissionAll, TestRequirePermission, TestRolesHierarchy ### Community 492 - "Community 492" Cohesion: 0.33 Nodes (5): Baseline (lane 4), Export recipe, Move triggers (any one fires the migration), Options, Vector Scale-Up Runbook ### Community 493 - "Community 493" -Cohesion: 0.05 -Nodes (37): Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC (+29 more) +Cohesion: 0.09 +Nodes (10): Verify memory endpoints exist and are wired correctly., GET /prometheus/memories exists., POST /memories rejects missing key., POST /memories rejects missing value., POST /prometheus/memories exists., DELETE /prometheus/memories/{id} exists., GET /memories requires authentication., Full integration tests using mocked MemoryManager. (+2 more) ### Community 495 - "Community 495" Cohesion: 0.05 @@ -1737,11 +1759,11 @@ Nodes (42): 0. The blockers, ranked, 1.1 Process model — exactly one process, ### Community 497 - "Community 497" Cohesion: 0.19 -Nodes (5): buildSystemPrompt(), getClient(), persistEvent(), OrunmilaCompactor, newTokenCache() +Nodes (11): buildFeatherCache(), Feather build / read helpers for the stocks cache. Owns the on-disk layout (CAC, Return (engine, featherPath, nestedPath), preferring live values on the cach, Return (engine, featherPath, nestedPath), preferring live values on the cach, readFeatherDataFrame(), _runtimeConf(), tryBuildLock(), arrowTypeFor() (+3 more) ### Community 498 - "Community 498" -Cohesion: 0.33 -Nodes (5): Tests for optimized search filtering, Filter should use ticker index for O(1) lookup, Tests for optimized search filtering, Filter should use ticker index for O(1) lookup, TestFilterBySearchTerms +Cohesion: 0.07 +Nodes (30): Covers lines 114-115: session ownership check fails., Covers lines 114-115: session ownership check fails., Covers lines 114-115: session ownership check fails., Covers lines 120-121: session ownership check fails., Covers lines 114-115: session ownership check fails., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136. (+22 more) ### Community 499 - "Community 499" Cohesion: 0.2 @@ -1756,16 +1778,12 @@ Cohesion: 0.22 Nodes (3): getCurrentSession(), getSessions(), sessionToDict() ### Community 502 - "Community 502" -Cohesion: 0.11 -Nodes (15): Tests for connection pool configuration, Tests for connection pool configuration, Stocks engine should have optimized pool settings, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Tests for lazy JSON deserialization, Query manager should have deserialize method, Query manager should have deserialize method (+7 more) +Cohesion: 0.2 +Nodes (7): Store a value in state. Marks state as changed for context injection., autoAbbreviate(), dedupAbbrev(), detectNestedFields(), generateAbbreviations(), TOOL_REGISTRY pattern must work correctly., TestToolRegistry ### Community 503 - "Community 503" -Cohesion: 0.17 -Nodes (7): Tests for dynamic ticker index feature, Ticker index should be built when cache is loaded, Ticker index should contain all tickers from cache, Ticker index should be case-insensitive, Looking up ticker should return valid row index, Ticker index should be rebuilt when cache refreshes, TestTickerIndex - -### Community 504 - "Community 504" Cohesion: 0.18 -Nodes (6): System prompt should include state context when provided., System prompt should not include state section when empty., State section should appear after memories section., All state entries should appear in the prompt., System prompt should work without state parameter., TestBuildSystemPromptState +Nodes (11): Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback. (+3 more) ### Community 505 - "Community 505" Cohesion: 0.33 @@ -1787,6 +1805,10 @@ Nodes (5): Disputed (already litigated — needs your ruling to proceed), Held o Cohesion: 0.6 Nodes (3): bench(), main(), stats() +### Community 511 - "Community 511" +Cohesion: 0.18 +Nodes (6): System prompt should include state context when provided., System prompt should not include state section when empty., State section should appear after memories section., All state entries should appear in the prompt., System prompt should work without state parameter., TestBuildSystemPromptState + ### Community 512 - "Community 512" Cohesion: 0.18 Nodes (11): 2.0 Grounding: what the code actually does, 2.1 Hypotheses, 2.3 Scenarios, 2.4 Protocol, 2.5 Metrics, 2.6 Acceptance thresholds — **ALL PROPOSED, freeze after first real run**, 2.7 Results doc layout, 2.8 Feeding `/status` (TODO 14) (+3 more) @@ -1796,32 +1818,32 @@ Cohesion: 0.2 Nodes (16): baseFrame(), deserializeJsonColumns(), envelope(), fetchLivePayload(), filterBySearchTerms(), _filterCotationByDate(), filterCotationData(), finalize() (+8 more) ### Community 518 - "Community 518" -Cohesion: 0.11 -Nodes (12): create_memories(), Zero access but score still above threshold → not archived., Already archived memories are skipped., Already archived memories are skipped., Helper to create memories with controlled baseScore, lastAccessedAt, accessCount, Helper to create memories with controlled baseScore, lastAccessedAt, accessCount, Decay applies to ALL active memories, not just accessed ones., Decay applies to ALL active memories, not just accessed ones. (+4 more) +Cohesion: 0.08 +Nodes (21): create_memories(), Zero access but score still above threshold → not archived., Even with low score, if accessed → not archived., Even with low score, if accessed → not archived., Already archived memories are skipped., Already archived memories are skipped., Decay happens first, then archive check with new scores., Decay happens first, then archive check with new scores. (+13 more) ### Community 519 - "Community 519" -Cohesion: 0.26 -Nodes (10): introspectToken(), verifyAccessToken(), introspect(), FastAPI, addRole(), addRoleToUser(), getCurrentUser(), getRolesList() (+2 more) +Cohesion: 0.57 +Nodes (6): addRole(), addRoleToUser(), getCurrentUser(), getRolesList(), hasRole(), toDict() ### Community 520 - "Community 520" Cohesion: 0.16 Nodes (9): pd.NA is not a string, so lambda returns it unchanged., All four SPECIAL_COLS should parse correctly when mixed with None., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., All four SPECIAL_COLS should parse correctly when mixed with None., All four SPECIAL_COLS should parse correctly when mixed with None. (+1 more) ### Community 521 - "Community 521" -Cohesion: 0.33 -Nodes (3): buildClient(), connect(), MCPClientPool +Cohesion: 0.15 +Nodes (18): executeStateTool(), get_state(), Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, test_dispatch_get_state(), test_dispatch_set_state() (+10 more) ### Community 522 - "Community 522" Cohesion: 0.18 Nodes (11): 2.0 Grounding: what the code actually does, 2.1 Hypotheses, 2.3 Scenarios, 2.4 Protocol, 2.5 Metrics, 2.6 Acceptance thresholds — **ALL PROPOSED, freeze after first real run**, 2.7 Results doc layout, 2.8 Feeding `/status` (TODO 14) (+3 more) ### Community 523 - "Community 523" -Cohesion: 0.24 -Nodes (5): lifespan(), status(), checkDatabaseConnection(), checkSingleDb(), runMigrations() +Cohesion: 0.38 +Nodes (9): compactCotations(), compactRow(), compactValue(), compressResponse(), fixHeaders(), getAbbr(), getNest(), toColumnar() (+1 more) ### Community 524 - "Community 524" -Cohesion: 0.11 -Nodes (17): Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers line 16: empty password raises ValueError., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 48-49: jwt.ExpiredSignatureError. (+9 more) +Cohesion: 0.36 +Nodes (4): countTokens(), getTokenizer(), PrometheusSummarizer, smartTruncate() ### Community 525 - "Community 525" Cohesion: 0.11 @@ -1831,13 +1853,13 @@ Nodes (21): list_files(), Write a file to the workspace. Use this to save data f Cohesion: 0.33 Nodes (7): buildKey(), clearAll(), getMatrix(), invalidateUser(), runAwait(), main(), One-shot: renormalize stored embeddings to unit norm. Usage: python scripts/back -### Community 528 - "Community 528" -Cohesion: 0.18 -Nodes (11): Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback. (+3 more) - ### Community 529 - "Community 529" -Cohesion: 0.33 -Nodes (6): dispatchToolCall must route memory tool names via TOOL_REGISTRY., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., TestDispatchRoutesMemoryTools +Cohesion: 0.29 +Nodes (6): Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404. + +### Community 530 - "Community 530" +Cohesion: 0.2 +Nodes (10): code:python (def test_compra_average_includes_costs(dbSession):), code:python (from datetime import date), code:bash (git add main/service/wallet_service.py main/controller/walle), code:bash (git add ), code:python (import main.models.wallet # noqa: F401), code:bash (git add migrations/env.py migrations/versions/_wallet_t), Review Focus, Task 3: Alembic revision for the wallet tables (needs MySQL) (+2 more) ### Community 532 - "Community 532" Cohesion: 0.5 @@ -1852,16 +1874,16 @@ Cohesion: 0.5 Nodes (4): LATER (P2 — when touching these files), NOW (P0 — fix before next release), Priority Matrix, SOON (P1 — fix within 2 weeks) ### Community 535 - "Community 535" -Cohesion: 0.18 -Nodes (11): client(), TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with stocks router + verifyAPIKey + getCurrentUser overrides., TestClient with all routers mounted — no lifespan (no DB/service init). O (+3 more) +Cohesion: 0.13 +Nodes (13): Covers lines 95-98: session deleted., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 95-98: DELETE /prometheus/sessions/{sessionId}., Covers lines 95-98: session deleted., Covers lines 96-97: session not found., Covers lines 95-98: DELETE /prometheus/sessions/{sessionId}. (+5 more) ### Community 536 - "Community 536" -Cohesion: 0.14 -Nodes (12): initialize(), P5: register memory maintenance on the shared scheduler. Kept in this ser, registerMemoryMaintenanceJob(), initialize(), P5: register the session-cleanup job on the shared scheduler. Kept in thi, registerSessionCleanupJobs(), UserService, getSharedScheduler() (+4 more) +Cohesion: 0.07 +Nodes (25): _downloadModel(), getEmbeddingModel(), AuthenticationService, initialize(), initialize(), OrunmilaService, initialize(), P5: register memory maintenance on the shared scheduler. Kept in this ser (+17 more) ### Community 538 - "Community 538" -Cohesion: 0.14 -Nodes (13): dispatchToolCall(), execute_code(), list_files(), Read a file from the workspace. Args: path: Path to the file (e., Write a file to the workspace. Use this to save data files (CSV, JSON, scri, List files in the workspace directory. Args: path: Directory pat, Get a download link for a workspace file to share with the user. Use this, Search user's saved memories, preferences, and past analysis context. Use (+5 more) +Cohesion: 0.22 +Nodes (4): Authentication System, Google OAuth, JWT Authentication, TestSessionExpiryConfig ### Community 539 - "Community 539" Cohesion: 0.22 @@ -1888,8 +1910,8 @@ Cohesion: 0.29 Nodes (7): code:python (def test_split_cliff_no_fake_loss_on_adjusted_series(monkeyp), code:python (def test_snapshot_includes_received_and_cash_gain(dbSession,), code:python (def test_history_merges_dividend_receipts(dbSession, sampleU), code:python (def test_ex_div_methodology_decides_received_stacking(dbSess), code:python (def ex_div_smoothing_verdict(padrao_before: float, padrao_af), code:bash (git add main/app/wallet/manager.py main/controller/wallet_co), Task 12: Split-cliff regression test + snapshot/history dividend extension + final gate ### Community 546 - "Community 546" -Cohesion: 0.16 -Nodes (14): execute_code(), Store a value in the harness state for this session. Use this to save inter, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis, (+6 more) +Cohesion: 0.18 +Nodes (11): Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers line 16: empty password raises ValueError., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 48-49: jwt.ExpiredSignatureError. (+3 more) ### Community 547 - "Community 547" Cohesion: 0.33 @@ -1945,15 +1967,19 @@ Nodes (4): code:python (import pytest), code:python (import logging), code:bash ### Community 560 - "Community 560" Cohesion: 0.22 -Nodes (4): Authentication System, Google OAuth, JWT Authentication, TestSessionExpiryConfig +Nodes (4): generateKey(), JSONBytesResponse, Sends pre-serialized JSON bytes without re-encoding (cache-friendly)., FastAPIResponse + +### Community 561 - "Community 561" +Cohesion: 0.09 +Nodes (17): client(), pytest_configure(), TestClient with all routers mounted — no lifespan (no DB/service init). O, Set required env vars before test collection. config.py eagerly instantia, Reset slowapi in-memory rate limiter between every test., Set required env vars before test collection. config.py eagerly instantia, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O (+9 more) ### Community 563 - "Community 563" -Cohesion: 0.33 -Nodes (5): Tests for optimized search filtering, Tests for optimized search filtering, Filter should use ticker index for O(1) lookup, Filter should use ticker index for O(1) lookup, TestFilterBySearchTerms +Cohesion: 0.2 +Nodes (9): Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval. (+1 more) ### Community 564 - "Community 564" -Cohesion: 0.22 -Nodes (6): Store a memory about the user's preferences, analysis results, or feedback., save_memory(), batchCosineSimilarity(), contentHash(), embed(), normalizeRows() +Cohesion: 0.25 +Nodes (30): Base, BaseModel, EarningsSync, WalletCreate, IntFlag, OrunmilaMemory, Earning, Holding (+22 more) ### Community 565 - "Community 565" Cohesion: 0.33 @@ -1968,40 +1994,44 @@ Cohesion: 0.14 Nodes (11): Integration tests for the verifyAPIKey function., Test successful API key verification., Integration tests for the verifyAPIKey function., Test API key verification when quota is exceeded., Test API key verification with invalid key., Test API key verification with missing key., Test API key verification with invalid key., Test that API key system can be disabled. (+3 more) ### Community 568 - "Community 568" -Cohesion: 0.11 -Nodes (16): Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 17, 22-27: user found, role not present, role added. (+8 more) +Cohesion: 0.33 +Nodes (5): Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails. ### Community 569 - "Community 569" -Cohesion: 0.14 -Nodes (8): initialize(), initialize(), OrunmilaService, initialize(), MCPDetectMiddleware, StocksAPIService, getApp(), runAll() +Cohesion: 0.39 +Nodes (8): _build_error_response(), buildErrorResponse(), generic_exception_handler(), genericExceptionHandler(), http_exception_handler(), httpExceptionHandler(), validation_exception_handler(), validationExceptionHandler() ### Community 570 - "Community 570" Cohesion: 0.33 Nodes (6): 2.2 Tooling, code:bash (# Windows/Docker Desktop: do NOT use --network host (the Lin), code:bash (curl -s -o /dev/null -w '%header{x-cache-status}\n' -H "X-AP), code:bash (docker stats --no-stream --format "{{.Name}},{{.CPUPerc}},{{), code:bash (docker exec api sh -c "pidstat -w -p 1 1 30" # if sysst), code:block15 (tests/perf/nginx/) ### Community 571 - "Community 571" -Cohesion: 0.29 -Nodes (7): check_cache(), Read a file from the sandbox filesystem. Args: path: Absolute pa, List files in the workspace directory. Args: path: Directory pat, Upload a file to the sandbox filesystem. Use this to push data files (CSV,, Check if a computed result exists in the cache. Use before executing expens, read_sandbox_file(), upload_to_sandbox() +Cohesion: 0.25 +Nodes (8): code:python (TIPO_MAP = {"Dividendo": "Div", "JCP": "JSCP", "Juros Sobre ), code:python (from freezegun import freeze_time), code:bash (git add main/service/wallet_service.py main/controller/walle), code:python (def _flat_series_with_one_div(url, params=None, headers=None), code:bash (git add main/service/wallet_service.py main/controller/walle), Goal 2 — P2 earnings + performance (starts only after Goal 1 complete), Task P2-2: Earnings sync (accrue + transition, pull-based), Task P2-3: Performance windows (on-demand reconstruction, no new table) ### Community 572 - "Community 572" -Cohesion: 0.39 -Nodes (8): _build_error_response(), buildErrorResponse(), generic_exception_handler(), genericExceptionHandler(), http_exception_handler(), httpExceptionHandler(), validation_exception_handler(), validationExceptionHandler() +Cohesion: 0.22 +Nodes (7): Integration tests for all query optimizations, Integration tests for all query optimizations, All optimizations should be implemented, All optimizations should be implemented, Query filter should use ticker index, Query filter should use ticker index, TestQueryOptimization ### Community 573 - "Community 573" -Cohesion: 0.25 -Nodes (8): Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the sandbox filesystem. Args: path: Absolute pa, Read a file from the sandbox filesystem. Args: path: Absolute pa, Read a file from the workspace. Args: path: Path to the file (e., read_file() +Cohesion: 0.29 +Nodes (6): Global Constraints, Goal 3 — P3+ assist + narration (starts only after Goal 2 complete), Mansa Wallet Implementation Plan (P1 + P2 + P3+), Task P3-0: Write the P3+ detailed plan (required before P3-1/P3-2), Task P3-1: Ratings-assist tuning (gated on the P3+ plan), Task P3-2: Orunmila narration tools (gated on the P3+ plan) -### Community 574 - "Community 574" -Cohesion: 0.14 -Nodes (9): Verify that getSession() returns per-thread Session instances., Calling getSession() twice in the same thread returns the same object., Two threads must NOT share a Session object., With 20 concurrent threads, every thread must get its own Session., The returned object must be a real requests.Session., TestGetSession, get_session(), Return a requests.Session for the current thread. Sessions are created la (+1 more) +### Community 575 - "Community 575" +Cohesion: 0.13 +Nodes (8): create_entry_route(), delete_entry_route(), list_earnings_route(), list_entries_route(), serialize_earning(), serialize_entry(), serialize_holding(), update_entry_route() + +### Community 576 - "Community 576" +Cohesion: 0.29 +Nodes (7): check_cache(), Read a file from the sandbox filesystem. Args: path: Absolute pa, List files in the workspace directory. Args: path: Directory pat, Upload a file to the sandbox filesystem. Use this to push data files (CSV,, Check if a computed result exists in the cache. Use before executing expens, read_sandbox_file(), upload_to_sandbox() ### Community 577 - "Community 577" Cohesion: 0.33 Nodes (5): replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34). ### Community 578 - "Community 578" -Cohesion: 0.47 -Nodes (3): TestCleanup, cleanup(), Close the main thread's session at interpreter shutdown. +Cohesion: 0.29 +Nodes (7): code:python (def make_wallet_client(mock_identity=None, db=None):), code:python (import main.models.wallet # noqa: F401), code:python (def test_list_wallets_returns_only_mine(dbSession):), code:python (from sqlalchemy.orm import Session), code:python (from fastapi import APIRouter, Depends), code:bash (git add main/controller/wallet_controller.py main/service/wa), Task 5: Wallets CRUD + mount + `make_wallet_client` ### Community 579 - "Community 579" Cohesion: 0.33 @@ -2020,40 +2050,28 @@ Cohesion: 0.13 Nodes (14): 1.1 Functional (per surface; tags: EXISTS = build on it, PARTIAL = half reusable, MISSING = greenfield), 1.2 Non-functional, 1. Requirements, 2. Domain model, 3. API contracts (all under `/api/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout), 4. Phased build plan (writing-plans: each phase independently reviewable; reviewer PASS per phase), 5. Risks / assumptions (honest flags carried over — do not treat as fact), 6.1 DB & migrations (`user_db`) — READY, 2 actions (+6 more) ### Community 584 - "Community 584" -Cohesion: 0.32 -Nodes (4): memoryMaintenance(), _create(), After 10 cycles, preference (0.99^10) > context (0.90^10)., TestTypeAwareDecay +Cohesion: 0.43 +Nodes (4): _extractCredential(), _introspectUrl(), introspectUser(), _serviceToken() ### Community 585 - "Community 585" Cohesion: 0.33 -Nodes (5): Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Regression: HarnessState must never leak into tool signatures., Regression: HarnessState must never leak into tool signatures., TestGeminiCompatibility +Nodes (5): Environment, Standing rules (do not re-derive), Swarm protocol (all three goals), The three goals (sequential — one at a time, never parallel), Wallet Orchestrator Prompt (P1 + P2 + P3+ — one goal per scope) ### Community 586 - "Community 586" -Cohesion: 0.24 -Nodes (4): Pytest Testing, PrometheusSettings, TestSandboxConfig, TestConfig - -### Community 587 - "Community 587" -Cohesion: 0.4 -Nodes (5): Category 8: Testing Gaps (MEDIUM), Issue 8.1 — No integration tests for full request lifecycle, Issue 8.2 — No tests for scraper, stocks query, or cache, Issue 8.3 — No tests for Google OAuth callback, Issue 8.4 — No tests for session cleanup +Cohesion: 0.09 +Nodes (17): Tests for connection pool configuration, Stocks engine should have optimized pool settings, Integration tests for all query optimizations, All optimizations should be implemented, Query filter should use ticker index, Tests for optimized search filtering, Filter should use ticker index for O(1) lookup, Performance tests for query operations (+9 more) ### Community 588 - "Community 588" -Cohesion: 0.29 -Nodes (6): GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422. - -### Community 589 - "Community 589" -Cohesion: 0.33 -Nodes (6): makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., TestMakeChatIncludesMemoryTools - -### Community 590 - "Community 590" -Cohesion: 0.29 -Nodes (5): buildClient(), connect(), ensureFastmcp(), MCPClientPool, _parseServers() +Cohesion: 0.25 +Nodes (8): Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the sandbox filesystem. Args: path: Absolute pa, Read a file from the sandbox filesystem. Args: path: Absolute pa, Read a file from the workspace. Args: path: Path to the file (e., read_file() ### Community 591 - "Community 591" Cohesion: 0.4 Nodes (4): 0. Purpose and constraints, Next actions (not in scope here), nginx Scaling Plan — reverse proxy + response cache for `/stocks`, and the multi-server evolution, Open decisions (blocking or product-owned) ### Community 592 - "Community 592" -Cohesion: 0.17 -Nodes (7): Decay happens first, then archive check with new scores., Decay happens first, then archive check with new scores., Score that decays to >= threshold stays alive. 0.11 * 0.95 = 0.1045 >= 0.1., Score that decays to >= threshold stays alive. 0.12 * 0.90 = 0.108 >= 0.1., 89 days with low score → not archived (need > 90)., 89 days with low score → not archived (need > 90)., TestDecayAndArchiveTogether +Cohesion: 0.2 +Nodes (9): introspectToken(), verifyAccessToken(), introspect(), Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError. (+1 more) ### Community 593 - "Community 593" Cohesion: 0.5 @@ -2067,6 +2085,10 @@ Nodes (4): 1.4 Phase P1 — cache locations, TTL table, directives, code:nginx ( Cohesion: 0.19 Nodes (7): Tests for thread safety utilities (Issues 5 & 6). Issue 5: DiscordHandler use, Verify getSession returns thread-local sessions under concurrency., getSession() must give each thread its own Session., connectivity.checkServiceConnection must call getSession(), not use a global Ses, connectivity.checkServiceConnection must call getSession(), not use a global Ses, TestConcurrentGetSession, TestConcurrentHttpProxy +### Community 596 - "Community 596" +Cohesion: 0.4 +Nodes (5): Tests covering key.py lines 15-40. Uses asyncio.run() since pytest-asyncio, Tests covering key.py lines 15-40. Uses asyncio.run() since pytest-asyncio, Tests covering key.py lines 15-40. Uses asyncio.run() since pytest-asyncio, Tests covering key.py lines 15-40. Uses asyncio.run() since pytest-asyncio, TestVerifyAPIKey + ### Community 597 - "Community 597" Cohesion: 0.5 Nodes (4): 1.3 Phase P0 — nginx service + config skeleton, code:yaml (nginx:), code:nginx (proxy_cache_path /var/cache/nginx/stocks), code:nginx (upstream stocks_api {) @@ -2080,63 +2102,135 @@ Cohesion: 0.33 Nodes (10): Tests for main/utils/logging_config.py — covers DiscordHandler branches., test_discord_disabled(), test_discord_no_webhook(), test_exception_in_submit(), test_level_below_error(), test_message_truncation(), test_submit_called_on_error(), test_with_exception_info() (+2 more) ### Community 600 - "Community 600" -Cohesion: 0.22 -Nodes (7): Integration tests for all query optimizations, Integration tests for all query optimizations, All optimizations should be implemented, All optimizations should be implemented, Query filter should use ticker index, Query filter should use ticker index, TestQueryOptimization - -### Community 602 - "Community 602" -Cohesion: 0.32 -Nodes (7): create_memory(), createMemory(), _downloadModel(), embed(), getEmbeddingModel(), executeMemoryTool(), executeMemoryTool() +Cohesion: 0.4 +Nodes (5): code:python (def test_permission_enum_values():), code:python (class Permission(IntFlag):), code:markdown (| `USER` | `WALLET` — default on registration |), code:bash (git add main/utils/roles.py tests/test_roles.py docs/authent), Task 1: `Permission.WALLET` on the base role + ripple fixes -### Community 603 - "Community 603" +### Community 601 - "Community 601" Cohesion: 0.4 -Nodes (5): Tests covering key.py lines 15-40. Uses asyncio.run() since pytest-asyncio, Tests covering key.py lines 15-40. Uses asyncio.run() since pytest-asyncio, Tests covering key.py lines 15-40. Uses asyncio.run() since pytest-asyncio, Tests covering key.py lines 15-40. Uses asyncio.run() since pytest-asyncio, TestVerifyAPIKey +Nodes (5): code:python (import requests), code:python (import os), code:python (def fetchCachedClose(ticker: str) -> float | None:), code:bash (git add main/service/wallet_service.py main/controller/walle), Task 7: Positions — live-price join over HTTP -### Community 604 - "Community 604" +### Community 602 - "Community 602" Cohesion: 0.29 Nodes (6): dbSession(), Tests for atomic API key quota enforcement (race condition fix). Verifies tha, Sample API key data for tests., Create an in-memory SQLite database for testing., Sample API key data for tests., sampleKeyData() -### Community 605 - "Community 605" +### Community 604 - "Community 604" Cohesion: 0.29 Nodes (6): Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., TestStocksApiHealth -### Community 606 - "Community 606" +### Community 605 - "Community 605" Cohesion: 0.29 -Nodes (6): GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422. +Nodes (6): Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., TestStocksApiFundamental + +### Community 606 - "Community 606" +Cohesion: 0.2 +Nodes (9): 1. Orunmila's loop today, 2. Where Orunmila is already ahead — do not rebuild, 3. The 12 modern patterns vs Orunmila, 4. P0 — reliability (do first, each one PR), 5. P1 — context quality (biggest behavior delta per line), 6. P2 — structural (larger, sequenced after P0/P1), 7. P3 / later — deliberate scope, not accidents, 8. Sources (+1 more) + +### Community 607 - "Community 607" +Cohesion: 0.5 +Nodes (4): code:python (from fastapi import Depends, FastAPI), code:python (import logging), code:bash (git add main/app/wallet/auth.py tests/test_wallet_auth.py), Task 4: Wallet auth dependency (introspect contract + raw-token resolver) ### Community 608 - "Community 608" -Cohesion: 0.27 -Nodes (4): Test that invalid API key returns zero rows affected., Test that multiple API keys have independent quotas., Test that invalid API key returns zero rows affected., Test that multiple API keys have independent quotas. +Cohesion: 0.5 +Nodes (4): code:python (from main.models.wallet import Earning), code:python (class Earning(Base):), code:bash (git add main/models/wallet.py migrations/versions/_wall), Task P2-1: `Earning` model + second migration revision -### Community 618 - "Community 618" +### Community 609 - "Community 609" +Cohesion: 0.29 +Nodes (6): Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers line 16: empty password raises ValueError. + +### Community 611 - "Community 611" Cohesion: 0.5 -Nodes (4): code:python (from dataclasses import dataclass), code:bash (git add main/app/wallet/__init__.py main/app/wallet/math.py ), code:python (from datetime import date), Task 3: Pure derivation math +Nodes (4): code:python (from main.models.base import Base), code:python (from sqlalchemy import Column, Date, Enum, ForeignKey, Integ), code:bash (git add main/models/wallet.py tests/test_wallet_models.py), Task 2: Wallet ORM models (5 tables, `user_db`) -### Community 621 - "Community 621" -Cohesion: 0.83 -Nodes (4): getMatrix(), getMatrixAsync(), matrixKey(), matrixUserTag() +### Community 612 - "Community 612" +Cohesion: 0.67 +Nodes (3): code:python (def test_summary_math_and_snapshot_upsert(dbSession, monkeyp), code:bash (git add main/service/wallet_service.py main/controller/walle), Task 8: Summary + snapshots + allocation + targets + ratings -### Community 623 - "Community 623" +### Community 613 - "Community 613" +Cohesion: 0.08 +Nodes (20): Tests for connection pool configuration, Tests for connection pool configuration, Stocks engine should have optimized pool settings, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Tests for lazy JSON deserialization, Query manager should have deserialize method, Query manager should have deserialize method (+12 more) + +### Community 614 - "Community 614" +Cohesion: 0.29 +Nodes (6): Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 48-49: jwt.ExpiredSignatureError. + +### Community 615 - "Community 615" +Cohesion: 0.33 +Nodes (6): dispatchToolCall must route memory tool names via TOOL_REGISTRY., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., TestDispatchRoutesMemoryTools + +### Community 616 - "Community 616" +Cohesion: 0.2 +Nodes (9): Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148. (+1 more) + +### Community 617 - "Community 617" +Cohesion: 0.29 +Nodes (6): Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation. + +### Community 618 - "Community 618" Cohesion: 0.67 Nodes (3): checkServiceConnection — success, not found, errors., checkServiceConnection — success, not found, errors., TestCheckServiceConnection -### Community 624 - "Community 624" +### Community 620 - "Community 620" +Cohesion: 0.33 +Nodes (6): Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., TestAddRoleToUser + +### Community 621 - "Community 621" Cohesion: 0.67 Nodes (3): checkMySqlConnection — success, errors, engine=None paths., checkMySqlConnection — success, errors, engine=None paths., TestCheckMySqlConnection +### Community 623 - "Community 623" +Cohesion: 0.33 +Nodes (5): Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added. + +### Community 625 - "Community 625" +Cohesion: 0.33 +Nodes (5): Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers lines 42-44: session validation fails. + +### Community 626 - "Community 626" +Cohesion: 0.33 +Nodes (5): Covers line 24: GET /prometheus/health., Covers line 24: GET /prometheus/health., Covers line 24: GET /prometheus/health., Covers line 24: GET /prometheus/health., TestPrometheusHealth + +### Community 627 - "Community 627" +Cohesion: 0.47 +Nodes (3): TestCleanup, cleanup(), Close the main thread's session at interpreter shutdown. + +### Community 628 - "Community 628" +Cohesion: 0.33 +Nodes (6): makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., TestMakeChatIncludesMemoryTools + +### Community 629 - "Community 629" +Cohesion: 0.5 +Nodes (3): getWalletIdentity(), requireWalletOwnership(), resolveRawToken() + +### Community 630 - "Community 630" +Cohesion: 0.33 +Nodes (5): Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Regression: HarnessState must never leak into tool signatures., Regression: HarnessState must never leak into tool signatures., TestGeminiCompatibility + +### Community 631 - "Community 631" +Cohesion: 0.4 +Nodes (4): getGoogleSSO(), googleLogin(), test_get_google_sso_default_redirect(), test_get_google_sso_with_redirect() + +### Community 632 - "Community 632" +Cohesion: 0.5 +Nodes (4): code:python (from dataclasses import dataclass), code:bash (git add main/app/wallet/__init__.py main/app/wallet/math.py ), code:python (from datetime import date), Task 3: Pure derivation math + +### Community 634 - "Community 634" +Cohesion: 0.4 +Nodes (5): Category 8: Testing Gaps (MEDIUM), Issue 8.1 — No integration tests for full request lifecycle, Issue 8.2 — No tests for scraper, stocks query, or cache, Issue 8.3 — No tests for Google OAuth callback, Issue 8.4 — No tests for session cleanup + ## Knowledge Gaps -- **3360 isolated node(s):** `$schema`, `style`, `rsc`, `tsx`, `config` (+3355 more) +- **3443 isolated node(s):** `$schema`, `style`, `rsc`, `tsx`, `config` (+3438 more) These have ≤1 connection - possible missing edges or undocumented components. -- **243 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. +- **237 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. ## Suggested Questions _Questions this graph is uniquely positioned to answer:_ -- **Why does `Pytest Testing` connect `Community 586` to `Authentication Core`, `Frontend Components`, `Community 129`, `Data Models & Types`, `Community 131`, `Community 518`, `Community 519`, `Community 135`, `Community 138`, `Community 140`, `Community 527`, `Community 16`, `Community 18`, `Community 147`, `Community 24`, `Community 25`, `Community 27`, `Community 29`, `Community 32`, `Community 33`, `Community 40`, `Community 44`, `Community 560`, `Community 49`, `Community 51`, `Community 186`, `Community 59`, `Community 188`, `Community 61`, `Community 584`, `Community 595`, `Community 599`, `Community 474`, `Community 604`, `Community 93`, `Community 477`, `Community 611`, `Community 100`, `Community 101`, `Community 491`, `Community 500`, `Community 502`, `Community 120`, `Community 251`, `Community 511`?** +- **Why does `Pytest Testing` connect `Community 491` to `Authentication Core`, `Frontend Components`, `Community 129`, `Data Models & Types`, `Community 131`, `Community 518`, `Community 135`, `Device Detection`, `Community 521`, `Community 138`, `Community 140`, `Community 527`, `Community 18`, `Community 147`, `Community 24`, `Community 25`, `Community 538`, `Community 27`, `Community 29`, `Community 32`, `Community 33`, `Community 40`, `Community 44`, `Community 561`, `Community 49`, `Community 51`, `Community 186`, `Community 59`, `Community 188`, `Community 586`, `Community 595`, `Community 599`, `Community 602`, `Community 93`, `Community 477`, `Community 95`, `Community 610`, `Community 98`, `Community 100`, `Community 613`, `Community 102`, `Community 504`, `Community 493`, `Community 500`, `Community 120`, `Community 125`?** _High betweenness centrality (0.078) - this node is a cross-community bridge._ -- **Why does `FastAPI` connect `Community 519` to `Community 129`, `Community 131`, `Community 517`, `Community 523`, `Community 18`, `Community 147`, `Community 33`, `Community 34`, `Community 40`, `Community 560`, `Community 569`, `Community 186`, `Community 58`, `Community 572`, `Community 68`, `Community 71`, `Community 73`, `Community 81`, `Community 84`, `Community 604`, `Community 477`, `Community 482`, `Community 612`, `Community 491`, `Community 500`, `Community 501`, `Community 120`, `Community 511`?** - _High betweenness centrality (0.050) - this node is a cross-community bridge._ -- **Why does `UserManager` connect `Community 45` to `Community 256`, `Prometheus Agent`, `Community 519`, `Community 136`, `Prometheus Memory`, `Community 524`, `Community 141`, `User Roles & Permissions`, `Community 148`, `Community 22`, `Community 28`, `Community 541`, `Community 37`, `Community 172`, `Community 47`, `Community 565`, `Community 568`, `Community 58`, `Community 61`, `Community 67`, `Community 474`, `Community 603`, `Community 605`, `Community 221`, `Community 99`, `Community 107`, `Community 493`, `Community 112`, `Community 114`, `Community 120`?** - _High betweenness centrality (0.027) - this node is a cross-community bridge._ +- **Why does `FastAPI` connect `Community 152` to `Community 129`, `Community 517`, `Community 519`, `Community 18`, `Community 147`, `Community 536`, `Community 538`, `Community 33`, `Community 34`, `Community 40`, `Community 172`, `Community 560`, `Community 54`, `Community 569`, `Community 58`, `Community 186`, `Community 575`, `Community 67`, `Community 68`, `Community 71`, `Community 72`, `Community 73`, `Community 584`, `Community 592`, `Community 84`, `Community 602`, `Community 477`, `Community 98`, `Community 504`, `Community 234`, `Community 491`, `Community 500`, `Community 501`, `Community 629`, `Community 120`?** + _High betweenness centrality (0.068) - this node is a cross-community bridge._ +- **Why does `UserManager` connect `Community 45` to `Community 256`, `Prometheus Agent`, `Community 519`, `Prometheus Memory`, `Community 140`, `Community 141`, `User Roles & Permissions`, `Community 148`, `Community 22`, `Community 535`, `Community 28`, `Community 541`, `Community 546`, `Community 162`, `Community 37`, `Community 172`, `Community 47`, `Community 563`, `Community 564`, `Community 565`, `Community 58`, `Community 61`, `Community 596`, `Community 604`, `Community 605`, `Community 99`, `Community 616`, `Community 107`, `Community 620`, `Community 493`, `Community 112`, `Community 498`, `Community 626`, `Community 114`, `Community 120`, `Community 125`?** + _High betweenness centrality (0.031) - this node is a cross-community bridge._ - **Are the 72 inferred relationships involving `StocksCacheManager` (e.g. with `TestStocksCacheManager` and `TestVerifyAPIKey`) actually correct?** _`StocksCacheManager` has 72 INFERRED edges - model-reasoned connections that need verification._ - **Are the 52 inferred relationships involving `HarnessState` (e.g. with `Prometheus` and `.streamMessage()`) actually correct?** diff --git a/graphify-out/graph.json b/graphify-out/graph.json index 7eda6a52..c6cfbe1e 100644 --- a/graphify-out/graph.json +++ b/graphify-out/graph.json @@ -237,7 +237,7 @@ "source_file": "config.py", "source_location": "L90", "id": "server_config_config", - "community": 45, + "community": 564, "norm_label": "config" }, { @@ -264,43 +264,43 @@ "source_file": "run.py", "source_location": "L1", "id": "run_py", - "community": 523, + "community": 72, "norm_label": "run.py" }, { "label": "lifespan()", "file_type": "code", "source_file": "run.py", - "source_location": "L28", + "source_location": "L29", "id": "server_run_lifespan", - "community": 523, + "community": 72, "norm_label": "lifespan()" }, { "label": "health()", "file_type": "code", "source_file": "run.py", - "source_location": "L73", + "source_location": "L82", "id": "server_run_health", - "community": 523, + "community": 72, "norm_label": "health()" }, { "label": "status()", "file_type": "code", "source_file": "run.py", - "source_location": "L78", + "source_location": "L87", "id": "server_run_status", - "community": 523, + "community": 72, "norm_label": "status()" }, { "label": "triggerScraper()", "file_type": "code", "source_file": "run.py", - "source_location": "L112", + "source_location": "L121", "id": "server_run_triggerscraper", - "community": 523, + "community": 72, "norm_label": "triggerscraper()" }, { @@ -2190,7 +2190,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L1", "id": "main_app_authentication_authentication_py", - "community": 612, + "community": 172, "norm_label": "authentication.py" }, { @@ -2208,7 +2208,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L16", "id": "authentication_authentication_createuseraccount", - "community": 612, + "community": 43, "norm_label": "createuseraccount()" }, { @@ -2217,7 +2217,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L51", "id": "authentication_authentication_authenticategoogleuser", - "community": 612, + "community": 172, "norm_label": "authenticategoogleuser()" }, { @@ -2235,7 +2235,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L79", "id": "authentication_authentication_resolveuniqueusername", - "community": 612, + "community": 172, "norm_label": "resolveuniqueusername()" }, { @@ -2253,7 +2253,7 @@ "source_file": "main/app/authentication/introspect.py", "source_location": "L1", "id": "main_app_authentication_introspect_py", - "community": 519, + "community": 592, "norm_label": "introspect.py" }, { @@ -2262,7 +2262,7 @@ "source_file": "main/app/authentication/introspect.py", "source_location": "L14", "id": "authentication_introspect_introspecttoken", - "community": 519, + "community": 592, "norm_label": "introspecttoken()" }, { @@ -2379,7 +2379,7 @@ "source_file": "main/app/authentication/sso.py", "source_location": "L1", "id": "main_app_authentication_sso_py", - "community": 58, + "community": 631, "norm_label": "sso.py" }, { @@ -2388,7 +2388,7 @@ "source_file": "main/app/authentication/sso.py", "source_location": "L6", "id": "authentication_sso_getgooglesso", - "community": 58, + "community": 631, "norm_label": "getgooglesso()" }, { @@ -2397,7 +2397,7 @@ "source_file": "main/app/authentication/util.py", "source_location": "L1", "id": "main_app_authentication_util_py", - "community": 560, + "community": 538, "norm_label": "util.py" }, { @@ -2433,7 +2433,7 @@ "source_file": "main/app/authentication/util.py", "source_location": "L44", "id": "authentication_util_verifyaccesstoken", - "community": 519, + "community": 592, "norm_label": "verifyaccesstoken()" }, { @@ -2451,7 +2451,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L1", "id": "main_app_orunmila_agent_py", - "community": 497, + "community": 137, "norm_label": "agent.py" }, { @@ -2460,7 +2460,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L25", "id": "orunmila_agent_safefilter", - "community": 497, + "community": 137, "norm_label": "safefilter()" }, { @@ -2469,7 +2469,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L31", "id": "orunmila_agent_persistevent", - "community": 497, + "community": 137, "norm_label": "persistevent()" }, { @@ -2478,7 +2478,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L45", "id": "orunmila_agent_getclient", - "community": 497, + "community": 137, "norm_label": "getclient()" }, { @@ -2487,7 +2487,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L208", "id": "orunmila_agent_orunmila", - "community": 45, + "community": 137, "norm_label": "orunmila" }, { @@ -2496,7 +2496,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L209", "id": "orunmila_agent_orunmila_init", - "community": 497, + "community": 137, "norm_label": ".__init__()" }, { @@ -2505,7 +2505,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L213", "id": "orunmila_agent_buildsystemprompt", - "community": 497, + "community": 137, "norm_label": "buildsystemprompt()" }, { @@ -2514,7 +2514,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L242", "id": "orunmila_agent_orunmila_makechat", - "community": 497, + "community": 137, "norm_label": ".makechat()" }, { @@ -2523,7 +2523,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L253", "id": "orunmila_agent_orunmila_streammessage", - "community": 497, + "community": 137, "norm_label": ".streammessage()" }, { @@ -2532,7 +2532,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L1", "id": "main_app_orunmila_chat_py", - "community": 231, + "community": 137, "norm_label": "chat.py" }, { @@ -2541,7 +2541,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L13", "id": "orunmila_chat_orunmilachatmanager", - "community": 45, + "community": 564, "norm_label": "orunmilachatmanager" }, { @@ -2550,7 +2550,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L15", "id": "orunmila_chat_getusersessions", - "community": 231, + "community": 137, "norm_label": "getusersessions()" }, { @@ -2559,7 +2559,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L34", "id": "orunmila_chat_createsession", - "community": 231, + "community": 137, "norm_label": "createsession()" }, { @@ -2568,7 +2568,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L42", "id": "orunmila_chat_updatesessiontitle", - "community": 231, + "community": 137, "norm_label": "updatesessiontitle()" }, { @@ -2577,7 +2577,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L53", "id": "orunmila_chat_appendhistory", - "community": 231, + "community": 137, "norm_label": "appendhistory()" }, { @@ -2586,7 +2586,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L72", "id": "orunmila_chat_gethistory", - "community": 231, + "community": 137, "norm_label": "gethistory()" }, { @@ -2595,7 +2595,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L93", "id": "orunmila_chat_deletesession", - "community": 231, + "community": 137, "norm_label": "deletesession()" }, { @@ -2604,7 +2604,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L107", "id": "orunmila_chat_verifysessionownership", - "community": 231, + "community": 137, "norm_label": "verifysessionownership()" }, { @@ -2613,7 +2613,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L1", "id": "main_app_orunmila_compact_py", - "community": 162, + "community": 137, "norm_label": "compact.py" }, { @@ -2622,7 +2622,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L35", "id": "orunmila_compact_gettokenizer", - "community": 162, + "community": 137, "norm_label": "gettokenizer()" }, { @@ -2631,7 +2631,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L47", "id": "orunmila_compact_counttokens", - "community": 162, + "community": 137, "norm_label": "counttokens()" }, { @@ -2640,7 +2640,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L64", "id": "orunmila_compact_getstocksfieldsurl", - "community": 162, + "community": 137, "norm_label": "getstocksfieldsurl()" }, { @@ -2649,7 +2649,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L68", "id": "orunmila_compact_istransientfieldserror", - "community": 162, + "community": 137, "norm_label": "istransientfieldserror()" }, { @@ -2658,7 +2658,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L83", "id": "orunmila_compact_fetchfieldspayload", - "community": 162, + "community": 137, "norm_label": "fetchfieldspayload()" }, { @@ -2667,7 +2667,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L89", "id": "orunmila_compact_loadfielddata", - "community": 162, + "community": 137, "norm_label": "loadfielddata()" }, { @@ -2676,7 +2676,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L105", "id": "orunmila_compact_getmetricregex", - "community": 162, + "community": 137, "norm_label": "getmetricregex()" }, { @@ -2685,7 +2685,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L119", "id": "orunmila_compact_dedup", - "community": 162, + "community": 137, "norm_label": "dedup()" }, { @@ -2694,7 +2694,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L123", "id": "orunmila_compact_extracttickers", - "community": 162, + "community": 137, "norm_label": "extracttickers()" }, { @@ -2703,7 +2703,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L127", "id": "orunmila_compact_extractmetrics", - "community": 162, + "community": 137, "norm_label": "extractmetrics()" }, { @@ -2712,7 +2712,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L131", "id": "orunmila_compact_extractdecisions", - "community": 162, + "community": 137, "norm_label": "extractdecisions()" }, { @@ -2721,7 +2721,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L145", "id": "orunmila_compact_extractsnapshots", - "community": 162, + "community": 137, "norm_label": "extractsnapshots()" }, { @@ -2730,7 +2730,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L158", "id": "orunmila_compact_extracttoolcalls", - "community": 162, + "community": 137, "norm_label": "extracttoolcalls()" }, { @@ -2739,7 +2739,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L174", "id": "orunmila_compact_buildsummary", - "community": 162, + "community": 137, "norm_label": "buildsummary()" }, { @@ -2748,7 +2748,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L195", "id": "orunmila_compact_orunmilacompactor", - "community": 497, + "community": 137, "norm_label": "orunmilacompactor" }, { @@ -2757,7 +2757,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L196", "id": "orunmila_compact_orunmilacompactor_shouldcompact", - "community": 497, + "community": 137, "norm_label": ".shouldcompact()" }, { @@ -2766,7 +2766,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L213", "id": "orunmila_compact_orunmilacompactor_getcompactablechunk", - "community": 497, + "community": 137, "norm_label": ".getcompactablechunk()" }, { @@ -2775,7 +2775,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L222", "id": "orunmila_compact_orunmilacompactor_extractepisode", - "community": 162, + "community": 137, "norm_label": ".extractepisode()" }, { @@ -2784,7 +2784,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L244", "id": "orunmila_compact_orunmilacompactor_consolidate", - "community": 497, + "community": 137, "norm_label": ".consolidate()" }, { @@ -2793,7 +2793,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L271", "id": "orunmila_compact_orunmilacompactor_compact", - "community": 497, + "community": 137, "norm_label": ".compact()" }, { @@ -2802,7 +2802,7 @@ "source_file": "main/app/orunmila/compact.py", "source_location": "L310", "id": "orunmila_compact_orunmilacompactor_getepisodes", - "community": 497, + "community": 137, "norm_label": ".getepisodes()" }, { @@ -2811,7 +2811,7 @@ "source_file": "main/app/orunmila/mcp.py", "source_location": "L1", "id": "main_app_orunmila_mcp_py", - "community": 521, + "community": 189, "norm_label": "mcp.py" }, { @@ -2820,7 +2820,7 @@ "source_file": "main/app/orunmila/mcp.py", "source_location": "L21", "id": "orunmila_mcp_buildclient", - "community": 521, + "community": 189, "norm_label": "buildclient()" }, { @@ -2829,7 +2829,7 @@ "source_file": "main/app/orunmila/mcp.py", "source_location": "L29", "id": "orunmila_mcp_connect", - "community": 521, + "community": 189, "norm_label": "connect()" }, { @@ -2838,7 +2838,7 @@ "source_file": "main/app/orunmila/mcp.py", "source_location": "L36", "id": "orunmila_mcp_mcpclientpool", - "community": 521, + "community": 189, "norm_label": "mcpclientpool" }, { @@ -2847,7 +2847,7 @@ "source_file": "main/app/orunmila/mcp.py", "source_location": "L37", "id": "orunmila_mcp_mcpclientpool_init", - "community": 521, + "community": 189, "norm_label": ".__init__()" }, { @@ -2856,7 +2856,7 @@ "source_file": "main/app/orunmila/mcp.py", "source_location": "L42", "id": "orunmila_mcp_mcpclientpool_initialize", - "community": 521, + "community": 189, "norm_label": ".initialize()" }, { @@ -2865,7 +2865,7 @@ "source_file": "main/app/orunmila/mcp.py", "source_location": "L56", "id": "orunmila_mcp_mcpclientpool_getclients", - "community": 521, + "community": 189, "norm_label": ".getclients()" }, { @@ -2874,7 +2874,7 @@ "source_file": "main/app/orunmila/mcp.py", "source_location": "L63", "id": "orunmila_mcp_mcpclientpool_healthcheck", - "community": 521, + "community": 189, "norm_label": ".healthcheck()" }, { @@ -2883,7 +2883,7 @@ "source_file": "main/app/orunmila/mcp.py", "source_location": "L75", "id": "orunmila_mcp_mcpclientpool_reconnect", - "community": 521, + "community": 189, "norm_label": ".reconnect()" }, { @@ -2892,7 +2892,7 @@ "source_file": "main/app/orunmila/mcp.py", "source_location": "L90", "id": "orunmila_mcp_mcpclientpool_close", - "community": 521, + "community": 189, "norm_label": ".close()" }, { @@ -2937,7 +2937,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L64", "id": "orunmila_memory_memorycandidate", - "community": 45, + "community": 564, "norm_label": "memorycandidate" }, { @@ -2946,7 +2946,7 @@ "source_file": "", "source_location": "", "id": "basemodel", - "community": 45, + "community": 564, "norm_label": "basemodel" }, { @@ -2955,7 +2955,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L90", "id": "orunmila_memory_newtokencache", - "community": 497, + "community": 137, "norm_label": "newtokencache()" }, { @@ -3027,7 +3027,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L179", "id": "orunmila_memory_sumtokens", - "community": 162, + "community": 137, "norm_label": "sumtokens()" }, { @@ -3036,7 +3036,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L194", "id": "orunmila_memory_orunmilamemory", - "community": 45, + "community": 564, "norm_label": "orunmilamemory" }, { @@ -3171,7 +3171,7 @@ "source_file": "main/app/orunmila/sandbox.py", "source_location": "L51", "id": "orunmila_sandbox_sandboxmanager", - "community": 45, + "community": 234, "norm_label": "sandboxmanager" }, { @@ -3396,151 +3396,169 @@ "source_file": "main/app/orunmila/tools.py", "source_location": "L1", "id": "main_app_orunmila_tools_py", - "community": 538, + "community": 67, "norm_label": "tools.py" }, { "label": "search_memory()", "file_type": "code", "source_file": "main/app/orunmila/tools.py", - "source_location": "L20", + "source_location": "L21", "id": "orunmila_tools_search_memory", - "community": 538, + "community": 67, "norm_label": "search_memory()" }, { "label": "save_memory()", "file_type": "code", "source_file": "main/app/orunmila/tools.py", - "source_location": "L51", + "source_location": "L52", "id": "orunmila_tools_save_memory", - "community": 564, + "community": 137, "norm_label": "save_memory()" }, { "label": "execute_code()", "file_type": "code", "source_file": "main/app/orunmila/tools.py", - "source_location": "L93", + "source_location": "L94", "id": "orunmila_tools_execute_code", - "community": 538, + "community": 67, "norm_label": "execute_code()" }, { "label": "read_file()", "file_type": "code", "source_file": "main/app/orunmila/tools.py", - "source_location": "L114", + "source_location": "L115", "id": "orunmila_tools_read_file", - "community": 538, + "community": 67, "norm_label": "read_file()" }, { "label": "write_file()", "file_type": "code", "source_file": "main/app/orunmila/tools.py", - "source_location": "L128", + "source_location": "L129", "id": "orunmila_tools_write_file", - "community": 538, + "community": 67, "norm_label": "write_file()" }, { "label": "list_files()", "file_type": "code", "source_file": "main/app/orunmila/tools.py", - "source_location": "L144", + "source_location": "L145", "id": "orunmila_tools_list_files", - "community": 538, + "community": 67, "norm_label": "list_files()" }, { "label": "serve_file()", "file_type": "code", "source_file": "main/app/orunmila/tools.py", - "source_location": "L157", + "source_location": "L158", "id": "orunmila_tools_serve_file", - "community": 538, + "community": 234, "norm_label": "serve_file()" }, + { + "label": "narrate_positions()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L183", + "id": "orunmila_tools_narrate_positions", + "community": 68, + "norm_label": "narrate_positions()" + }, { "label": "dispatchToolCall()", "file_type": "code", "source_file": "main/app/orunmila/tools.py", - "source_location": "L190", + "source_location": "L260", "id": "orunmila_tools_dispatchtoolcall", - "community": 538, + "community": 137, "norm_label": "dispatchtoolcall()" }, { "label": "Search user's saved memories, preferences, and past analysis context. Use", "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", - "source_location": "L21", - "id": "orunmila_tools_rationale_21", - "community": 538, + "source_location": "L22", + "id": "orunmila_tools_rationale_22", + "community": 67, "norm_label": "search user's saved memories, preferences, and past analysis context. use" }, { "label": "Store a memory about the user's preferences, analysis results, or feedback.", "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", - "source_location": "L52", - "id": "orunmila_tools_rationale_52", - "community": 564, + "source_location": "L53", + "id": "orunmila_tools_rationale_53", + "community": 137, "norm_label": "store a memory about the user's preferences, analysis results, or feedback." }, { "label": "Execute Python code in an isolated sandbox. Use for quantitative analysis,", "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", - "source_location": "L94", - "id": "orunmila_tools_rationale_94", - "community": 538, + "source_location": "L95", + "id": "orunmila_tools_rationale_95", + "community": 67, "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis," }, { "label": "Read a file from the workspace. Args: path: Path to the file (e.", "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", - "source_location": "L115", - "id": "orunmila_tools_rationale_115", - "community": 538, + "source_location": "L116", + "id": "orunmila_tools_rationale_116", + "community": 67, "norm_label": "read a file from the workspace. args: path: path to the file (e." }, { "label": "Write a file to the workspace. Use this to save data files (CSV, JSON, scri", "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", - "source_location": "L129", - "id": "orunmila_tools_rationale_129", - "community": 538, + "source_location": "L130", + "id": "orunmila_tools_rationale_130", + "community": 67, "norm_label": "write a file to the workspace. use this to save data files (csv, json, scri" }, { "label": "List files in the workspace directory. Args: path: Directory pat", "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", - "source_location": "L145", - "id": "orunmila_tools_rationale_145", - "community": 538, + "source_location": "L146", + "id": "orunmila_tools_rationale_146", + "community": 67, "norm_label": "list files in the workspace directory. args: path: directory pat" }, { "label": "Get a download link for a workspace file to share with the user. Use this", "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", - "source_location": "L158", - "id": "orunmila_tools_rationale_158", - "community": 538, + "source_location": "L159", + "id": "orunmila_tools_rationale_159", + "community": 234, "norm_label": "get a download link for a workspace file to share with the user. use this" }, + { + "label": "Narrate the user's wallet positions in plain language. Read-only summary", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L184", + "id": "orunmila_tools_rationale_184", + "community": 68, + "norm_label": "narrate the user's wallet positions in plain language. read-only summary" + }, { "label": "vector.py", "file_type": "code", "source_file": "main/app/orunmila/vector.py", "source_location": "L1", "id": "main_app_orunmila_vector_py", - "community": 564, + "community": 137, "norm_label": "vector.py" }, { @@ -3549,7 +3567,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L10", "id": "orunmila_vector_normalizerows", - "community": 564, + "community": 137, "norm_label": "normalizerows()" }, { @@ -3558,7 +3576,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L15", "id": "orunmila_vector_embed", - "community": 564, + "community": 137, "norm_label": "embed()" }, { @@ -3567,7 +3585,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L19", "id": "orunmila_vector_decodeembeddings", - "community": 564, + "community": 137, "norm_label": "decodeembeddings()" }, { @@ -3576,7 +3594,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L41", "id": "orunmila_vector_batchcosinesimilarity", - "community": 564, + "community": 137, "norm_label": "batchcosinesimilarity()" }, { @@ -3585,7 +3603,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L51", "id": "orunmila_vector_contenthash", - "community": 564, + "community": 137, "norm_label": "contenthash()" }, { @@ -3594,7 +3612,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L55", "id": "orunmila_vector_tovectorstring", - "community": 564, + "community": 137, "norm_label": "tovectorstring()" }, { @@ -3603,7 +3621,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L59", "id": "orunmila_vector_fromvectorstring", - "community": 564, + "community": 137, "norm_label": "fromvectorstring()" }, { @@ -3621,187 +3639,187 @@ "source_file": "main/app/scraper_b3/scraper.py", "source_location": "L1", "id": "main_app_scraper_b3_scraper_py", - "community": 21, + "community": 474, "norm_label": "scraper.py" }, { "label": "getCurrentSelic()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L29", + "source_location": "L30", "id": "scraper_b3_scraper_getcurrentselic", - "community": 21, + "community": 474, "norm_label": "getcurrentselic()" }, { "label": "B3Scraper", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L38", + "source_location": "L41", "id": "scraper_b3_scraper_b3scraper", - "community": 21, + "community": 474, "norm_label": "b3scraper" }, { "label": ".__init__()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L39", + "source_location": "L42", "id": "scraper_b3_scraper_b3scraper_init", - "community": 21, + "community": 474, "norm_label": ".__init__()" }, { "label": "getInitialData()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L53", + "source_location": "L56", "id": "scraper_b3_scraper_getinitialdata", - "community": 21, + "community": 474, "norm_label": "getinitialdata()" }, { "label": "historicalRentability()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L108", + "source_location": "L111", "id": "scraper_b3_scraper_historicalrentability", - "community": 21, + "community": 474, "norm_label": "historicalrentability()" }, { "label": "historicalDividends()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L131", + "source_location": "L134", "id": "scraper_b3_scraper_historicaldividends", - "community": 21, + "community": 474, "norm_label": "historicaldividends()" }, { "label": "historicalDividendYields()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L164", + "source_location": "L167", "id": "scraper_b3_scraper_historicaldividendyields", - "community": 21, + "community": 474, "norm_label": "historicaldividendyields()" }, { "label": "historicalRevenue()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L192", + "source_location": "L195", "id": "scraper_b3_scraper_historicalrevenue", - "community": 21, + "community": 474, "norm_label": "historicalrevenue()" }, { "label": "historicalCotationProfits()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L213", + "source_location": "L216", "id": "scraper_b3_scraper_historicalcotationprofits", - "community": 21, + "community": 474, "norm_label": "historicalcotationprofits()" }, { "label": ".historicalCotationProfits_Oceans14()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L226", + "source_location": "L229", "id": "scraper_b3_scraper_b3scraper_historicalcotationprofits_oceans14", - "community": 21, + "community": 474, "norm_label": ".historicalcotationprofits_oceans14()" }, { "label": "historicalCotations()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L239", + "source_location": "L242", "id": "scraper_b3_scraper_historicalcotations", - "community": 21, + "community": 474, "norm_label": "historicalcotations()" }, { "label": "tagAlong()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L256", + "source_location": "L259", "id": "scraper_b3_scraper_tagalong", - "community": 21, + "community": 474, "norm_label": "tagalong()" }, { "label": "stockNews()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L277", + "source_location": "L280", "id": "scraper_b3_scraper_stocknews", - "community": 21, + "community": 474, "norm_label": "stocknews()" }, { "label": ".fundamentalIndicators()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L290", + "source_location": "L293", "id": "scraper_b3_scraper_b3scraper_fundamentalindicators", - "community": 21, + "community": 474, "norm_label": ".fundamentalindicators()" }, { "label": ".processTicker()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L413", + "source_location": "L416", "id": "scraper_b3_scraper_b3scraper_processticker", - "community": 21, + "community": 474, "norm_label": ".processticker()" }, { "label": ".scrapeStocks()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L444", + "source_location": "L447", "id": "scraper_b3_scraper_b3scraper_scrapestocks", - "community": 21, + "community": 474, "norm_label": ".scrapestocks()" }, { "label": ".reorderColumns()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L491", + "source_location": "L494", "id": "scraper_b3_scraper_b3scraper_reordercolumns", - "community": 21, + "community": 474, "norm_label": ".reordercolumns()" }, { "label": ".serializeComplexTypes()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L500", + "source_location": "L503", "id": "scraper_b3_scraper_b3scraper_serializecomplextypes", - "community": 21, + "community": 474, "norm_label": ".serializecomplextypes()" }, { "label": ".exportJson()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L519", + "source_location": "L522", "id": "scraper_b3_scraper_b3scraper_exportjson", - "community": 21, + "community": 474, "norm_label": ".exportjson()" }, { "label": ".exportMysql()", "file_type": "code", "source_file": "main/app/scraper_b3/scraper.py", - "source_location": "L527", + "source_location": "L530", "id": "scraper_b3_scraper_b3scraper_exportmysql", - "community": 21, + "community": 474, "norm_label": ".exportmysql()" }, { @@ -3810,7 +3828,7 @@ "source_file": "main/app/scraper_b3/xango.py", "source_location": "L1", "id": "main_app_scraper_b3_xango_py", - "community": 21, + "community": 474, "norm_label": "xango.py" }, { @@ -3819,7 +3837,7 @@ "source_file": "main/app/scraper_b3/xango.py", "source_location": "L15", "id": "scraper_b3_xango_calculateinvestingscore", - "community": 21, + "community": 474, "norm_label": "calculateinvestingscore()" }, { @@ -3828,7 +3846,7 @@ "source_file": "main/app/stocks_api/build.py", "source_location": "L1", "id": "main_app_stocks_api_build_py", - "community": 82, + "community": 497, "norm_label": "build.py" }, { @@ -3837,7 +3855,7 @@ "source_file": "main/app/stocks_api/build.py", "source_location": "L39", "id": "stocks_api_build_buildfeathercache", - "community": 82, + "community": 497, "norm_label": "buildfeathercache()" }, { @@ -3846,7 +3864,7 @@ "source_file": "main/app/stocks_api/build.py", "source_location": "L131", "id": "stocks_api_build_trybuildlock", - "community": 82, + "community": 497, "norm_label": "trybuildlock()" }, { @@ -3855,7 +3873,7 @@ "source_file": "main/app/stocks_api/build.py", "source_location": "L148", "id": "stocks_api_build_readfeatherdataframe", - "community": 82, + "community": 497, "norm_label": "readfeatherdataframe()" }, { @@ -3900,7 +3918,7 @@ "source_file": "main/app/stocks_api/cache.py", "source_location": "L47", "id": "stocks_api_cache_stockscachemanager_cachescheduler", - "community": 536, + "community": 82, "norm_label": ".cachescheduler()" }, { @@ -3927,7 +3945,7 @@ "source_file": "main/app/stocks_api/compress.py", "source_location": "L1", "id": "main_app_stocks_api_compress_py", - "community": 194, + "community": 251, "norm_label": "compress.py" }, { @@ -3936,7 +3954,7 @@ "source_file": "main/app/stocks_api/compress.py", "source_location": "L30", "id": "stocks_api_compress_getabbr", - "community": 194, + "community": 251, "norm_label": "getabbr()" }, { @@ -3945,7 +3963,7 @@ "source_file": "main/app/stocks_api/compress.py", "source_location": "L43", "id": "stocks_api_compress_getnest", - "community": 194, + "community": 251, "norm_label": "getnest()" }, { @@ -3963,7 +3981,7 @@ "source_file": "main/app/stocks_api/compress.py", "source_location": "L65", "id": "stocks_api_compress_compactvalue", - "community": 194, + "community": 251, "norm_label": "compactvalue()" }, { @@ -3972,7 +3990,7 @@ "source_file": "main/app/stocks_api/compress.py", "source_location": "L86", "id": "stocks_api_compress_compactrow", - "community": 194, + "community": 251, "norm_label": "compactrow()" }, { @@ -3981,7 +3999,7 @@ "source_file": "main/app/stocks_api/compress.py", "source_location": "L116", "id": "stocks_api_compress_compactcotations", - "community": 194, + "community": 251, "norm_label": "compactcotations()" }, { @@ -3990,7 +4008,7 @@ "source_file": "main/app/stocks_api/compress.py", "source_location": "L151", "id": "stocks_api_compress_compressresponse", - "community": 194, + "community": 251, "norm_label": "compressresponse()" }, { @@ -3999,7 +4017,7 @@ "source_file": "main/app/stocks_api/frame.py", "source_location": "L1", "id": "main_app_stocks_api_frame_py", - "community": 82, + "community": 497, "norm_label": "frame.py" }, { @@ -4008,7 +4026,7 @@ "source_file": "main/app/stocks_api/frame.py", "source_location": "L14", "id": "stocks_api_frame_optimizedtypes", - "community": 82, + "community": 497, "norm_label": "optimizedtypes()" }, { @@ -4017,7 +4035,7 @@ "source_file": "main/app/stocks_api/frame.py", "source_location": "L34", "id": "stocks_api_frame_arrowtypefor", - "community": 82, + "community": 497, "norm_label": "arrowtypefor()" }, { @@ -4035,7 +4053,7 @@ "source_file": "main/app/stocks_api/frame.py", "source_location": "L55", "id": "stocks_api_frame_buildtickerindex", - "community": 82, + "community": 497, "norm_label": "buildtickerindex()" }, { @@ -4240,7 +4258,7 @@ "label": "clearEndpointCache()", "file_type": "code", "source_file": "main/app/stocks_api/sync_cache.py", - "source_location": "L36", + "source_location": "L37", "id": "stocks_api_sync_cache_clearendpointcache", "community": 562, "norm_label": "clearendpointcache()" @@ -4260,7 +4278,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L17", "id": "stocks_api_util_dedupabbrev", - "community": 194, + "community": 502, "norm_label": "dedupabbrev()" }, { @@ -4269,7 +4287,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L26", "id": "stocks_api_util_autoabbreviate", - "community": 194, + "community": 502, "norm_label": "autoabbreviate()" }, { @@ -4278,7 +4296,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L49", "id": "stocks_api_util_generateabbreviations", - "community": 194, + "community": 502, "norm_label": "generateabbreviations()" }, { @@ -4314,7 +4332,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L98", "id": "stocks_api_util_detectnestedfields", - "community": 194, + "community": 502, "norm_label": "detectnestedfields()" }, { @@ -4353,6 +4371,384 @@ "community": 519, "norm_label": "getcurrentuser()" }, + { + "label": "earnings.py", + "file_type": "code", + "source_file": "main/app/wallet/earnings.py", + "source_location": "L1", + "id": "main_app_wallet_earnings_py", + "community": 152, + "norm_label": "earnings.py" + }, + { + "label": "syncEarnings()", + "file_type": "code", + "source_file": "main/app/wallet/earnings.py", + "source_location": "L24", + "id": "wallet_earnings_syncearnings", + "community": 152, + "norm_label": "syncearnings()" + }, + { + "label": "listEarnings()", + "file_type": "code", + "source_file": "main/app/wallet/earnings.py", + "source_location": "L107", + "id": "wallet_earnings_listearnings", + "community": 152, + "norm_label": "listearnings()" + }, + { + "label": "entries.py", + "file_type": "code", + "source_file": "main/app/wallet/entries.py", + "source_location": "L1", + "id": "main_app_wallet_entries_py", + "community": 152, + "norm_label": "entries.py" + }, + { + "label": "EntryCreate", + "file_type": "code", + "source_file": "main/app/wallet/entries.py", + "source_location": "L15", + "id": "wallet_entries_entrycreate", + "community": 564, + "norm_label": "entrycreate" + }, + { + "label": "EntryUpdate", + "file_type": "code", + "source_file": "main/app/wallet/entries.py", + "source_location": "L26", + "id": "wallet_entries_entryupdate", + "community": 564, + "norm_label": "entryupdate" + }, + { + "label": "applyEntries()", + "file_type": "code", + "source_file": "main/app/wallet/entries.py", + "source_location": "L33", + "id": "wallet_entries_applyentries", + "community": 152, + "norm_label": "applyentries()" + }, + { + "label": "recalcHolding()", + "file_type": "code", + "source_file": "main/app/wallet/entries.py", + "source_location": "L52", + "id": "wallet_entries_recalcholding", + "community": 152, + "norm_label": "recalcholding()" + }, + { + "label": "addEntry()", + "file_type": "code", + "source_file": "main/app/wallet/entries.py", + "source_location": "L89", + "id": "wallet_entries_addentry", + "community": 152, + "norm_label": "addentry()" + }, + { + "label": "listEntries()", + "file_type": "code", + "source_file": "main/app/wallet/entries.py", + "source_location": "L121", + "id": "wallet_entries_listentries", + "community": 152, + "norm_label": "listentries()" + }, + { + "label": "updateEntry()", + "file_type": "code", + "source_file": "main/app/wallet/entries.py", + "source_location": "L136", + "id": "wallet_entries_updateentry", + "community": 152, + "norm_label": "updateentry()" + }, + { + "label": "deleteEntry()", + "file_type": "code", + "source_file": "main/app/wallet/entries.py", + "source_location": "L166", + "id": "wallet_entries_deleteentry", + "community": 152, + "norm_label": "deleteentry()" + }, + { + "label": "positionAtDate()", + "file_type": "code", + "source_file": "main/app/wallet/entries.py", + "source_location": "L191", + "id": "wallet_entries_positionatdate", + "community": 152, + "norm_label": "positionatdate()" + }, + { + "label": "market_data.py", + "file_type": "code", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L1", + "id": "main_app_wallet_market_data_py", + "community": 152, + "norm_label": "market_data.py" + }, + { + "label": "fetchLivePrices()", + "file_type": "code", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L14", + "id": "wallet_market_data_fetchliveprices", + "community": 152, + "norm_label": "fetchliveprices()" + }, + { + "label": "fetchCachedClose()", + "file_type": "code", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L40", + "id": "wallet_market_data_fetchcachedclose", + "community": 152, + "norm_label": "fetchcachedclose()" + }, + { + "label": "fetchMarketDividends()", + "file_type": "code", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L61", + "id": "wallet_market_data_fetchmarketdividends", + "community": 152, + "norm_label": "fetchmarketdividends()" + }, + { + "label": "fetchPadraoCloses()", + "file_type": "code", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L80", + "id": "wallet_market_data_fetchpadraocloses", + "community": 152, + "norm_label": "fetchpadraocloses()" + }, + { + "label": "performance.py", + "file_type": "code", + "source_file": "main/app/wallet/performance.py", + "source_location": "L1", + "id": "main_app_wallet_performance_py", + "community": 152, + "norm_label": "performance.py" + }, + { + "label": "cachedPerformance()", + "file_type": "code", + "source_file": "main/app/wallet/performance.py", + "source_location": "L21", + "id": "wallet_performance_cachedperformance", + "community": 152, + "norm_label": "cachedperformance()" + }, + { + "label": "getPerformance()", + "file_type": "code", + "source_file": "main/app/wallet/performance.py", + "source_location": "L145", + "id": "wallet_performance_getperformance", + "community": 152, + "norm_label": "getperformance()" + }, + { + "label": "positions.py", + "file_type": "code", + "source_file": "main/app/wallet/positions.py", + "source_location": "L1", + "id": "main_app_wallet_positions_py", + "community": 482, + "norm_label": "positions.py" + }, + { + "label": "fetchXangoScores()", + "file_type": "code", + "source_file": "main/app/wallet/positions.py", + "source_location": "L17", + "id": "wallet_positions_fetchxangoscores", + "community": 482, + "norm_label": "fetchxangoscores()" + }, + { + "label": "weightOf()", + "file_type": "code", + "source_file": "main/app/wallet/positions.py", + "source_location": "L49", + "id": "wallet_positions_weightof", + "community": 482, + "norm_label": "weightof()" + }, + { + "label": "pricePass()", + "file_type": "code", + "source_file": "main/app/wallet/positions.py", + "source_location": "L53", + "id": "wallet_positions_pricepass", + "community": 482, + "norm_label": "pricepass()" + }, + { + "label": "rebalanceDeltas()", + "file_type": "code", + "source_file": "main/app/wallet/positions.py", + "source_location": "L75", + "id": "wallet_positions_rebalancedeltas", + "community": 482, + "norm_label": "rebalancedeltas()" + }, + { + "label": "getPositions()", + "file_type": "code", + "source_file": "main/app/wallet/positions.py", + "source_location": "L91", + "id": "wallet_positions_getpositions", + "community": 482, + "norm_label": "getpositions()" + }, + { + "label": "getRebalance()", + "file_type": "code", + "source_file": "main/app/wallet/positions.py", + "source_location": "L138", + "id": "wallet_positions_getrebalance", + "community": 482, + "norm_label": "getrebalance()" + }, + { + "label": "XANGO quality score per ticker (0-100 scale). One fundamental read per tick", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L18", + "id": "wallet_positions_rationale_18", + "community": 482, + "norm_label": "xango quality score per ticker (0-100 scale). one fundamental read per tick" + }, + { + "label": "Shared live-price/equity pass for positions + rebalance (single source, no dupli", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L56", + "id": "wallet_positions_rationale_56", + "community": 482, + "norm_label": "shared live-price/equity pass for positions + rebalance (single source, no dupli" + }, + { + "label": "Weight-share deltas on backend floats: target_i = w_i/\u03a3w, targetEquity = target_", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L78", + "id": "wallet_positions_rationale_78", + "community": 482, + "norm_label": "weight-share deltas on backend floats: target_i = w_i/\u03c3w, targetequity = target_" + }, + { + "label": "summary.py", + "file_type": "code", + "source_file": "main/app/wallet/summary.py", + "source_location": "L1", + "id": "main_app_wallet_summary_py", + "community": 152, + "norm_label": "summary.py" + }, + { + "label": "TargetUpsert", + "file_type": "code", + "source_file": "main/app/wallet/summary.py", + "source_location": "L17", + "id": "wallet_summary_targetupsert", + "community": 564, + "norm_label": "targetupsert" + }, + { + "label": "RatingUpsert", + "file_type": "code", + "source_file": "main/app/wallet/summary.py", + "source_location": "L24", + "id": "wallet_summary_ratingupsert", + "community": 564, + "norm_label": "ratingupsert" + }, + { + "label": "getSummary()", + "file_type": "code", + "source_file": "main/app/wallet/summary.py", + "source_location": "L30", + "id": "wallet_summary_getsummary", + "community": 152, + "norm_label": "getsummary()" + }, + { + "label": "getAllocation()", + "file_type": "code", + "source_file": "main/app/wallet/summary.py", + "source_location": "L88", + "id": "wallet_summary_getallocation", + "community": 152, + "norm_label": "getallocation()" + }, + { + "label": "upsertTarget()", + "file_type": "code", + "source_file": "main/app/wallet/summary.py", + "source_location": "L118", + "id": "wallet_summary_upserttarget", + "community": 152, + "norm_label": "upserttarget()" + }, + { + "label": "set_rating()", + "file_type": "code", + "source_file": "main/app/wallet/summary.py", + "source_location": "L147", + "id": "wallet_summary_set_rating", + "community": 152, + "norm_label": "set_rating()" + }, + { + "label": "wallets.py", + "file_type": "code", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L1", + "id": "main_app_wallet_wallets_py", + "community": 152, + "norm_label": "wallets.py" + }, + { + "label": "getWallet()", + "file_type": "code", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L11", + "id": "wallet_wallets_getwallet", + "community": 152, + "norm_label": "getwallet()" + }, + { + "label": "createWallet()", + "file_type": "code", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L18", + "id": "wallet_wallets_createwallet", + "community": 152, + "norm_label": "createwallet()" + }, + { + "label": "listWallets()", + "file_type": "code", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L26", + "id": "wallet_wallets_listwallets", + "community": 152, + "norm_label": "listwallets()" + }, { "label": "authentication_controller.py", "file_type": "code", @@ -4431,7 +4827,7 @@ "source_file": "main/controller/authentication_controller.py", "source_location": "L154", "id": "controller_authentication_controller_introspect", - "community": 519, + "community": 592, "norm_label": "introspect()" }, { @@ -4440,7 +4836,7 @@ "source_file": "main/controller/authentication_controller.py", "source_location": "L180", "id": "controller_authentication_controller_googlelogin", - "community": 58, + "community": 631, "norm_label": "googlelogin()" }, { @@ -4458,7 +4854,7 @@ "source_file": "main/controller/orunmila_controller.py", "source_location": "L1", "id": "main_controller_orunmila_controller_py", - "community": 68, + "community": 234, "norm_label": "orunmila_controller.py" }, { @@ -4467,7 +4863,7 @@ "source_file": "main/controller/orunmila_controller.py", "source_location": "L26", "id": "controller_orunmila_controller_verifysessionownsership", - "community": 68, + "community": 234, "norm_label": "verifysessionownsership()" }, { @@ -4476,7 +4872,7 @@ "source_file": "main/controller/orunmila_controller.py", "source_location": "L32", "id": "controller_orunmila_controller_health", - "community": 68, + "community": 234, "norm_label": "health()" }, { @@ -4485,7 +4881,7 @@ "source_file": "main/controller/orunmila_controller.py", "source_location": "L37", "id": "controller_orunmila_controller_getsessions", - "community": 68, + "community": 234, "norm_label": "getsessions()" }, { @@ -4494,7 +4890,7 @@ "source_file": "main/controller/orunmila_controller.py", "source_location": "L56", "id": "controller_orunmila_controller_updatesessiontitle", - "community": 68, + "community": 234, "norm_label": "updatesessiontitle()" }, { @@ -4503,7 +4899,7 @@ "source_file": "main/controller/orunmila_controller.py", "source_location": "L71", "id": "controller_orunmila_controller_gethistory", - "community": 68, + "community": 234, "norm_label": "gethistory()" }, { @@ -4512,7 +4908,7 @@ "source_file": "main/controller/orunmila_controller.py", "source_location": "L90", "id": "controller_orunmila_controller_deletesession", - "community": 68, + "community": 234, "norm_label": "deletesession()" }, { @@ -4521,7 +4917,7 @@ "source_file": "main/controller/orunmila_controller.py", "source_location": "L103", "id": "controller_orunmila_controller_chat_stream", - "community": 68, + "community": 234, "norm_label": "chat_stream()" }, { @@ -4530,7 +4926,7 @@ "source_file": "main/controller/orunmila_controller.py", "source_location": "L154", "id": "controller_orunmila_controller_resumechatstream", - "community": 68, + "community": 234, "norm_label": "resumechatstream()" }, { @@ -4539,7 +4935,7 @@ "source_file": "main/controller/orunmila_controller.py", "source_location": "L166", "id": "controller_orunmila_controller_deleteworkspacefile", - "community": 68, + "community": 234, "norm_label": "deleteworkspacefile()" }, { @@ -4548,7 +4944,7 @@ "source_file": "main/controller/orunmila_controller.py", "source_location": "L179", "id": "controller_orunmila_controller_downloadworkspacefile", - "community": 68, + "community": 234, "norm_label": "downloadworkspacefile()" }, { @@ -4557,7 +4953,7 @@ "source_file": "main/controller/orunmila_controller.py", "source_location": "L195", "id": "controller_orunmila_controller_listworkspacefiles", - "community": 68, + "community": 234, "norm_label": "listworkspacefiles()" }, { @@ -4566,7 +4962,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L1", "id": "main_controller_stocksapi_controller_py", - "community": 81, + "community": 560, "norm_label": "stocksapi_controller.py" }, { @@ -4575,7 +4971,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L28", "id": "controller_stocksapi_controller_health", - "community": 81, + "community": 560, "norm_label": "health()" }, { @@ -4584,7 +4980,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L44", "id": "controller_stocksapi_controller_listfields", - "community": 222, + "community": 194, "norm_label": "listfields()" }, { @@ -4629,7 +5025,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L45", "id": "controller_stocksapi_controller_rationale_45", - "community": 222, + "community": 194, "norm_label": "discover available field names before querying /historical or /fundamental." }, { @@ -4749,6 +5145,195 @@ "community": 501, "norm_label": "revokeallsessions()" }, + { + "label": "wallet_controller.py", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L1", + "id": "main_controller_wallet_controller_py", + "community": 575, + "norm_label": "wallet_controller.py" + }, + { + "label": "WalletCreate", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L20", + "id": "controller_wallet_controller_walletcreate", + "community": 564, + "norm_label": "walletcreate" + }, + { + "label": "create_wallet_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L25", + "id": "controller_wallet_controller_create_wallet_route", + "community": 575, + "norm_label": "create_wallet_route()" + }, + { + "label": "list_wallets_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L35", + "id": "controller_wallet_controller_list_wallets_route", + "community": 575, + "norm_label": "list_wallets_route()" + }, + { + "label": "serialize_holding()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L45", + "id": "controller_wallet_controller_serialize_holding", + "community": 575, + "norm_label": "serialize_holding()" + }, + { + "label": "serialize_entry()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L51", + "id": "controller_wallet_controller_serialize_entry", + "community": 575, + "norm_label": "serialize_entry()" + }, + { + "label": "create_entry_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L66", + "id": "controller_wallet_controller_create_entry_route", + "community": 575, + "norm_label": "create_entry_route()" + }, + { + "label": "list_entries_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L76", + "id": "controller_wallet_controller_list_entries_route", + "community": 575, + "norm_label": "list_entries_route()" + }, + { + "label": "update_entry_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L89", + "id": "controller_wallet_controller_update_entry_route", + "community": 575, + "norm_label": "update_entry_route()" + }, + { + "label": "delete_entry_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L100", + "id": "controller_wallet_controller_delete_entry_route", + "community": 575, + "norm_label": "delete_entry_route()" + }, + { + "label": "list_positions_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L110", + "id": "controller_wallet_controller_list_positions_route", + "community": 575, + "norm_label": "list_positions_route()" + }, + { + "label": "get_rebalance_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L119", + "id": "controller_wallet_controller_get_rebalance_route", + "community": 575, + "norm_label": "get_rebalance_route()" + }, + { + "label": "get_summary_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L128", + "id": "controller_wallet_controller_get_summary_route", + "community": 575, + "norm_label": "get_summary_route()" + }, + { + "label": "get_allocation_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L137", + "id": "controller_wallet_controller_get_allocation_route", + "community": 575, + "norm_label": "get_allocation_route()" + }, + { + "label": "upsert_target_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L147", + "id": "controller_wallet_controller_upsert_target_route", + "community": 575, + "norm_label": "upsert_target_route()" + }, + { + "label": "set_rating_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L162", + "id": "controller_wallet_controller_set_rating_route", + "community": 575, + "norm_label": "set_rating_route()" + }, + { + "label": "EarningsSync", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L171", + "id": "controller_wallet_controller_earningssync", + "community": 564, + "norm_label": "earningssync" + }, + { + "label": "serialize_earning()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L175", + "id": "controller_wallet_controller_serialize_earning", + "community": 575, + "norm_label": "serialize_earning()" + }, + { + "label": "list_earnings_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L186", + "id": "controller_wallet_controller_list_earnings_route", + "community": 575, + "norm_label": "list_earnings_route()" + }, + { + "label": "sync_earnings_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L196", + "id": "controller_wallet_controller_sync_earnings_route", + "community": 575, + "norm_label": "sync_earnings_route()" + }, + { + "label": "get_performance_route()", + "file_type": "code", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L205", + "id": "controller_wallet_controller_get_performance_route", + "community": 575, + "norm_label": "get_performance_route()" + }, { "label": "base.py", "file_type": "code", @@ -4773,7 +5358,7 @@ "source_file": "main/models/memory.py", "source_location": "L8", "id": "models_memory_orunmilamemory", - "community": 45, + "community": 564, "norm_label": "orunmilamemory" }, { @@ -4782,7 +5367,7 @@ "source_file": "", "source_location": "", "id": "base", - "community": 140, + "community": 564, "norm_label": "base" }, { @@ -4791,7 +5376,7 @@ "source_file": "main/models/orunmila.py", "source_location": "L1", "id": "main_models_orunmila_py", - "community": 231, + "community": 137, "norm_label": "orunmila.py" }, { @@ -4800,7 +5385,7 @@ "source_file": "main/models/orunmila.py", "source_location": "L7", "id": "models_orunmila_orunmilasession", - "community": 231, + "community": 137, "norm_label": "orunmilasession" }, { @@ -4809,7 +5394,7 @@ "source_file": "main/models/sandbox.py", "source_location": "L1", "id": "main_models_sandbox_py", - "community": 4, + "community": 234, "norm_label": "sandbox.py" }, { @@ -4818,7 +5403,7 @@ "source_file": "main/models/sandbox.py", "source_location": "L5", "id": "models_sandbox_orunmilasandbox", - "community": 140, + "community": 234, "norm_label": "orunmilasandbox" }, { @@ -4929,13 +5514,76 @@ "community": 44, "norm_label": "usersession" }, + { + "label": "wallet.py", + "file_type": "code", + "source_file": "main/models/wallet.py", + "source_location": "L1", + "id": "main_models_wallet_py", + "community": 564, + "norm_label": "wallet.py" + }, + { + "label": "Wallet", + "file_type": "code", + "source_file": "main/models/wallet.py", + "source_location": "L18", + "id": "models_wallet_wallet", + "community": 564, + "norm_label": "wallet" + }, + { + "label": "Holding", + "file_type": "code", + "source_file": "main/models/wallet.py", + "source_location": "L28", + "id": "models_wallet_holding", + "community": 564, + "norm_label": "holding" + }, + { + "label": "Transaction", + "file_type": "code", + "source_file": "main/models/wallet.py", + "source_location": "L45", + "id": "models_wallet_transaction", + "community": 564, + "norm_label": "transaction" + }, + { + "label": "Target", + "file_type": "code", + "source_file": "main/models/wallet.py", + "source_location": "L60", + "id": "models_wallet_target", + "community": 564, + "norm_label": "target" + }, + { + "label": "Snapshot", + "file_type": "code", + "source_file": "main/models/wallet.py", + "source_location": "L72", + "id": "models_wallet_snapshot", + "community": 564, + "norm_label": "snapshot" + }, + { + "label": "Earning", + "file_type": "code", + "source_file": "main/models/wallet.py", + "source_location": "L89", + "id": "models_wallet_earning", + "community": 564, + "norm_label": "earning" + }, { "label": "authentication_service.py", "file_type": "code", "source_file": "main/service/authentication_service.py", "source_location": "L1", "id": "main_service_authentication_service_py", - "community": 569, + "community": 536, "norm_label": "authentication_service.py" }, { @@ -4944,7 +5592,7 @@ "source_file": "main/service/authentication_service.py", "source_location": "L5", "id": "service_authentication_service_authenticationservice", - "community": 45, + "community": 536, "norm_label": "authenticationservice" }, { @@ -4953,7 +5601,7 @@ "source_file": "main/service/authentication_service.py", "source_location": "L7", "id": "service_authentication_service_initialize", - "community": 569, + "community": 536, "norm_label": "initialize()" }, { @@ -4962,7 +5610,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L1", "id": "main_service_orunmila_service_py", - "community": 569, + "community": 536, "norm_label": "orunmila_service.py" }, { @@ -4980,7 +5628,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L65", "id": "service_orunmila_service_orunmilaservice", - "community": 569, + "community": 536, "norm_label": "orunmilaservice" }, { @@ -4989,7 +5637,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L67", "id": "service_orunmila_service_initialize", - "community": 569, + "community": 536, "norm_label": "initialize()" }, { @@ -4998,7 +5646,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L1", "id": "main_service_scraper_service_py", - "community": 21, + "community": 474, "norm_label": "scraper_service.py" }, { @@ -5007,7 +5655,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L13", "id": "service_scraper_service_runscraper", - "community": 21, + "community": 474, "norm_label": "runscraper()" }, { @@ -5016,7 +5664,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L23", "id": "service_scraper_service_registerscraperjobs", - "community": 21, + "community": 474, "norm_label": "registerscraperjobs()" }, { @@ -5025,7 +5673,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L49", "id": "service_scraper_service_scraperservice", - "community": 21, + "community": 474, "norm_label": "scraperservice" }, { @@ -5034,7 +5682,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L51", "id": "service_scraper_service_initialize", - "community": 21, + "community": 474, "norm_label": "initialize()" }, { @@ -5043,7 +5691,7 @@ "source_file": "main/service/stocksapi_service.py", "source_location": "L1", "id": "main_service_stocksapi_service_py", - "community": 569, + "community": 536, "norm_label": "stocksapi_service.py" }, { @@ -5052,7 +5700,7 @@ "source_file": "main/service/stocksapi_service.py", "source_location": "L10", "id": "service_stocksapi_service_mcpdetectmiddleware", - "community": 569, + "community": 536, "norm_label": "mcpdetectmiddleware" }, { @@ -5061,7 +5709,7 @@ "source_file": "main/service/stocksapi_service.py", "source_location": "L11", "id": "service_stocksapi_service_mcpdetectmiddleware_init", - "community": 569, + "community": 536, "norm_label": ".__init__()" }, { @@ -5070,7 +5718,7 @@ "source_file": "main/service/stocksapi_service.py", "source_location": "L14", "id": "service_stocksapi_service_mcpdetectmiddleware_call", - "community": 569, + "community": 536, "norm_label": ".__call__()" }, { @@ -5079,7 +5727,7 @@ "source_file": "main/service/stocksapi_service.py", "source_location": "L25", "id": "service_stocksapi_service_stocksapiservice", - "community": 569, + "community": 536, "norm_label": "stocksapiservice" }, { @@ -5088,7 +5736,7 @@ "source_file": "main/service/stocksapi_service.py", "source_location": "L27", "id": "service_stocksapi_service_initialize", - "community": 569, + "community": 536, "norm_label": "initialize()" }, { @@ -5127,13 +5775,40 @@ "community": 536, "norm_label": "initialize()" }, + { + "label": "wallet_service.py", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L1", + "id": "main_service_wallet_service_py", + "community": 54, + "norm_label": "wallet_service.py" + }, + { + "label": "WalletService", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L9", + "id": "service_wallet_service_walletservice", + "community": 54, + "norm_label": "walletservice" + }, + { + "label": "initialize()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L11", + "id": "service_wallet_service_initialize", + "community": 536, + "norm_label": "initialize()" + }, { "label": "connectivity.py", "file_type": "code", "source_file": "main/utils/connectivity.py", "source_location": "L1", "id": "main_utils_connectivity_py", - "community": 523, + "community": 72, "norm_label": "connectivity.py" }, { @@ -5142,7 +5817,7 @@ "source_file": "main/utils/connectivity.py", "source_location": "L11", "id": "utils_connectivity_checkdatabaseconnection", - "community": 523, + "community": 72, "norm_label": "checkdatabaseconnection()" }, { @@ -5160,7 +5835,7 @@ "source_file": "main/utils/errors.py", "source_location": "L1", "id": "main_utils_errors_py", - "community": 572, + "community": 569, "norm_label": "errors.py" }, { @@ -5196,7 +5871,7 @@ "source_file": "main/utils/errors.py", "source_location": "L26", "id": "utils_errors_builderrorresponse", - "community": 572, + "community": 569, "norm_label": "builderrorresponse()" }, { @@ -5205,7 +5880,7 @@ "source_file": "main/utils/errors.py", "source_location": "L36", "id": "utils_errors_httpexceptionhandler", - "community": 572, + "community": 569, "norm_label": "httpexceptionhandler()" }, { @@ -5214,7 +5889,7 @@ "source_file": "main/utils/errors.py", "source_location": "L43", "id": "utils_errors_validationexceptionhandler", - "community": 572, + "community": 569, "norm_label": "validationexceptionhandler()" }, { @@ -5223,7 +5898,7 @@ "source_file": "main/utils/errors.py", "source_location": "L55", "id": "utils_errors_genericexceptionhandler", - "community": 572, + "community": 569, "norm_label": "genericexceptionhandler()" }, { @@ -5232,7 +5907,7 @@ "source_file": "main/utils/errors.py", "source_location": "L64", "id": "utils_errors_registererrorhandlers", - "community": 120, + "community": 498, "norm_label": "registererrorhandlers()" }, { @@ -5241,7 +5916,7 @@ "source_file": "main/utils/http_session.py", "source_location": "L1", "id": "main_utils_http_session_py", - "community": 574, + "community": 184, "norm_label": "http_session.py" }, { @@ -5250,7 +5925,7 @@ "source_file": "main/utils/http_session.py", "source_location": "L8", "id": "utils_http_session_getsession", - "community": 574, + "community": 184, "norm_label": "getsession()" }, { @@ -5313,7 +5988,7 @@ "source_file": "main/utils/migrator.py", "source_location": "L1", "id": "main_utils_migrator_py", - "community": 523, + "community": 72, "norm_label": "migrator.py" }, { @@ -5322,7 +5997,7 @@ "source_file": "main/utils/migrator.py", "source_location": "L8", "id": "utils_migrator_runmigrations", - "community": 523, + "community": 72, "norm_label": "runmigrations()" }, { @@ -5367,7 +6042,7 @@ "source_file": "main/utils/roles.py", "source_location": "L1", "id": "main_utils_roles_py", - "community": 131, + "community": 584, "norm_label": "roles.py" }, { @@ -5376,7 +6051,7 @@ "source_file": "main/utils/roles.py", "source_location": "L5", "id": "utils_roles_permission", - "community": 45, + "community": 140, "norm_label": "permission" }, { @@ -5385,14 +6060,14 @@ "source_file": "", "source_location": "", "id": "intflag", - "community": 45, + "community": 564, "norm_label": "intflag" }, { "label": "ALL()", "file_type": "code", "source_file": "main/utils/roles.py", - "source_location": "L13", + "source_location": "L15", "id": "utils_roles_all", "community": 131, "norm_label": "all()" @@ -5401,27 +6076,27 @@ "label": "Roles", "file_type": "code", "source_file": "main/utils/roles.py", - "source_location": "L17", + "source_location": "L19", "id": "utils_roles_roles", - "community": 45, + "community": 564, "norm_label": "roles" }, { "label": "checkAccess()", "file_type": "code", "source_file": "main/utils/roles.py", - "source_location": "L29", + "source_location": "L31", "id": "utils_roles_checkaccess", - "community": 131, + "community": 584, "norm_label": "checkaccess()" }, { "label": "requirePermission()", "file_type": "code", "source_file": "main/utils/roles.py", - "source_location": "L42", + "source_location": "L44", "id": "utils_roles_requirepermission", - "community": 131, + "community": 584, "norm_label": "requirepermission()" }, { @@ -5457,7 +6132,7 @@ "source_file": "main/utils/service_manager.py", "source_location": "L1", "id": "main_utils_service_manager_py", - "community": 569, + "community": 536, "norm_label": "service_manager.py" }, { @@ -5466,7 +6141,7 @@ "source_file": "main/utils/service_manager.py", "source_location": "L19", "id": "utils_service_manager_getapp", - "community": 569, + "community": 536, "norm_label": "getapp()" }, { @@ -5475,7 +6150,7 @@ "source_file": "main/utils/service_manager.py", "source_location": "L43", "id": "utils_service_manager_runall", - "community": 569, + "community": 536, "norm_label": "runall()" }, { @@ -5484,7 +6159,7 @@ "source_file": "main/utils/models/loader.py", "source_location": "L1", "id": "main_utils_models_loader_py", - "community": 602, + "community": 536, "norm_label": "loader.py" }, { @@ -5493,7 +6168,7 @@ "source_file": "main/utils/models/loader.py", "source_location": "L12", "id": "models_loader_getembeddingmodel", - "community": 602, + "community": 536, "norm_label": "getembeddingmodel()" }, { @@ -5518,7 +6193,7 @@ "label": "getDatabaseUrl()", "file_type": "code", "source_file": "migrations/env.py", - "source_location": "L27", + "source_location": "L29", "id": "migrations_env_getdatabaseurl", "community": 240, "norm_label": "getdatabaseurl()" @@ -5527,7 +6202,7 @@ "label": "runMigrationsOffline()", "file_type": "code", "source_file": "migrations/env.py", - "source_location": "L31", + "source_location": "L33", "id": "migrations_env_runmigrationsoffline", "community": 240, "norm_label": "runmigrationsoffline()" @@ -5536,7 +6211,7 @@ "label": "runMigrationsOnline()", "file_type": "code", "source_file": "migrations/env.py", - "source_location": "L43", + "source_location": "L45", "id": "migrations_env_runmigrationsonline", "community": 240, "norm_label": "runmigrationsonline()" @@ -5613,6 +6288,42 @@ "community": 241, "norm_label": "user sessions table revision id: 4a2f1c9e3b5d revises: 25af7ad931e7 create" }, + { + "label": "73211a401c34_wallet_tables.py", + "file_type": "code", + "source_file": "migrations/versions/73211a401c34_wallet_tables.py", + "source_location": "L1", + "id": "migrations_versions_73211a401c34_wallet_tables_py", + "community": 622, + "norm_label": "73211a401c34_wallet_tables.py" + }, + { + "label": "upgrade()", + "file_type": "code", + "source_file": "migrations/versions/73211a401c34_wallet_tables.py", + "source_location": "L22", + "id": "versions_73211a401c34_wallet_tables_upgrade", + "community": 622, + "norm_label": "upgrade()" + }, + { + "label": "downgrade()", + "file_type": "code", + "source_file": "migrations/versions/73211a401c34_wallet_tables.py", + "source_location": "L104", + "id": "versions_73211a401c34_wallet_tables_downgrade", + "community": 622, + "norm_label": "downgrade()" + }, + { + "label": "wallet tables Revision ID: 73211a401c34 Revises: f7a8b9c0d1e2 Create Date:", + "file_type": "rationale", + "source_file": "migrations/versions/73211a401c34_wallet_tables.py", + "source_location": "L1", + "id": "versions_73211a401c34_wallet_tables_rationale_1", + "community": 622, + "norm_label": "wallet tables revision id: 73211a401c34 revises: f7a8b9c0d1e2 create date:" + }, { "label": "9f3b339dde20_drop_unused_user_sessions_columns.py", "file_type": "code", @@ -5802,6 +6513,42 @@ "community": 242, "norm_label": "drop embeddingmodel and embeddingversion columns revision id: c2e4f6a8b0c1 r" }, + { + "label": "c4d1e8f2a917_wallet_earnings.py", + "file_type": "code", + "source_file": "migrations/versions/c4d1e8f2a917_wallet_earnings.py", + "source_location": "L1", + "id": "migrations_versions_c4d1e8f2a917_wallet_earnings_py", + "community": 624, + "norm_label": "c4d1e8f2a917_wallet_earnings.py" + }, + { + "label": "upgrade()", + "file_type": "code", + "source_file": "migrations/versions/c4d1e8f2a917_wallet_earnings.py", + "source_location": "L27", + "id": "versions_c4d1e8f2a917_wallet_earnings_upgrade", + "community": 624, + "norm_label": "upgrade()" + }, + { + "label": "downgrade()", + "file_type": "code", + "source_file": "migrations/versions/c4d1e8f2a917_wallet_earnings.py", + "source_location": "L51", + "id": "versions_c4d1e8f2a917_wallet_earnings_downgrade", + "community": 624, + "norm_label": "downgrade()" + }, + { + "label": "wallet earnings Revision ID: c4d1e8f2a917 Revises: 73211a401c34 Create Date: 20", + "file_type": "rationale", + "source_file": "migrations/versions/c4d1e8f2a917_wallet_earnings.py", + "source_location": "L1", + "id": "versions_c4d1e8f2a917_wallet_earnings_rationale_1", + "community": 624, + "norm_label": "wallet earnings revision id: c4d1e8f2a917 revises: 73211a401c34 create date: 20" + }, { "label": "d3df3fc5ca72_rename_memory_base_score.py", "file_type": "code", @@ -6193,7 +6940,7 @@ "label": "User structure defined by string roles:", "file_type": "document", "source_file": "TODO.md", - "source_location": "L39", + "source_location": "L43", "id": "server_todo_user_structure_defined_by_string_roles", "community": 187, "norm_label": "user structure defined by string roles:" @@ -6202,7 +6949,7 @@ "label": "USER:", "file_type": "document", "source_file": "TODO.md", - "source_location": "L48", + "source_location": "L52", "id": "server_todo_user", "community": 187, "norm_label": "user:" @@ -6211,7 +6958,7 @@ "label": "PREMIUM:", "file_type": "document", "source_file": "TODO.md", - "source_location": "L51", + "source_location": "L55", "id": "server_todo_premium", "community": 187, "norm_label": "premium:" @@ -6220,7 +6967,7 @@ "label": "DEVELOPER:", "file_type": "document", "source_file": "TODO.md", - "source_location": "L54", + "source_location": "L58", "id": "server_todo_developer", "community": 187, "norm_label": "developer:" @@ -7066,7 +7813,7 @@ "label": "2. User lifecycle end-to-end", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L30", + "source_location": "L29", "id": "superpowers_investidor10_wallet_research_2_user_lifecycle_end_to_end", "community": 539, "norm_label": "2. user lifecycle end-to-end" @@ -7075,7 +7822,7 @@ "label": "3. Wallet API reference", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L40", + "source_location": "L39", "id": "superpowers_investidor10_wallet_research_3_wallet_api_reference", "community": 539, "norm_label": "3. wallet api reference" @@ -7084,7 +7831,7 @@ "label": "4. Data model inference (from payloads, no DB access)", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L65", + "source_location": "L64", "id": "superpowers_investidor10_wallet_research_4_data_model_inference_from_payloads_no_db_access", "community": 539, "norm_label": "4. data model inference (from payloads, no db access)" @@ -7093,7 +7840,7 @@ "label": "5. Product logic", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L74", + "source_location": "L73", "id": "superpowers_investidor10_wallet_research_5_product_logic", "community": 539, "norm_label": "5. product logic" @@ -7102,7 +7849,7 @@ "label": "5b. Gaps / unverified (do not treat as fact)", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L82", + "source_location": "L81", "id": "superpowers_investidor10_wallet_research_5b_gaps_unverified_do_not_treat_as_fact", "community": 539, "norm_label": "5b. gaps / unverified (do not treat as fact)" @@ -7111,7 +7858,7 @@ "label": "6. Concrete Mansa proposal (build first \u2192 later; minimal sketches)", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L86", + "source_location": "L85", "id": "superpowers_investidor10_wallet_research_6_concrete_mansa_proposal_build_first_later_minimal_sketches", "community": 539, "norm_label": "6. concrete mansa proposal (build first \u2192 later; minimal sketches)" @@ -7165,25 +7912,25 @@ "label": "2. Domain model", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L38", + "source_location": "L47", "id": "superpowers_investidor10_wallet_spec_2_domain_model", "community": 130, "norm_label": "2. domain model" }, { - "label": "3. API contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` \u2192 `main/service/wallet_service.py::` \u2192 `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout)", + "label": "3. API contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` \u2192 `main/service/wallet_service.py::` \u2192 `main/models/wallet.py::`; auth = wallet-local dependency on the **introspect contract** (user directive 2026-09-30): resolve the raw token (`X-Access-Token` \u2192 `Authorization: Bearer` \u2192 `mansa_token` cookie, order per `main/app/authentication/util.py:54-66`) \u2192 `introspectToken(db, raw)` (`main/app/authentication/introspect.py:14`) \u2192 `{userId, username, roles}` \u2192 `Roles.checkAccess(roles, Permission.WALLET)` (`main/utils/roles.py:29-39`) \u2192 `403` if absent; `Depends(getSession)` for the DB session)", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L49", - "id": "superpowers_investidor10_wallet_spec_3_api_contracts_all_under_wallet_chain_main_controller_wallet_controller_py_main_service_wallet_service_py_fn_main_models_wallet_py_model_auth_depends_usermanager_getcurrentuser_depends_getsession_throughout", + "source_location": "L58", + "id": "superpowers_investidor10_wallet_spec_3_api_contracts_all_under_wallet_chain_main_controller_wallet_controller_py_main_service_wallet_service_py_fn_main_models_wallet_py_model_auth_wallet_local_dependency_on_the_introspect_contract_user_directive_2026_09_30_resolve_the_raw_token_x_access_token_authorization_bearer_mansa_token_cookie_order_per_main_app_authentication_util_py_54_66_introspecttoken_db_raw_main_app_authentication_introspect_py_14_userid_username_roles_roles_checkaccess_roles_permission_wallet_main_utils_roles_py_29_39_403_if_absent_depends_getsession_for_the_db_session", "community": 130, - "norm_label": "3. api contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` \u2192 `main/service/wallet_service.py::` \u2192 `main/models/wallet.py::`; auth `depends(usermanager.getcurrentuser)` + `depends(getsession)` throughout)" + "norm_label": "3. api contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` \u2192 `main/service/wallet_service.py::` \u2192 `main/models/wallet.py::`; auth = wallet-local dependency on the **introspect contract** (user directive 2026-09-30): resolve the raw token (`x-access-token` \u2192 `authorization: bearer` \u2192 `mansa_token` cookie, order per `main/app/authentication/util.py:54-66`) \u2192 `introspecttoken(db, raw)` (`main/app/authentication/introspect.py:14`) \u2192 `{userid, username, roles}` \u2192 `roles.checkaccess(roles, permission.wallet)` (`main/utils/roles.py:29-39`) \u2192 `403` if absent; `depends(getsession)` for the db session)" }, { "label": "4. Phased build plan (writing-plans: each phase independently reviewable; reviewer PASS per phase)", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L66", + "source_location": "L75", "id": "superpowers_investidor10_wallet_spec_4_phased_build_plan_writing_plans_each_phase_independently_reviewable_reviewer_pass_per_phase", "community": 130, "norm_label": "4. phased build plan (writing-plans: each phase independently reviewable; reviewer pass per phase)" @@ -7192,7 +7939,7 @@ "label": "5. Risks / assumptions (honest flags carried over \u2014 do not treat as fact)", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L72", + "source_location": "L80", "id": "superpowers_investidor10_wallet_spec_5_risks_assumptions_honest_flags_carried_over_do_not_treat_as_fact", "community": 130, "norm_label": "5. risks / assumptions (honest flags carried over \u2014 do not treat as fact)" @@ -7201,7 +7948,7 @@ "label": "6. Readiness assessment (s3, verified 2026-09-29) \u2014 prerequisites before P1", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L81", + "source_location": "L89", "id": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", "community": 130, "norm_label": "6. readiness assessment (s3, verified 2026-09-29) \u2014 prerequisites before p1" @@ -7210,7 +7957,7 @@ "label": "6.1 DB & migrations (`user_db`) \u2014 CONTESTED (\u00a77.1): 3 actions, incl. one destructive autogenerate risk", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L87", + "source_location": "L95", "id": "superpowers_investidor10_wallet_spec_6_1_db_migrations_user_db_contested_7_1_3_actions_incl_one_destructive_autogenerate_risk", "community": 130, "norm_label": "6.1 db & migrations (`user_db`) \u2014 contested (\u00a77.1): 3 actions, incl. one destructive autogenerate risk" @@ -7219,7 +7966,7 @@ "label": "6.2 Stocks/price access \u2014 CONFIRMED + extended (\u00a77.2)", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L94", + "source_location": "L102", "id": "superpowers_investidor10_wallet_spec_6_2_stocks_price_access_confirmed_extended_7_2", "community": 130, "norm_label": "6.2 stocks/price access \u2014 confirmed + extended (\u00a77.2)" @@ -7228,25 +7975,25 @@ "label": "6.3 Wiring / auth / tests \u2014 CONTESTED (\u00a77.3): mounting TRUE; gating + test seams missing", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L100", + "source_location": "L108", "id": "superpowers_investidor10_wallet_spec_6_3_wiring_auth_tests_contested_7_3_mounting_true_gating_test_seams_missing", "community": 130, "norm_label": "6.3 wiring / auth / tests \u2014 contested (\u00a77.3): mounting true; gating + test seams missing" }, { - "label": "6.4 Scraper pipeline (P2 dividends / has_b3) \u2014 CONTESTED (\u00a77.4): data present; source/staleness gaps", + "label": "6.4 Scraper pipeline (P2 dividends) \u2014 CONTESTED (\u00a77.4): data present; source/staleness gaps", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L106", - "id": "superpowers_investidor10_wallet_spec_6_4_scraper_pipeline_p2_dividends_has_b3_contested_7_4_data_present_source_staleness_gaps", + "source_location": "L115", + "id": "superpowers_investidor10_wallet_spec_6_4_scraper_pipeline_p2_dividends_contested_7_4_data_present_source_staleness_gaps", "community": 130, - "norm_label": "6.4 scraper pipeline (p2 dividends / has_b3) \u2014 contested (\u00a77.4): data present; source/staleness gaps" + "norm_label": "6.4 scraper pipeline (p2 dividends) \u2014 contested (\u00a77.4): data present; source/staleness gaps" }, { "label": "6.5 Ordered actions before P1 code", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L112", + "source_location": "L121", "id": "superpowers_investidor10_wallet_spec_6_5_ordered_actions_before_p1_code", "community": 130, "norm_label": "6.5 ordered actions before p1 code" @@ -7255,7 +8002,7 @@ "label": "7. Independent re-verification (swarm s4, 2026-09-29) \u2014 corrections to \u00a76", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L121", + "source_location": "L130", "id": "superpowers_investidor10_wallet_spec_7_independent_re_verification_swarm_s4_2026_09_29_corrections_to_6", "community": 130, "norm_label": "7. independent re-verification (swarm s4, 2026-09-29) \u2014 corrections to \u00a76" @@ -7264,7 +8011,7 @@ "label": "7.1 DB & migrations \u2014 \u00a76.1 CONTESTED: 3 actions, one destructive risk", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L125", + "source_location": "L134", "id": "superpowers_investidor10_wallet_spec_7_1_db_migrations_6_1_contested_3_actions_one_destructive_risk", "community": 130, "norm_label": "7.1 db & migrations \u2014 \u00a76.1 contested: 3 actions, one destructive risk" @@ -7273,7 +8020,7 @@ "label": "7.2 Stocks/price access \u2014 \u00a76.2 CONFIRMED, incomplete", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L133", + "source_location": "L142", "id": "superpowers_investidor10_wallet_spec_7_2_stocks_price_access_6_2_confirmed_incomplete", "community": 130, "norm_label": "7.2 stocks/price access \u2014 \u00a76.2 confirmed, incomplete" @@ -7282,7 +8029,7 @@ "label": "7.3 Wiring / auth / tests \u2014 \u00a76.3 CONTESTED (mounting TRUE)", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L143", + "source_location": "L154", "id": "superpowers_investidor10_wallet_spec_7_3_wiring_auth_tests_6_3_contested_mounting_true", "community": 130, "norm_label": "7.3 wiring / auth / tests \u2014 \u00a76.3 contested (mounting true)" @@ -7291,7 +8038,7 @@ "label": "7.4 Scraper pipeline \u2014 \u00a76.4 CONTESTED", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L150", + "source_location": "L164", "id": "superpowers_investidor10_wallet_spec_7_4_scraper_pipeline_6_4_contested", "community": 130, "norm_label": "7.4 scraper pipeline \u2014 \u00a76.4 contested" @@ -7300,7 +8047,7 @@ "label": "7.5 Revised pre-P1 actions (supersedes \u00a76.5)", "file_type": "document", "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L159", + "source_location": "L173", "id": "superpowers_investidor10_wallet_spec_7_5_revised_pre_p1_actions_supersedes_6_5", "community": 130, "norm_label": "7.5 revised pre-p1 actions (supersedes \u00a76.5)" @@ -7827,6 +8574,96 @@ "community": 579, "norm_label": "next actions (not in scope here)" }, + { + "label": "orunmila-harness-gaps.md", + "file_type": "document", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L1", + "id": "docs_superpowers_orunmila_harness_gaps_md", + "community": 606, + "norm_label": "orunmila-harness-gaps.md" + }, + { + "label": "Orunmila Harness-Loop Gap Analysis", + "file_type": "document", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L1", + "id": "superpowers_orunmila_harness_gaps_orunmila_harness_loop_gap_analysis", + "community": 606, + "norm_label": "orunmila harness-loop gap analysis" + }, + { + "label": "1. Orunmila's loop today", + "file_type": "document", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L5", + "id": "superpowers_orunmila_harness_gaps_1_orunmila_s_loop_today", + "community": 606, + "norm_label": "1. orunmila's loop today" + }, + { + "label": "2. Where Orunmila is already ahead \u2014 do not rebuild", + "file_type": "document", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L9", + "id": "superpowers_orunmila_harness_gaps_2_where_orunmila_is_already_ahead_do_not_rebuild", + "community": 606, + "norm_label": "2. where orunmila is already ahead \u2014 do not rebuild" + }, + { + "label": "3. The 12 modern patterns vs Orunmila", + "file_type": "document", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L16", + "id": "superpowers_orunmila_harness_gaps_3_the_12_modern_patterns_vs_orunmila", + "community": 606, + "norm_label": "3. the 12 modern patterns vs orunmila" + }, + { + "label": "4. P0 \u2014 reliability (do first, each one PR)", + "file_type": "document", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L33", + "id": "superpowers_orunmila_harness_gaps_4_p0_reliability_do_first_each_one_pr", + "community": 606, + "norm_label": "4. p0 \u2014 reliability (do first, each one pr)" + }, + { + "label": "5. P1 \u2014 context quality (biggest behavior delta per line)", + "file_type": "document", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L39", + "id": "superpowers_orunmila_harness_gaps_5_p1_context_quality_biggest_behavior_delta_per_line", + "community": 606, + "norm_label": "5. p1 \u2014 context quality (biggest behavior delta per line)" + }, + { + "label": "6. P2 \u2014 structural (larger, sequenced after P0/P1)", + "file_type": "document", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L47", + "id": "superpowers_orunmila_harness_gaps_6_p2_structural_larger_sequenced_after_p0_p1", + "community": 606, + "norm_label": "6. p2 \u2014 structural (larger, sequenced after p0/p1)" + }, + { + "label": "7. P3 / later \u2014 deliberate scope, not accidents", + "file_type": "document", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L54", + "id": "superpowers_orunmila_harness_gaps_7_p3_later_deliberate_scope_not_accidents", + "community": 606, + "norm_label": "7. p3 / later \u2014 deliberate scope, not accidents" + }, + { + "label": "8. Sources", + "file_type": "document", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L60", + "id": "superpowers_orunmila_harness_gaps_8_sources", + "community": 606, + "norm_label": "8. sources" + }, { "label": "uvicorn-worker-scaling-plan.md", "file_type": "document", @@ -7980,6 +8817,60 @@ "community": 495, "norm_label": "8. evidence index" }, + { + "label": "wallet-orchestrator-prompt.md", + "file_type": "document", + "source_file": "docs/superpowers/wallet-orchestrator-prompt.md", + "source_location": "L1", + "id": "docs_superpowers_wallet_orchestrator_prompt_md", + "community": 585, + "norm_label": "wallet-orchestrator-prompt.md" + }, + { + "label": "Wallet Orchestrator Prompt (P1 + P2 + P3+ \u2014 one goal per scope)", + "file_type": "document", + "source_file": "docs/superpowers/wallet-orchestrator-prompt.md", + "source_location": "L1", + "id": "superpowers_wallet_orchestrator_prompt_wallet_orchestrator_prompt_p1_p2_p3_one_goal_per_scope", + "community": 585, + "norm_label": "wallet orchestrator prompt (p1 + p2 + p3+ \u2014 one goal per scope)" + }, + { + "label": "The three goals (sequential \u2014 one at a time, never parallel)", + "file_type": "document", + "source_file": "docs/superpowers/wallet-orchestrator-prompt.md", + "source_location": "L10", + "id": "superpowers_wallet_orchestrator_prompt_the_three_goals_sequential_one_at_a_time_never_parallel", + "community": 585, + "norm_label": "the three goals (sequential \u2014 one at a time, never parallel)" + }, + { + "label": "Swarm protocol (all three goals)", + "file_type": "document", + "source_file": "docs/superpowers/wallet-orchestrator-prompt.md", + "source_location": "L30", + "id": "superpowers_wallet_orchestrator_prompt_swarm_protocol_all_three_goals", + "community": 585, + "norm_label": "swarm protocol (all three goals)" + }, + { + "label": "Standing rules (do not re-derive)", + "file_type": "document", + "source_file": "docs/superpowers/wallet-orchestrator-prompt.md", + "source_location": "L40", + "id": "superpowers_wallet_orchestrator_prompt_standing_rules_do_not_re_derive", + "community": 585, + "norm_label": "standing rules (do not re-derive)" + }, + { + "label": "Environment", + "file_type": "document", + "source_file": "docs/superpowers/wallet-orchestrator-prompt.md", + "source_location": "L78", + "id": "superpowers_wallet_orchestrator_prompt_environment", + "community": 585, + "norm_label": "environment" + }, { "label": "stocks-cache-ttl.md", "file_type": "document", @@ -9750,7 +10641,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L269", "id": "plans_2026_09_04_wallet_management_task_3_pure_derivation_math", - "community": 618, + "community": 632, "norm_label": "task 3: pure derivation math" }, { @@ -9759,7 +10650,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L281", "id": "plans_2026_09_04_wallet_management_codeblock_9", - "community": 618, + "community": 632, "norm_label": "code:python (from datetime import date)" }, { @@ -9768,7 +10659,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L325", "id": "plans_2026_09_04_wallet_management_codeblock_10", - "community": 618, + "community": 632, "norm_label": "code:python (from dataclasses import dataclass)" }, { @@ -9777,7 +10668,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L384", "id": "plans_2026_09_04_wallet_management_codeblock_11", - "community": 618, + "community": 632, "norm_label": "code:bash (git add main/app/wallet/__init__.py main/app/wallet/math.py )" }, { @@ -10675,7 +11566,7 @@ "label": "code:yaml (nginx:)", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L131", + "source_location": "L135", "id": "plans_2026_09_29_nginx_response_cache_codeblock_6", "community": 126, "norm_label": "code:yaml (nginx:)" @@ -10684,7 +11575,7 @@ "label": "code:yaml (volumes:)", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L152", + "source_location": "L156", "id": "plans_2026_09_29_nginx_response_cache_codeblock_7", "community": 126, "norm_label": "code:yaml (volumes:)" @@ -10693,7 +11584,7 @@ "label": "code:powershell (docker compose config -q)", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L164", + "source_location": "L168", "id": "plans_2026_09_29_nginx_response_cache_codeblock_8", "community": 126, "norm_label": "code:powershell (docker compose config -q)" @@ -10702,7 +11593,7 @@ "label": "code:bash (git add docker-compose.yml nginx/conf.d/00-http-common.conf )", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L176", + "source_location": "L180", "id": "plans_2026_09_29_nginx_response_cache_codeblock_9", "community": 126, "norm_label": "code:bash (git add docker-compose.yml nginx/conf.d/00-http-common.conf )" @@ -10711,7 +11602,7 @@ "label": "Task 2: Cached locations, shared proxy snippet, mirrored TTLs", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L183", + "source_location": "L187", "id": "plans_2026_09_29_nginx_response_cache_task_2_cached_locations_shared_proxy_snippet_mirrored_ttls", "community": 126, "norm_label": "task 2: cached locations, shared proxy snippet, mirrored ttls" @@ -10720,7 +11611,7 @@ "label": "code:powershell ($U = \"http://localhost/stocks/cotations?search=PETR4\")", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L195", + "source_location": "L199", "id": "plans_2026_09_29_nginx_response_cache_codeblock_10", "community": 126, "norm_label": "code:powershell ($u = \"http://localhost/stocks/cotations?search=petr4\")" @@ -10729,7 +11620,7 @@ "label": "code:nginx (proxy_pass http://stocks_api;)", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L206", + "source_location": "L210", "id": "plans_2026_09_29_nginx_response_cache_codeblock_11", "community": 126, "norm_label": "code:nginx (proxy_pass http://stocks_api;)" @@ -10738,7 +11629,7 @@ "label": "code:nginx (# Exact-match on purpose: a prefix match on /stocks/cotation)", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L246", + "source_location": "L249", "id": "plans_2026_09_29_nginx_response_cache_codeblock_12", "community": 126, "norm_label": "code:nginx (# exact-match on purpose: a prefix match on /stocks/cotation)" @@ -10747,7 +11638,7 @@ "label": "code:powershell (docker exec nginx nginx -t; if ($?) { docker exec nginx ngin)", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L282", + "source_location": "L283", "id": "plans_2026_09_29_nginx_response_cache_codeblock_13", "community": 126, "norm_label": "code:powershell (docker exec nginx nginx -t; if ($?) { docker exec nginx ngin)" @@ -10756,7 +11647,7 @@ "label": "code:bash (git add nginx/conf.d/20-stocks.conf nginx/snippets/stocks-pr)", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L295", + "source_location": "L296", "id": "plans_2026_09_29_nginx_response_cache_codeblock_14", "community": 126, "norm_label": "code:bash (git add nginx/conf.d/20-stocks.conf nginx/snippets/stocks-pr)" @@ -10765,7 +11656,7 @@ "label": "Task 3: Measure the GIL relief and record it", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L302", + "source_location": "L303", "id": "plans_2026_09_29_nginx_response_cache_task_3_measure_the_gil_relief_and_record_it", "community": 126, "norm_label": "task 3: measure the gil relief and record it" @@ -10774,52 +11665,43 @@ "label": "code:powershell (docker stats --no-stream --format \"{{.Name}},{{.CPUPerc}},{{)", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L314", + "source_location": "L315", "id": "plans_2026_09_29_nginx_response_cache_codeblock_15", "community": 126, "norm_label": "code:powershell (docker stats --no-stream --format \"{{.name}},{{.cpuperc}},{{)" }, { - "label": "code:powershell ($U = \"http://localhost/stocks/cotations?search=PETR4\")", + "label": "code:powershell ($env:PERF_API_KEY=\"sk-...\" # all three make targets below )", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L321", + "source_location": "L322", "id": "plans_2026_09_29_nginx_response_cache_codeblock_16", "community": 126, - "norm_label": "code:powershell ($u = \"http://localhost/stocks/cotations?search=petr4\")" + "norm_label": "code:powershell ($env:perf_api_key=\"sk-...\" # all three make targets below )" }, { - "label": "code:powershell ($D = \"http://localhost:3200/stocks/cotations?search=PETR4\")", + "label": "code:powershell (make perf-direct # same load at api:3200 (requires $env:P)", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L333", + "source_location": "L335", "id": "plans_2026_09_29_nginx_response_cache_codeblock_17", "community": 126, - "norm_label": "code:powershell ($d = \"http://localhost:3200/stocks/cotations?search=petr4\")" + "norm_label": "code:powershell (make perf-direct # same load at api:3200 (requires $env:p)" }, { "label": "code:markdown (# nginx response cache \u2014 GIL-relief measurement)", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L346", + "source_location": "L349", "id": "plans_2026_09_29_nginx_response_cache_codeblock_18", "community": 126, "norm_label": "code:markdown (# nginx response cache \u2014 gil-relief measurement)" }, - { - "label": "code:bash (.\\ci.ps1)", - "file_type": "document", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L367", - "id": "plans_2026_09_29_nginx_response_cache_codeblock_19", - "community": 126, - "norm_label": "code:bash (.\\ci.ps1)" - }, { "label": "Execution Handoff", "file_type": "document", "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L375", + "source_location": "L374", "id": "plans_2026_09_29_nginx_response_cache_execution_handoff", "community": 126, "norm_label": "execution handoff" @@ -11598,6 +12480,663 @@ "community": 86, "norm_label": "execution handoff" }, + { + "label": "2026-09-30-wallet-p1.md", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1", + "id": "docs_superpowers_plans_2026_09_30_wallet_p1_md", + "community": 573, + "norm_label": "2026-09-30-wallet-p1.md" + }, + { + "label": "Mansa Wallet Implementation Plan (P1 + P2 + P3+)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1", + "id": "plans_2026_09_30_wallet_p1_mansa_wallet_implementation_plan_p1_p2_p3", + "community": 573, + "norm_label": "mansa wallet implementation plan (p1 + p2 + p3+)" + }, + { + "label": "Global Constraints", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L13", + "id": "plans_2026_09_30_wallet_p1_global_constraints", + "community": 573, + "norm_label": "global constraints" + }, + { + "label": "Review Focus", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L29", + "id": "plans_2026_09_30_wallet_p1_review_focus", + "community": 530, + "norm_label": "review focus" + }, + { + "label": "Task 1: `Permission.WALLET` on the base role + ripple fixes", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L43", + "id": "plans_2026_09_30_wallet_p1_task_1_permission_wallet_on_the_base_role_ripple_fixes", + "community": 600, + "norm_label": "task 1: `permission.wallet` on the base role + ripple fixes" + }, + { + "label": "code:python (def test_permission_enum_values():)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L60", + "id": "plans_2026_09_30_wallet_p1_codeblock_1", + "community": 600, + "norm_label": "code:python (def test_permission_enum_values():)" + }, + { + "label": "code:python (class Permission(IntFlag):)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L93", + "id": "plans_2026_09_30_wallet_p1_codeblock_2", + "community": 600, + "norm_label": "code:python (class permission(intflag):)" + }, + { + "label": "code:markdown (| `USER` | `WALLET` \u2014 default on registration |)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L115", + "id": "plans_2026_09_30_wallet_p1_codeblock_3", + "community": 600, + "norm_label": "code:markdown (| `user` | `wallet` \u2014 default on registration |)" + }, + { + "label": "code:bash (git add main/utils/roles.py tests/test_roles.py docs/authent)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L124", + "id": "plans_2026_09_30_wallet_p1_codeblock_4", + "community": 600, + "norm_label": "code:bash (git add main/utils/roles.py tests/test_roles.py docs/authent)" + }, + { + "label": "Task 2: Wallet ORM models (5 tables, `user_db`)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L131", + "id": "plans_2026_09_30_wallet_p1_task_2_wallet_orm_models_5_tables_user_db", + "community": 611, + "norm_label": "task 2: wallet orm models (5 tables, `user_db`)" + }, + { + "label": "code:python (from main.models.base import Base)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L143", + "id": "plans_2026_09_30_wallet_p1_codeblock_5", + "community": 611, + "norm_label": "code:python (from main.models.base import base)" + }, + { + "label": "code:python (from sqlalchemy import Column, Date, Enum, ForeignKey, Integ)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L172", + "id": "plans_2026_09_30_wallet_p1_codeblock_6", + "community": 611, + "norm_label": "code:python (from sqlalchemy import column, date, enum, foreignkey, integ)" + }, + { + "label": "code:bash (git add main/models/wallet.py tests/test_wallet_models.py)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L258", + "id": "plans_2026_09_30_wallet_p1_codeblock_7", + "community": 611, + "norm_label": "code:bash (git add main/models/wallet.py tests/test_wallet_models.py)" + }, + { + "label": "Task 3: Alembic revision for the wallet tables (needs MySQL)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L265", + "id": "plans_2026_09_30_wallet_p1_task_3_alembic_revision_for_the_wallet_tables_needs_mysql", + "community": 530, + "norm_label": "task 3: alembic revision for the wallet tables (needs mysql)" + }, + { + "label": "code:python (import main.models.wallet # noqa: F401)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L282", + "id": "plans_2026_09_30_wallet_p1_codeblock_8", + "community": 530, + "norm_label": "code:python (import main.models.wallet # noqa: f401)" + }, + { + "label": "code:bash (git add migrations/env.py migrations/versions/_wallet_t)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L309", + "id": "plans_2026_09_30_wallet_p1_codeblock_9", + "community": 530, + "norm_label": "code:bash (git add migrations/env.py migrations/versions/_wallet_t)" + }, + { + "label": "Task 4: Wallet auth dependency (introspect contract + raw-token resolver)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L316", + "id": "plans_2026_09_30_wallet_p1_task_4_wallet_auth_dependency_introspect_contract_raw_token_resolver", + "community": 607, + "norm_label": "task 4: wallet auth dependency (introspect contract + raw-token resolver)" + }, + { + "label": "code:python (from fastapi import Depends, FastAPI)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L328", + "id": "plans_2026_09_30_wallet_p1_codeblock_10", + "community": 607, + "norm_label": "code:python (from fastapi import depends, fastapi)" + }, + { + "label": "code:python (import logging)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L395", + "id": "plans_2026_09_30_wallet_p1_codeblock_11", + "community": 607, + "norm_label": "code:python (import logging)" + }, + { + "label": "code:bash (git add main/app/wallet/auth.py tests/test_wallet_auth.py)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L445", + "id": "plans_2026_09_30_wallet_p1_codeblock_12", + "community": 607, + "norm_label": "code:bash (git add main/app/wallet/auth.py tests/test_wallet_auth.py)" + }, + { + "label": "Task 5: Wallets CRUD + mount + `make_wallet_client`", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L452", + "id": "plans_2026_09_30_wallet_p1_task_5_wallets_crud_mount_make_wallet_client", + "community": 578, + "norm_label": "task 5: wallets crud + mount + `make_wallet_client`" + }, + { + "label": "code:python (def make_wallet_client(mock_identity=None, db=None):)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L467", + "id": "plans_2026_09_30_wallet_p1_codeblock_13", + "community": 578, + "norm_label": "code:python (def make_wallet_client(mock_identity=none, db=none):)" + }, + { + "label": "code:python (import main.models.wallet # noqa: F401)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L491", + "id": "plans_2026_09_30_wallet_p1_codeblock_14", + "community": 578, + "norm_label": "code:python (import main.models.wallet # noqa: f401)" + }, + { + "label": "code:python (def test_list_wallets_returns_only_mine(dbSession):)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L515", + "id": "plans_2026_09_30_wallet_p1_codeblock_15", + "community": 578, + "norm_label": "code:python (def test_list_wallets_returns_only_mine(dbsession):)" + }, + { + "label": "code:python (from sqlalchemy.orm import Session)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L553", + "id": "plans_2026_09_30_wallet_p1_codeblock_16", + "community": 578, + "norm_label": "code:python (from sqlalchemy.orm import session)" + }, + { + "label": "code:python (from fastapi import APIRouter, Depends)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L573", + "id": "plans_2026_09_30_wallet_p1_codeblock_17", + "community": 578, + "norm_label": "code:python (from fastapi import apirouter, depends)" + }, + { + "label": "code:bash (git add main/controller/wallet_controller.py main/service/wa)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L620", + "id": "plans_2026_09_30_wallet_p1_codeblock_18", + "community": 578, + "norm_label": "code:bash (git add main/controller/wallet_controller.py main/service/wa)" + }, + { + "label": "Task 6: Entries ledger + holdings recalc (avg-price engine)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L627", + "id": "plans_2026_09_30_wallet_p1_task_6_entries_ledger_holdings_recalc_avg_price_engine", + "community": 530, + "norm_label": "task 6: entries ledger + holdings recalc (avg-price engine)" + }, + { + "label": "code:python (def test_compra_average_includes_costs(dbSession):)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L642", + "id": "plans_2026_09_30_wallet_p1_codeblock_19", + "community": 530, + "norm_label": "code:python (def test_compra_average_includes_costs(dbsession):)" + }, + { + "label": "code:python (from datetime import date)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L691", + "id": "plans_2026_09_30_wallet_p1_codeblock_20", + "community": 530, + "norm_label": "code:python (from datetime import date)" + }, + { + "label": "code:bash (git add main/service/wallet_service.py main/controller/walle)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L782", + "id": "plans_2026_09_30_wallet_p1_codeblock_21", + "community": 530, + "norm_label": "code:bash (git add main/service/wallet_service.py main/controller/walle)" + }, + { + "label": "Task 7: Positions \u2014 live-price join over HTTP", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L789", + "id": "plans_2026_09_30_wallet_p1_task_7_positions_live_price_join_over_http", + "community": 601, + "norm_label": "task 7: positions \u2014 live-price join over http" + }, + { + "label": "code:python (import requests)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L804", + "id": "plans_2026_09_30_wallet_p1_codeblock_22", + "community": 601, + "norm_label": "code:python (import requests)" + }, + { + "label": "code:python (import os)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L888", + "id": "plans_2026_09_30_wallet_p1_codeblock_23", + "community": 601, + "norm_label": "code:python (import os)" + }, + { + "label": "code:python (def fetchCachedClose(ticker: str) -> float | None:)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L926", + "id": "plans_2026_09_30_wallet_p1_codeblock_24", + "community": 601, + "norm_label": "code:python (def fetchcachedclose(ticker: str) -> float | none:)" + }, + { + "label": "code:bash (git add main/service/wallet_service.py main/controller/walle)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L957", + "id": "plans_2026_09_30_wallet_p1_codeblock_25", + "community": 601, + "norm_label": "code:bash (git add main/service/wallet_service.py main/controller/walle)" + }, + { + "label": "Task 8: Summary + snapshots + allocation + targets + ratings", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L964", + "id": "plans_2026_09_30_wallet_p1_task_8_summary_snapshots_allocation_targets_ratings", + "community": 612, + "norm_label": "task 8: summary + snapshots + allocation + targets + ratings" + }, + { + "label": "code:python (def test_summary_math_and_snapshot_upsert(dbSession, monkeyp)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L979", + "id": "plans_2026_09_30_wallet_p1_codeblock_26", + "community": 612, + "norm_label": "code:python (def test_summary_math_and_snapshot_upsert(dbsession, monkeyp)" + }, + { + "label": "code:bash (git add main/service/wallet_service.py main/controller/walle)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1022", + "id": "plans_2026_09_30_wallet_p1_codeblock_27", + "community": 612, + "norm_label": "code:bash (git add main/service/wallet_service.py main/controller/walle)" + }, + { + "label": "Task 9: Full gate \u2014 `.\\ci.ps1` green, coverage, fallout", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1029", + "id": "plans_2026_09_30_wallet_p1_task_9_full_gate_ci_ps1_green_coverage_fallout", + "community": 530, + "norm_label": "task 9: full gate \u2014 `.\\ci.ps1` green, coverage, fallout" + }, + { + "label": "code:bash (git add )", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1051", + "id": "plans_2026_09_30_wallet_p1_codeblock_28", + "community": 530, + "norm_label": "code:bash (git add )" + }, + { + "label": "Goal 2 \u2014 P2 earnings + performance (starts only after Goal 1 complete)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1060", + "id": "plans_2026_09_30_wallet_p1_goal_2_p2_earnings_performance_starts_only_after_goal_1_complete", + "community": 571, + "norm_label": "goal 2 \u2014 p2 earnings + performance (starts only after goal 1 complete)" + }, + { + "label": "Task P2-1: `Earning` model + second migration revision", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1064", + "id": "plans_2026_09_30_wallet_p1_task_p2_1_earning_model_second_migration_revision", + "community": 608, + "norm_label": "task p2-1: `earning` model + second migration revision" + }, + { + "label": "code:python (from main.models.wallet import Earning)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1080", + "id": "plans_2026_09_30_wallet_p1_codeblock_29", + "community": 608, + "norm_label": "code:python (from main.models.wallet import earning)" + }, + { + "label": "code:python (class Earning(Base):)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1108", + "id": "plans_2026_09_30_wallet_p1_codeblock_30", + "community": 608, + "norm_label": "code:python (class earning(base):)" + }, + { + "label": "code:bash (git add main/models/wallet.py migrations/versions/_wall)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1139", + "id": "plans_2026_09_30_wallet_p1_codeblock_31", + "community": 608, + "norm_label": "code:bash (git add main/models/wallet.py migrations/versions/_wall)" + }, + { + "label": "Task P2-2: Earnings sync (accrue + transition, pull-based)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1146", + "id": "plans_2026_09_30_wallet_p1_task_p2_2_earnings_sync_accrue_transition_pull_based", + "community": 571, + "norm_label": "task p2-2: earnings sync (accrue + transition, pull-based)" + }, + { + "label": "code:python (TIPO_MAP = {\"Dividendo\": \"Div\", \"JCP\": \"JSCP\", \"Juros Sobre )", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1159", + "id": "plans_2026_09_30_wallet_p1_codeblock_32", + "community": 571, + "norm_label": "code:python (tipo_map = {\"dividendo\": \"div\", \"jcp\": \"jscp\", \"juros sobre )" + }, + { + "label": "code:python (from freezegun import freeze_time)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1167", + "id": "plans_2026_09_30_wallet_p1_codeblock_33", + "community": 571, + "norm_label": "code:python (from freezegun import freeze_time)" + }, + { + "label": "code:bash (git add main/service/wallet_service.py main/controller/walle)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1229", + "id": "plans_2026_09_30_wallet_p1_codeblock_34", + "community": 571, + "norm_label": "code:bash (git add main/service/wallet_service.py main/controller/walle)" + }, + { + "label": "Task P2-3: Performance windows (on-demand reconstruction, no new table)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1236", + "id": "plans_2026_09_30_wallet_p1_task_p2_3_performance_windows_on_demand_reconstruction_no_new_table", + "community": 571, + "norm_label": "task p2-3: performance windows (on-demand reconstruction, no new table)" + }, + { + "label": "code:python (def _flat_series_with_one_div(url, params=None, headers=None)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1251", + "id": "plans_2026_09_30_wallet_p1_codeblock_35", + "community": 571, + "norm_label": "code:python (def _flat_series_with_one_div(url, params=none, headers=none)" + }, + { + "label": "code:bash (git add main/service/wallet_service.py main/controller/walle)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1297", + "id": "plans_2026_09_30_wallet_p1_codeblock_36", + "community": 571, + "norm_label": "code:bash (git add main/service/wallet_service.py main/controller/walle)" + }, + { + "label": "Goal 3 \u2014 P3+ assist + narration (starts only after Goal 2 complete)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1304", + "id": "plans_2026_09_30_wallet_p1_goal_3_p3_assist_narration_starts_only_after_goal_2_complete", + "community": 573, + "norm_label": "goal 3 \u2014 p3+ assist + narration (starts only after goal 2 complete)" + }, + { + "label": "Task P3-0: Write the P3+ detailed plan (required before P3-1/P3-2)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1308", + "id": "plans_2026_09_30_wallet_p1_task_p3_0_write_the_p3_detailed_plan_required_before_p3_1_p3_2", + "community": 573, + "norm_label": "task p3-0: write the p3+ detailed plan (required before p3-1/p3-2)" + }, + { + "label": "Task P3-1: Ratings-assist tuning (gated on the P3+ plan)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1312", + "id": "plans_2026_09_30_wallet_p1_task_p3_1_ratings_assist_tuning_gated_on_the_p3_plan", + "community": 573, + "norm_label": "task p3-1: ratings-assist tuning (gated on the p3+ plan)" + }, + { + "label": "Task P3-2: Orunmila narration tools (gated on the P3+ plan)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1316", + "id": "plans_2026_09_30_wallet_p1_task_p3_2_orunmila_narration_tools_gated_on_the_p3_plan", + "community": 573, + "norm_label": "task p3-2: orunmila narration tools (gated on the p3+ plan)" + }, + { + "label": "2026-10-01-wallet-p3.md", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L1", + "id": "docs_superpowers_plans_2026_10_01_wallet_p3_md", + "community": 104, + "norm_label": "2026-10-01-wallet-p3.md" + }, + { + "label": "Mansa Wallet P3+ Detailed Plan (assist + narration)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L1", + "id": "plans_2026_10_01_wallet_p3_mansa_wallet_p3_detailed_plan_assist_narration", + "community": 104, + "norm_label": "mansa wallet p3+ detailed plan (assist + narration)" + }, + { + "label": "Global Constraints", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L13", + "id": "plans_2026_10_01_wallet_p3_global_constraints", + "community": 104, + "norm_label": "global constraints" + }, + { + "label": "Review Focus", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L31", + "id": "plans_2026_10_01_wallet_p3_review_focus", + "community": 104, + "norm_label": "review focus" + }, + { + "label": "Task P3-1: Ratings-assist tuning \u2014 XANGO-informed `buy_flag` (gated on this plan)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L45", + "id": "plans_2026_10_01_wallet_p3_task_p3_1_ratings_assist_tuning_xango_informed_buy_flag_gated_on_this_plan", + "community": 104, + "norm_label": "task p3-1: ratings-assist tuning \u2014 xango-informed `buy_flag` (gated on this plan)" + }, + { + "label": "code:python (buyFlag = ()", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L58", + "id": "plans_2026_10_01_wallet_p3_codeblock_1", + "community": 104, + "norm_label": "code:python (buyflag = ()" + }, + { + "label": "code:python (XANGO_WEIGHTS = {\"underweight\": 0.45, \"rating\": 0.25, \"xango)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L68", + "id": "plans_2026_10_01_wallet_p3_codeblock_2", + "community": 104, + "norm_label": "code:python (xango_weights = {\"underweight\": 0.45, \"rating\": 0.25, \"xango)" + }, + { + "label": "code:python (import hashlib)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L83", + "id": "plans_2026_10_01_wallet_p3_codeblock_3", + "community": 104, + "norm_label": "code:python (import hashlib)" + }, + { + "label": "code:bash (git add main/app/wallet/wallet_service.py tests/test_wallet_)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L178", + "id": "plans_2026_10_01_wallet_p3_codeblock_4", + "community": 104, + "norm_label": "code:bash (git add main/app/wallet/wallet_service.py tests/test_wallet_)" + }, + { + "label": "Task P3-2: Orunmila narration tools \u2014 `narrate-positions` first (gated on this plan)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L185", + "id": "plans_2026_10_01_wallet_p3_task_p3_2_orunmila_narration_tools_narrate_positions_first_gated_on_this_plan", + "community": 104, + "norm_label": "task p3-2: orunmila narration tools \u2014 `narrate-positions` first (gated on this plan)" + }, + { + "label": "code:python (async def narrate_positions(wallet_id: int, **_) -> dict:)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L198", + "id": "plans_2026_10_01_wallet_p3_codeblock_5", + "community": 104, + "norm_label": "code:python (async def narrate_positions(wallet_id: int, **_) -> dict:)" + }, + { + "label": "code:python (import asyncio)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L227", + "id": "plans_2026_10_01_wallet_p3_codeblock_6", + "community": 104, + "norm_label": "code:python (import asyncio)" + }, + { + "label": "code:bash (git add main/app/orunmila/tools.py tests/test_orunmila_walle)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L300", + "id": "plans_2026_10_01_wallet_p3_codeblock_7", + "community": 104, + "norm_label": "code:bash (git add main/app/orunmila/tools.py tests/test_orunmila_walle)" + }, + { + "label": "Out of scope for P3 (unchanged from spec \u00a74 / Goal 3)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L307", + "id": "plans_2026_10_01_wallet_p3_out_of_scope_for_p3_unchanged_from_spec_4_goal_3", + "community": 104, + "norm_label": "out of scope for p3 (unchanged from spec \u00a74 / goal 3)" + }, + { + "label": "Standing rules carried over", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L311", + "id": "plans_2026_10_01_wallet_p3_standing_rules_carried_over", + "community": 104, + "norm_label": "standing rules carried over" + }, + { + "label": "Finding-(9) charter-gap note", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L315", + "id": "plans_2026_10_01_wallet_p3_finding_9_charter_gap_note", + "community": 104, + "norm_label": "finding-(9) charter-gap note" + }, { "label": "2026-09-04-wallet-design.md", "file_type": "document", @@ -11958,6 +13497,771 @@ "community": 208, "norm_label": "10. plans and follow-ups" }, + { + "label": "scoreBuyFlag()", + "file_type": "code", + "source_file": "main/app/wallet/positions.py", + "source_location": "L52", + "community": 482, + "norm_label": "scorebuyflag()", + "id": "wallet_positions_scorebuyflag" + }, + { + "label": "XANGO quality score per ticker (0-100 scale). One fundamental read per tick", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L21", + "community": 482, + "norm_label": "xango quality score per ticker (0-100 scale). one fundamental read per tick", + "id": "wallet_positions_rationale_21" + }, + { + "label": "XANGO-informed buy flag (pure function, deterministic, no learned params).", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L59", + "community": 482, + "norm_label": "xango-informed buy flag (pure function, deterministic, no learned params).", + "id": "wallet_positions_rationale_59" + }, + { + "label": "XANGO-informed buy flag (pure function, deterministic, no learned params).", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L36", + "community": 482, + "norm_label": "xango-informed buy flag (pure function, deterministic, no learned params).", + "id": "wallet_positions_rationale_36" + }, + { + "label": "auth.py", + "file_type": "code", + "source_file": "main/app/wallet/auth.py", + "source_location": "L1", + "community": 629, + "norm_label": "auth.py", + "id": "main_app_wallet_auth_py" + }, + { + "label": "resolveRawToken()", + "file_type": "code", + "source_file": "main/app/wallet/auth.py", + "source_location": "L13", + "community": 629, + "norm_label": "resolverawtoken()", + "id": "wallet_auth_resolverawtoken" + }, + { + "label": "getWalletIdentity()", + "file_type": "code", + "source_file": "main/app/wallet/auth.py", + "source_location": "L26", + "community": 629, + "norm_label": "getwalletidentity()", + "id": "wallet_auth_getwalletidentity" + }, + { + "label": "requireWalletUser()", + "file_type": "code", + "source_file": "main/app/wallet/auth.py", + "source_location": "L30", + "community": 629, + "norm_label": "requirewalletuser()", + "id": "wallet_auth_requirewalletuser" + }, + { + "label": "requireWalletOwnership()", + "file_type": "code", + "source_file": "main/app/wallet/auth.py", + "source_location": "L36", + "community": 629, + "norm_label": "requirewalletownership()", + "id": "wallet_auth_requirewalletownership" + }, + { + "label": "stocksApiBase()", + "file_type": "code", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L16", + "community": 152, + "norm_label": "stocksapibase()", + "id": "wallet_market_data_stocksapibase" + }, + { + "label": "stocksApiHeaders()", + "file_type": "code", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L20", + "community": 152, + "norm_label": "stocksapiheaders()", + "id": "wallet_market_data_stocksapiheaders" + }, + { + "label": "getOwnedWallet()", + "file_type": "code", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L11", + "community": 152, + "norm_label": "getownedwallet()", + "id": "wallet_wallets_getownedwallet" + }, + { + "label": "wallet_service.py", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L1", + "community": 68, + "norm_label": "wallet_service.py", + "id": "main_app_wallet_wallet_service_py" + }, + { + "label": "fetchXangoScores()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L36", + "community": 68, + "norm_label": "fetchxangoscores()", + "id": "wallet_wallet_service_fetchxangoscores" + }, + { + "label": "scoreBuyFlag()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L48", + "community": 68, + "norm_label": "scorebuyflag()", + "id": "wallet_wallet_service_scorebuyflag" + }, + { + "label": "createWallet()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L98", + "community": 68, + "norm_label": "createwallet()", + "id": "wallet_wallet_service_createwallet" + }, + { + "label": "listWallets()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L106", + "community": 68, + "norm_label": "listwallets()", + "id": "wallet_wallet_service_listwallets" + }, + { + "label": "EntryCreate", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L110", + "community": 564, + "norm_label": "entrycreate", + "id": "wallet_wallet_service_entrycreate" + }, + { + "label": "EntryUpdate", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L121", + "community": 564, + "norm_label": "entryupdate", + "id": "wallet_wallet_service_entryupdate" + }, + { + "label": "getOwnedWallet()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L128", + "community": 68, + "norm_label": "getownedwallet()", + "id": "wallet_wallet_service_getownedwallet" + }, + { + "label": "applyEntries()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L138", + "community": 68, + "norm_label": "applyentries()", + "id": "wallet_wallet_service_applyentries" + }, + { + "label": "recalcHolding()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L154", + "community": 68, + "norm_label": "recalcholding()", + "id": "wallet_wallet_service_recalcholding" + }, + { + "label": "addEntry()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L178", + "community": 68, + "norm_label": "addentry()", + "id": "wallet_wallet_service_addentry" + }, + { + "label": "listEntries()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L204", + "community": 68, + "norm_label": "listentries()", + "id": "wallet_wallet_service_listentries" + }, + { + "label": "updateEntry()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L216", + "community": 68, + "norm_label": "updateentry()", + "id": "wallet_wallet_service_updateentry" + }, + { + "label": "deleteEntry()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L238", + "community": 68, + "norm_label": "deleteentry()", + "id": "wallet_wallet_service_deleteentry" + }, + { + "label": "stocksApiBase()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L259", + "community": 68, + "norm_label": "stocksapibase()", + "id": "wallet_wallet_service_stocksapibase" + }, + { + "label": "stocksApiHeaders()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L263", + "community": 68, + "norm_label": "stocksapiheaders()", + "id": "wallet_wallet_service_stocksapiheaders" + }, + { + "label": "fetchLivePrices()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L268", + "community": 68, + "norm_label": "fetchliveprices()", + "id": "wallet_wallet_service_fetchliveprices" + }, + { + "label": "fetchCachedClose()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L293", + "community": 68, + "norm_label": "fetchcachedclose()", + "id": "wallet_wallet_service_fetchcachedclose" + }, + { + "label": "getPositions()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L313", + "community": 68, + "norm_label": "getpositions()", + "id": "wallet_wallet_service_getpositions" + }, + { + "label": "TargetUpsert", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L377", + "community": 564, + "norm_label": "targetupsert", + "id": "wallet_wallet_service_targetupsert" + }, + { + "label": "RatingUpsert", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L384", + "community": 564, + "norm_label": "ratingupsert", + "id": "wallet_wallet_service_ratingupsert" + }, + { + "label": "getSummary()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L390", + "community": 68, + "norm_label": "getsummary()", + "id": "wallet_wallet_service_getsummary" + }, + { + "label": "getAllocation()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L441", + "community": 68, + "norm_label": "getallocation()", + "id": "wallet_wallet_service_getallocation" + }, + { + "label": "upsertTarget()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L467", + "community": 68, + "norm_label": "upserttarget()", + "id": "wallet_wallet_service_upserttarget" + }, + { + "label": "set_rating()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L493", + "community": 68, + "norm_label": "set_rating()", + "id": "wallet_wallet_service_set_rating" + }, + { + "label": "positionAtDate()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L504", + "community": 68, + "norm_label": "positionatdate()", + "id": "wallet_wallet_service_positionatdate" + }, + { + "label": "fetchMarketDividends()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L511", + "community": 68, + "norm_label": "fetchmarketdividends()", + "id": "wallet_wallet_service_fetchmarketdividends" + }, + { + "label": "syncEarnings()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L529", + "community": 68, + "norm_label": "syncearnings()", + "id": "wallet_wallet_service_syncearnings" + }, + { + "label": "listEarnings()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L596", + "community": 68, + "norm_label": "listearnings()", + "id": "wallet_wallet_service_listearnings" + }, + { + "label": "fetchPadraoCloses()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L607", + "community": 68, + "norm_label": "fetchpadraocloses()", + "id": "wallet_wallet_service_fetchpadraocloses" + }, + { + "label": "cachedPerformance()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L630", + "community": 68, + "norm_label": "cachedperformance()", + "id": "wallet_wallet_service_cachedperformance" + }, + { + "label": "getPerformance()", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L733", + "community": 68, + "norm_label": "getperformance()", + "id": "wallet_wallet_service_getperformance" + }, + { + "label": "XANGO quality score per ticker (0-100 scale). Stub: no HTTP score endpoin", + "file_type": "rationale", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L37", + "community": 68, + "norm_label": "xango quality score per ticker (0-100 scale). stub: no http score endpoin", + "id": "wallet_wallet_service_rationale_37" + }, + { + "label": "XANGO-informed buy flag (pure function, deterministic, no learned params).", + "file_type": "rationale", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L55", + "community": 68, + "norm_label": "xango-informed buy flag (pure function, deterministic, no learned params).", + "id": "wallet_wallet_service_rationale_55" + }, + { + "label": "Search user's saved memories, preferences, and past analysis context. Use", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L21", + "community": 67, + "norm_label": "search user's saved memories, preferences, and past analysis context. use", + "id": "orunmila_tools_rationale_21" + }, + { + "label": "Store a memory about the user's preferences, analysis results, or feedback.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L52", + "community": 137, + "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", + "id": "orunmila_tools_rationale_52" + }, + { + "label": "Execute Python code in an isolated sandbox. Use for quantitative analysis,", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L94", + "community": 67, + "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", + "id": "orunmila_tools_rationale_94" + }, + { + "label": "Read a file from the workspace. Args: path: Path to the file (e.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L115", + "community": 67, + "norm_label": "read a file from the workspace. args: path: path to the file (e.", + "id": "orunmila_tools_rationale_115" + }, + { + "label": "Write a file to the workspace. Use this to save data files (CSV, JSON, scri", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L129", + "community": 67, + "norm_label": "write a file to the workspace. use this to save data files (csv, json, scri", + "id": "orunmila_tools_rationale_129" + }, + { + "label": "List files in the workspace directory. Args: path: Directory pat", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L145", + "community": 67, + "norm_label": "list files in the workspace directory. args: path: directory pat", + "id": "orunmila_tools_rationale_145" + }, + { + "label": "Get a download link for a workspace file to share with the user. Use this", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L158", + "community": 234, + "norm_label": "get a download link for a workspace file to share with the user. use this", + "id": "orunmila_tools_rationale_158" + }, + { + "label": "create_wallet()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L32", + "community": 54, + "norm_label": "create_wallet()", + "id": "service_wallet_service_create_wallet" + }, + { + "label": "list_wallets()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L40", + "community": 54, + "norm_label": "list_wallets()", + "id": "service_wallet_service_list_wallets" + }, + { + "label": "EntryCreate", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L44", + "community": 564, + "norm_label": "entrycreate", + "id": "service_wallet_service_entrycreate" + }, + { + "label": "EntryUpdate", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L55", + "community": 564, + "norm_label": "entryupdate", + "id": "service_wallet_service_entryupdate" + }, + { + "label": "_get_owned_wallet()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L62", + "community": 54, + "norm_label": "_get_owned_wallet()", + "id": "service_wallet_service_get_owned_wallet" + }, + { + "label": "_apply_entries()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L72", + "community": 54, + "norm_label": "_apply_entries()", + "id": "service_wallet_service_apply_entries" + }, + { + "label": "recalc_holding()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L88", + "community": 54, + "norm_label": "recalc_holding()", + "id": "service_wallet_service_recalc_holding" + }, + { + "label": "add_entry()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L112", + "community": 54, + "norm_label": "add_entry()", + "id": "service_wallet_service_add_entry" + }, + { + "label": "list_entries()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L138", + "community": 54, + "norm_label": "list_entries()", + "id": "service_wallet_service_list_entries" + }, + { + "label": "update_entry()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L150", + "community": 54, + "norm_label": "update_entry()", + "id": "service_wallet_service_update_entry" + }, + { + "label": "delete_entry()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L172", + "community": 54, + "norm_label": "delete_entry()", + "id": "service_wallet_service_delete_entry" + }, + { + "label": "stocksApiBase()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L193", + "community": 54, + "norm_label": "stocksapibase()", + "id": "service_wallet_service_stocksapibase" + }, + { + "label": "stocksApiHeaders()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L197", + "community": 54, + "norm_label": "stocksapiheaders()", + "id": "service_wallet_service_stocksapiheaders" + }, + { + "label": "fetchLivePrices()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L202", + "community": 54, + "norm_label": "fetchliveprices()", + "id": "service_wallet_service_fetchliveprices" + }, + { + "label": "fetchCachedClose()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L227", + "community": 54, + "norm_label": "fetchcachedclose()", + "id": "service_wallet_service_fetchcachedclose" + }, + { + "label": "get_positions()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L247", + "community": 54, + "norm_label": "get_positions()", + "id": "service_wallet_service_get_positions" + }, + { + "label": "TargetUpsert", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L306", + "community": 564, + "norm_label": "targetupsert", + "id": "service_wallet_service_targetupsert" + }, + { + "label": "RatingUpsert", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L313", + "community": 564, + "norm_label": "ratingupsert", + "id": "service_wallet_service_ratingupsert" + }, + { + "label": "get_summary()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L319", + "community": 54, + "norm_label": "get_summary()", + "id": "service_wallet_service_get_summary" + }, + { + "label": "get_allocation()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L370", + "community": 54, + "norm_label": "get_allocation()", + "id": "service_wallet_service_get_allocation" + }, + { + "label": "upsert_target()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L396", + "community": 54, + "norm_label": "upsert_target()", + "id": "service_wallet_service_upsert_target" + }, + { + "label": "set_rating()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L422", + "community": 54, + "norm_label": "set_rating()", + "id": "service_wallet_service_set_rating" + }, + { + "label": "position_at_date()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L433", + "community": 54, + "norm_label": "position_at_date()", + "id": "service_wallet_service_position_at_date" + }, + { + "label": "fetchMarketDividends()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L440", + "community": 54, + "norm_label": "fetchmarketdividends()", + "id": "service_wallet_service_fetchmarketdividends" + }, + { + "label": "sync_earnings()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L458", + "community": 54, + "norm_label": "sync_earnings()", + "id": "service_wallet_service_sync_earnings" + }, + { + "label": "list_earnings()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L525", + "community": 54, + "norm_label": "list_earnings()", + "id": "service_wallet_service_list_earnings" + }, + { + "label": "fetchPadraoCloses()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L536", + "community": 54, + "norm_label": "fetchpadraocloses()", + "id": "service_wallet_service_fetchpadraocloses" + }, + { + "label": "_cachedPerformance()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L559", + "community": 54, + "norm_label": "_cachedperformance()", + "id": "service_wallet_service_cachedperformance" + }, + { + "label": "get_performance()", + "file_type": "code", + "source_file": "main/service/wallet_service.py", + "source_location": "L662", + "community": 54, + "norm_label": "get_performance()", + "id": "service_wallet_service_get_performance" + }, + { + "label": "3. API contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` \u2192 `main/service/wallet_service.py::` \u2192 `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout)", + "file_type": "document", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L49", + "community": 130, + "norm_label": "3. api contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` \u2192 `main/service/wallet_service.py::` \u2192 `main/models/wallet.py::`; auth `depends(usermanager.getcurrentuser)` + `depends(getsession)` throughout)", + "id": "superpowers_investidor10_wallet_spec_3_api_contracts_all_under_wallet_chain_main_controller_wallet_controller_py_main_service_wallet_service_py_fn_main_models_wallet_py_model_auth_depends_usermanager_getcurrentuser_depends_getsession_throughout" + }, + { + "label": "6.4 Scraper pipeline (P2 dividends / has_b3) \u2014 CONTESTED (\u00a77.4): data present; source/staleness gaps", + "file_type": "document", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L106", + "community": 130, + "norm_label": "6.4 scraper pipeline (p2 dividends / has_b3) \u2014 contested (\u00a77.4): data present; source/staleness gaps", + "id": "superpowers_investidor10_wallet_spec_6_4_scraper_pipeline_p2_dividends_has_b3_contested_7_4_data_present_source_staleness_gaps" + }, + { + "label": "code:bash (.\\ci.ps1)", + "file_type": "document", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L367", + "community": 126, + "norm_label": "code:bash (.\\ci.ps1)", + "id": "plans_2026_09_29_nginx_response_cache_codeblock_19" + }, { "label": "Drop every cached endpoint body \u2014 called when the feather frame is replaced.", "file_type": "rationale", @@ -11972,7 +14276,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/build.py", "source_location": "L50", - "community": 82, + "community": 497, "norm_label": "_runtimeconf()", "id": "stocks_api_build_runtimeconf" }, @@ -11981,7 +14285,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/build.py", "source_location": "L1", - "community": 82, + "community": 497, "norm_label": "feather build / read helpers for the stocks cache. owns the on-disk layout (cac", "id": "stocks_api_build_rationale_1" }, @@ -11990,7 +14294,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/build.py", "source_location": "L51", - "community": 82, + "community": 497, "norm_label": "return (engine, featherpath, nestedpath), preferring live values on the cach", "id": "stocks_api_build_rationale_51" }, @@ -11999,7 +14303,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/compress.py", "source_location": "L31", - "community": 194, + "community": 251, "norm_label": "abbreviation map for a frame (dependency-injected; no cache import). result", "id": "stocks_api_compress_rationale_31" }, @@ -12008,7 +14312,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/compress.py", "source_location": "L51", - "community": 194, + "community": 251, "norm_label": "nested-field map for a frame plus its nested sample (same memo policy).", "id": "stocks_api_compress_rationale_51" }, @@ -12017,7 +14321,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/frame.py", "source_location": "L1", - "community": 82, + "community": 497, "norm_label": "pure dataframe helpers for the stocks feather cache (no i/o, no imports from sib", "id": "stocks_api_frame_rationale_1" }, @@ -12026,7 +14330,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/build.py", "source_location": "L47", - "community": 82, + "community": 497, "norm_label": "return (engine, featherpath, nestedpath), preferring live values on the cach", "id": "stocks_api_build_rationale_47" }, @@ -12134,7 +14438,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L47", - "community": 222, + "community": 194, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_47" }, @@ -12179,7 +14483,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L39", - "community": 222, + "community": 194, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_39" }, @@ -13430,7 +15734,7 @@ "file_type": "code", "source_file": "main/utils/roles.py", "source_location": "L63", - "community": 131, + "community": 584, "norm_label": "_servicetoken()", "id": "utils_roles_servicetoken" }, @@ -13439,7 +15743,7 @@ "file_type": "code", "source_file": "main/utils/roles.py", "source_location": "L69", - "community": 131, + "community": 584, "norm_label": "_introspecturl()", "id": "utils_roles_introspecturl" }, @@ -13448,7 +15752,7 @@ "file_type": "code", "source_file": "main/utils/roles.py", "source_location": "L75", - "community": 131, + "community": 584, "norm_label": "_extractcredential()", "id": "utils_roles_extractcredential" }, @@ -13457,7 +15761,7 @@ "file_type": "code", "source_file": "main/utils/roles.py", "source_location": "L92", - "community": 131, + "community": 584, "norm_label": "introspectuser()", "id": "utils_roles_introspectuser" }, @@ -13466,7 +15770,7 @@ "file_type": "code", "source_file": "config.py", "source_location": "L59", - "community": 586, + "community": 102, "norm_label": "prometheussettings", "id": "server_config_prometheussettings" }, @@ -13646,7 +15950,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L35", - "community": 53, + "community": 222, "norm_label": "gettokenizer()", "id": "prometheus_compact_gettokenizer" }, @@ -13655,7 +15959,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L47", - "community": 53, + "community": 222, "norm_label": "counttokens()", "id": "prometheus_compact_counttokens" }, @@ -13772,7 +16076,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L195", - "community": 80, + "community": 589, "norm_label": "prometheuscompactor", "id": "prometheus_compact_prometheuscompactor" }, @@ -13781,7 +16085,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L196", - "community": 80, + "community": 589, "norm_label": ".shouldcompact()", "id": "prometheus_compact_prometheuscompactor_shouldcompact" }, @@ -13790,7 +16094,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L213", - "community": 80, + "community": 589, "norm_label": ".getcompactablechunk()", "id": "prometheus_compact_prometheuscompactor_getcompactablechunk" }, @@ -13808,7 +16112,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L244", - "community": 80, + "community": 589, "norm_label": ".consolidate()", "id": "prometheus_compact_prometheuscompactor_consolidate" }, @@ -13817,7 +16121,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L271", - "community": 80, + "community": 589, "norm_label": ".compact()", "id": "prometheus_compact_prometheuscompactor_compact" }, @@ -13826,7 +16130,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L310", - "community": 80, + "community": 589, "norm_label": ".getepisodes()", "id": "prometheus_compact_prometheuscompactor_getepisodes" }, @@ -13835,7 +16139,7 @@ "file_type": "code", "source_file": "main/app/prometheus/mcp.py", "source_location": "L1", - "community": 590, + "community": 105, "norm_label": "mcp.py", "id": "main_app_prometheus_mcp_py" }, @@ -13844,7 +16148,7 @@ "file_type": "code", "source_file": "main/app/prometheus/mcp.py", "source_location": "L21", - "community": 590, + "community": 105, "norm_label": "buildclient()", "id": "prometheus_mcp_buildclient" }, @@ -13853,7 +16157,7 @@ "file_type": "code", "source_file": "main/app/prometheus/mcp.py", "source_location": "L29", - "community": 590, + "community": 105, "norm_label": "connect()", "id": "prometheus_mcp_connect" }, @@ -13862,7 +16166,7 @@ "file_type": "code", "source_file": "main/app/prometheus/mcp.py", "source_location": "L36", - "community": 590, + "community": 105, "norm_label": "mcpclientpool", "id": "prometheus_mcp_mcpclientpool" }, @@ -13871,7 +16175,7 @@ "file_type": "code", "source_file": "main/app/prometheus/mcp.py", "source_location": "L37", - "community": 590, + "community": 105, "norm_label": ".__init__()", "id": "prometheus_mcp_mcpclientpool_init" }, @@ -13880,7 +16184,7 @@ "file_type": "code", "source_file": "main/app/prometheus/mcp.py", "source_location": "L42", - "community": 590, + "community": 105, "norm_label": ".initialize()", "id": "prometheus_mcp_mcpclientpool_initialize" }, @@ -13889,7 +16193,7 @@ "file_type": "code", "source_file": "main/app/prometheus/mcp.py", "source_location": "L56", - "community": 590, + "community": 105, "norm_label": ".getclients()", "id": "prometheus_mcp_mcpclientpool_getclients" }, @@ -13898,7 +16202,7 @@ "file_type": "code", "source_file": "main/app/prometheus/mcp.py", "source_location": "L63", - "community": 590, + "community": 105, "norm_label": ".healthcheck()", "id": "prometheus_mcp_mcpclientpool_healthcheck" }, @@ -13907,7 +16211,7 @@ "file_type": "code", "source_file": "main/app/prometheus/mcp.py", "source_location": "L75", - "community": 590, + "community": 105, "norm_label": ".reconnect()", "id": "prometheus_mcp_mcpclientpool_reconnect" }, @@ -13916,7 +16220,7 @@ "file_type": "code", "source_file": "main/app/prometheus/mcp.py", "source_location": "L90", - "community": 590, + "community": 105, "norm_label": ".close()", "id": "prometheus_mcp_mcpclientpool_close" }, @@ -13934,7 +16238,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L35", - "community": 621, + "community": 53, "norm_label": "getmatrix()", "id": "prometheus_memory_getmatrix" }, @@ -13961,7 +16265,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L64", - "community": 45, + "community": 564, "norm_label": "memorycandidate", "id": "prometheus_memory_memorycandidate" }, @@ -13979,7 +16283,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L97", - "community": 53, + "community": 222, "norm_label": "getclient()", "id": "prometheus_memory_getclient" }, @@ -13988,7 +16292,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L104", - "community": 104, + "community": 53, "norm_label": "minmax()", "id": "prometheus_memory_minmax" }, @@ -13997,7 +16301,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L113", - "community": 63, + "community": 222, "norm_label": "normalizekey()", "id": "prometheus_memory_normalizekey" }, @@ -14006,7 +16310,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L120", - "community": 53, + "community": 222, "norm_label": "findsimilarkey()", "id": "prometheus_memory_findsimilarkey" }, @@ -14015,7 +16319,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L140", - "community": 104, + "community": 53, "norm_label": "scorerow()", "id": "prometheus_memory_scorerow" }, @@ -14024,7 +16328,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L152", - "community": 104, + "community": 53, "norm_label": "scorerecency()", "id": "prometheus_memory_scorerecency" }, @@ -14033,7 +16337,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L162", - "community": 104, + "community": 53, "norm_label": "scorecandidates()", "id": "prometheus_memory_scorecandidates" }, @@ -14042,7 +16346,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L179", - "community": 53, + "community": 222, "norm_label": "sumtokens()", "id": "prometheus_memory_sumtokens" }, @@ -14060,7 +16364,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L196", - "community": 53, + "community": 222, "norm_label": "getmemorylimit()", "id": "prometheus_memory_getmemorylimit" }, @@ -14069,7 +16373,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L202", - "community": 53, + "community": 222, "norm_label": "countmemories()", "id": "prometheus_memory_countmemories" }, @@ -14078,7 +16382,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L211", - "community": 53, + "community": 222, "norm_label": "touch()", "id": "prometheus_memory_touch" }, @@ -14087,7 +16391,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L222", - "community": 53, + "community": 222, "norm_label": "upsertmemory()", "id": "prometheus_memory_upsertmemory" }, @@ -14096,7 +16400,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L286", - "community": 104, + "community": 53, "norm_label": "search()", "id": "prometheus_memory_search" }, @@ -14105,7 +16409,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L349", - "community": 104, + "community": 53, "norm_label": "fulltextsearch()", "id": "prometheus_memory_fulltextsearch" }, @@ -14114,7 +16418,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L407", - "community": 53, + "community": 27, "norm_label": "getusermemories()", "id": "prometheus_memory_getusermemories" }, @@ -14132,7 +16436,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L450", - "community": 53, + "community": 222, "norm_label": "extract()", "id": "prometheus_memory_extract" }, @@ -14411,7 +16715,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L1", - "community": 571, + "community": 576, "norm_label": "tools.py", "id": "main_app_prometheus_tools_py" }, @@ -14420,7 +16724,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L20", - "community": 152, + "community": 136, "norm_label": "search_memory()", "id": "prometheus_tools_search_memory" }, @@ -14429,7 +16733,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L51", - "community": 528, + "community": 503, "norm_label": "save_memory()", "id": "prometheus_tools_save_memory" }, @@ -14438,7 +16742,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L93", - "community": 546, + "community": 221, "norm_label": "execute_code()", "id": "prometheus_tools_execute_code" }, @@ -14447,7 +16751,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L114", - "community": 573, + "community": 588, "norm_label": "read_file()", "id": "prometheus_tools_read_file" }, @@ -14492,7 +16796,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L21", - "community": 152, + "community": 136, "norm_label": "search user's saved memories, preferences, and past analysis context. use", "id": "prometheus_tools_rationale_21" }, @@ -14501,7 +16805,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L52", - "community": 528, + "community": 503, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_52" }, @@ -14510,7 +16814,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L94", - "community": 546, + "community": 221, "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", "id": "prometheus_tools_rationale_94" }, @@ -14519,7 +16823,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L115", - "community": 573, + "community": 588, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_115" }, @@ -14555,7 +16859,7 @@ "file_type": "code", "source_file": "main/app/prometheus/vector.py", "source_location": "L1", - "community": 104, + "community": 21, "norm_label": "vector.py", "id": "main_app_prometheus_vector_py" }, @@ -14564,7 +16868,7 @@ "file_type": "code", "source_file": "main/app/prometheus/vector.py", "source_location": "L10", - "community": 104, + "community": 21, "norm_label": "normalizerows()", "id": "prometheus_vector_normalizerows" }, @@ -14573,7 +16877,7 @@ "file_type": "code", "source_file": "main/app/prometheus/vector.py", "source_location": "L15", - "community": 104, + "community": 53, "norm_label": "embed()", "id": "prometheus_vector_embed" }, @@ -14582,7 +16886,7 @@ "file_type": "code", "source_file": "main/app/prometheus/vector.py", "source_location": "L19", - "community": 104, + "community": 21, "norm_label": "decodeembeddings()", "id": "prometheus_vector_decodeembeddings" }, @@ -14591,7 +16895,7 @@ "file_type": "code", "source_file": "main/app/prometheus/vector.py", "source_location": "L41", - "community": 104, + "community": 21, "norm_label": "batchcosinesimilarity()", "id": "prometheus_vector_batchcosinesimilarity" }, @@ -14600,7 +16904,7 @@ "file_type": "code", "source_file": "main/app/prometheus/vector.py", "source_location": "L51", - "community": 53, + "community": 222, "norm_label": "contenthash()", "id": "prometheus_vector_contenthash" }, @@ -14609,7 +16913,7 @@ "file_type": "code", "source_file": "main/app/prometheus/vector.py", "source_location": "L55", - "community": 104, + "community": 21, "norm_label": "tovectorstring()", "id": "prometheus_vector_tovectorstring" }, @@ -14618,7 +16922,7 @@ "file_type": "code", "source_file": "main/app/prometheus/vector.py", "source_location": "L59", - "community": 104, + "community": 21, "norm_label": "fromvectorstring()", "id": "prometheus_vector_fromvectorstring" }, @@ -14753,7 +17057,7 @@ "file_type": "code", "source_file": "main/models/prometheus.py", "source_location": "L1", - "community": 61, + "community": 125, "norm_label": "prometheus.py", "id": "main_models_prometheus_py" }, @@ -14762,7 +17066,7 @@ "file_type": "code", "source_file": "main/models/prometheus.py", "source_location": "L7", - "community": 61, + "community": 125, "norm_label": "prometheussession", "id": "models_prometheus_prometheussession" }, @@ -14789,7 +17093,7 @@ "file_type": "code", "source_file": "main/service/prometheus_service.py", "source_location": "L23", - "community": 584, + "community": 95, "norm_label": "memorymaintenance()", "id": "service_prometheus_service_memorymaintenance" }, @@ -15365,7 +17669,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compress.py", "source_location": "L46", - "community": 194, + "community": 251, "norm_label": "walk()", "id": "stocks_api_compress_walk" }, @@ -15374,7 +17678,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compress.py", "source_location": "L75", - "community": 194, + "community": 251, "norm_label": "tocolumnar()", "id": "stocks_api_compress_tocolumnar" }, @@ -15383,7 +17687,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compress.py", "source_location": "L84", - "community": 194, + "community": 251, "norm_label": "fixheaders()", "id": "stocks_api_compress_fixheaders" }, @@ -15509,7 +17813,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L31", - "community": 621, + "community": 53, "norm_label": "matrixkey()", "id": "prometheus_memory_matrixkey" }, @@ -15518,7 +17822,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L38", - "community": 621, + "community": 53, "norm_label": "matrixusertag()", "id": "prometheus_memory_matrixusertag" }, @@ -15527,7 +17831,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L450", - "community": 53, + "community": 222, "norm_label": "counttokenscached()", "id": "prometheus_memory_counttokenscached" }, @@ -15554,7 +17858,7 @@ "file_type": "code", "source_file": "main/app/prometheus/mcp.py", "source_location": "L10", - "community": 590, + "community": 105, "norm_label": "ensurefastmcp()", "id": "prometheus_mcp_ensurefastmcp" }, @@ -15563,7 +17867,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L43", - "community": 621, + "community": 53, "norm_label": "getmatrixasync()", "id": "prometheus_memory_getmatrixasync" }, @@ -15590,7 +17894,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L244", - "community": 53, + "community": 222, "norm_label": "upsertmemoryasync()", "id": "prometheus_memory_upsertmemoryasync" }, @@ -15599,7 +17903,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L333", - "community": 104, + "community": 53, "norm_label": "searchasync()", "id": "prometheus_memory_searchasync" }, @@ -15617,7 +17921,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L20", - "community": 152, + "community": 136, "norm_label": "search user's saved memories, preferences, and past analysis context. use", "id": "prometheus_tools_rationale_20" }, @@ -15626,7 +17930,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L50", - "community": 528, + "community": 503, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_50" }, @@ -15635,7 +17939,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L91", - "community": 546, + "community": 221, "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", "id": "prometheus_tools_rationale_91" }, @@ -15644,7 +17948,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L112", - "community": 573, + "community": 588, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_112" }, @@ -15662,7 +17966,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L142", - "community": 571, + "community": 576, "norm_label": "list files in the workspace directory. args: path: directory pat", "id": "prometheus_tools_rationale_142" }, @@ -15707,7 +18011,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L19", - "community": 152, + "community": 136, "norm_label": "search user's saved memories, preferences, and past analysis context. use", "id": "prometheus_tools_rationale_19" }, @@ -15716,7 +18020,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L49", - "community": 528, + "community": 503, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_49" }, @@ -15725,7 +18029,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L90", - "community": 546, + "community": 221, "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", "id": "prometheus_tools_rationale_90" }, @@ -15734,7 +18038,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L111", - "community": 573, + "community": 588, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_111" }, @@ -15779,7 +18083,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L23", - "community": 81, + "community": 560, "norm_label": "jsonbytesresponse", "id": "controller_stocksapi_controller_jsonbytesresponse" }, @@ -15788,7 +18092,7 @@ "file_type": "code", "source_file": "", "source_location": "", - "community": 81, + "community": 560, "norm_label": "fastapiresponse", "id": "fastapiresponse" }, @@ -15797,7 +18101,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L26", - "community": 81, + "community": 560, "norm_label": ".render()", "id": "controller_stocksapi_controller_jsonbytesresponse_render" }, @@ -15869,7 +18173,7 @@ "file_type": "code", "source_file": "bench/bench_memory_vector.py", "source_location": "L1", - "community": 104, + "community": 21, "norm_label": "bench_memory_vector.py", "id": "bench_bench_memory_vector_py" }, @@ -15878,7 +18182,7 @@ "file_type": "code", "source_file": "bench/bench_memory_vector.py", "source_location": "L14", - "community": 104, + "community": 21, "norm_label": "benchonce()", "id": "bench_bench_memory_vector_benchonce" }, @@ -15887,7 +18191,7 @@ "file_type": "code", "source_file": "bench/bench_memory_vector.py", "source_location": "L41", - "community": 104, + "community": 21, "norm_label": "main()", "id": "bench_bench_memory_vector_main" }, @@ -16589,7 +18893,7 @@ "file_type": "rationale", "source_file": "main/service/scraper_service.py", "source_location": "L23", - "community": 21, + "community": 474, "norm_label": "p5: register the scraper cron jobs on the shared scheduler. kept in this", "id": "service_scraper_service_rationale_23" }, @@ -17786,7 +20090,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L36", - "community": 222, + "community": 194, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_36" }, @@ -17831,7 +20135,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L40", - "community": 222, + "community": 194, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_40" }, @@ -17912,7 +20216,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L89", - "community": 544, + "community": 574, "norm_label": "fieldregistry", "id": "prometheus_compact_fieldregistry" }, @@ -17921,7 +20225,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L94", - "community": 544, + "community": 574, "norm_label": ".buildurl()", "id": "prometheus_compact_fieldregistry_buildurl" }, @@ -17930,7 +20234,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L99", - "community": 544, + "community": 574, "norm_label": ".fetchfields()", "id": "prometheus_compact_fieldregistry_fetchfields" }, @@ -17939,7 +20243,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L120", - "community": 544, + "community": 574, "norm_label": ".getfields()", "id": "prometheus_compact_fieldregistry_getfields" }, @@ -17948,7 +20252,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L127", - "community": 544, + "community": 574, "norm_label": ".buildmetricregex()", "id": "prometheus_compact_fieldregistry_buildmetricregex" }, @@ -17957,7 +20261,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L134", - "community": 544, + "community": 574, "norm_label": ".getmetricregex()", "id": "prometheus_compact_fieldregistry_getmetricregex" }, @@ -17966,7 +20270,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L222", - "community": 80, + "community": 589, "norm_label": ".__init__()", "id": "prometheus_compact_prometheuscompactor_init" }, @@ -17975,7 +20279,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L18", - "community": 152, + "community": 136, "norm_label": "_getdb()", "id": "prometheus_tools_getdb" }, @@ -17984,7 +20288,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L27", - "community": 152, + "community": 136, "norm_label": "search user's saved memories, preferences, and past analysis context. use", "id": "prometheus_tools_rationale_27" }, @@ -17993,7 +20297,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L54", - "community": 528, + "community": 503, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_54" }, @@ -18002,7 +20306,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L92", - "community": 546, + "community": 221, "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", "id": "prometheus_tools_rationale_92" }, @@ -18011,7 +20315,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L113", - "community": 573, + "community": 588, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_113" }, @@ -18065,7 +20369,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L48", - "community": 222, + "community": 194, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_48" }, @@ -18110,7 +20414,7 @@ "file_type": "code", "source_file": "main/utils/service_manager.py", "source_location": "L15", - "community": 45, + "community": 536, "norm_label": "servicemanager", "id": "utils_service_manager_servicemanager" }, @@ -18470,7 +20774,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L139", - "community": 544, + "community": 574, "norm_label": ".invalidate()", "id": "prometheus_compact_fieldregistry_invalidate" }, @@ -18479,7 +20783,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L145", - "community": 544, + "community": 574, "norm_label": ".warmup()", "id": "prometheus_compact_fieldregistry_warmup" }, @@ -18488,7 +20792,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L153", - "community": 53, + "community": 222, "norm_label": "charcount()", "id": "prometheus_compact_charcount" }, @@ -18560,7 +20864,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L24", - "community": 81, + "community": 560, "norm_label": "sends pre-serialized json bytes without re-encoding (cache-friendly).", "id": "controller_stocksapi_controller_rationale_24" }, @@ -18569,7 +20873,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L49", - "community": 222, + "community": 194, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_49" }, @@ -18614,7 +20918,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L1", - "community": 596, + "community": 603, "norm_label": "response_cache.py", "id": "main_app_stocks_api_response_cache_py" }, @@ -18623,7 +20927,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L19", - "community": 596, + "community": 603, "norm_label": "responsecache", "id": "stocks_api_response_cache_responsecache" }, @@ -18632,7 +20936,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L20", - "community": 596, + "community": 603, "norm_label": ".__init__()", "id": "stocks_api_response_cache_responsecache_init" }, @@ -18641,7 +20945,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L29", - "community": 596, + "community": 603, "norm_label": ".makekey()", "id": "stocks_api_response_cache_responsecache_makekey" }, @@ -18650,7 +20954,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L34", - "community": 596, + "community": 603, "norm_label": ".get()", "id": "stocks_api_response_cache_responsecache_get" }, @@ -18704,7 +21008,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L323", - "community": 26, + "community": 560, "norm_label": "generatekey()", "id": "controller_stocksapi_controller_generatekey" }, @@ -18713,7 +21017,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L30", - "community": 222, + "community": 194, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_30" }, @@ -19442,7 +21746,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L94", - "community": 544, + "community": 574, "norm_label": ".__new__()", "id": "prometheus_compact_fieldregistry_new" }, @@ -19451,7 +21755,7 @@ "file_type": "code", "source_file": "main/app/prometheus/mcp.py", "source_location": "L38", - "community": 590, + "community": 105, "norm_label": ".__new__()", "id": "prometheus_mcp_mcpclientpool_new" }, @@ -19505,7 +21809,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L1", - "community": 54, + "community": 523, "norm_label": "compressor.py", "id": "main_app_stocks_api_compressor_py" }, @@ -19514,7 +21818,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L25", - "community": 54, + "community": 523, "norm_label": "getabbr()", "id": "stocks_api_compressor_getabbr" }, @@ -19523,7 +21827,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L36", - "community": 54, + "community": 523, "norm_label": "getnest()", "id": "stocks_api_compressor_getnest" }, @@ -19541,7 +21845,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L51", - "community": 54, + "community": 523, "norm_label": "walk()", "id": "stocks_api_compressor_walk" }, @@ -19550,7 +21854,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L59", - "community": 54, + "community": 523, "norm_label": "compactvalue()", "id": "stocks_api_compressor_compactvalue" }, @@ -19559,7 +21863,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L80", - "community": 54, + "community": 523, "norm_label": "tocolumnar()", "id": "stocks_api_compressor_tocolumnar" }, @@ -19568,7 +21872,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L89", - "community": 54, + "community": 523, "norm_label": "fixheaders()", "id": "stocks_api_compressor_fixheaders" }, @@ -19577,7 +21881,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L98", - "community": 54, + "community": 523, "norm_label": "compactrow()", "id": "stocks_api_compressor_compactrow" }, @@ -19586,7 +21890,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L126", - "community": 54, + "community": 523, "norm_label": "compactcotations()", "id": "stocks_api_compressor_compactcotations" }, @@ -19595,7 +21899,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L160", - "community": 54, + "community": 523, "norm_label": "compressresponse()", "id": "stocks_api_compressor_compressresponse" }, @@ -20477,7 +22781,7 @@ "file_type": "code", "source_file": "main/app/prometheus/state.py", "source_location": "L14", - "community": 63, + "community": 502, "norm_label": ".set()", "id": "prometheus_state_harnessstate_set" }, @@ -20531,7 +22835,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L89", - "community": 16, + "community": 521, "norm_label": "get_state()", "id": "prometheus_tools_get_state" }, @@ -20540,7 +22844,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L104", - "community": 546, + "community": 221, "norm_label": "set_state()", "id": "prometheus_tools_set_state" }, @@ -20549,7 +22853,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L105", - "community": 546, + "community": 221, "norm_label": "store a value in the harness state for this session. use this to save inter", "id": "prometheus_tools_rationale_105" }, @@ -20558,7 +22862,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L123", - "community": 546, + "community": 221, "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", "id": "prometheus_tools_rationale_123" }, @@ -20585,7 +22889,7 @@ "file_type": "code", "source_file": "main/app/prometheus/mcp.py", "source_location": "L16", - "community": 590, + "community": 105, "norm_label": "_parseservers()", "id": "prometheus_mcp_parseservers" }, @@ -20756,7 +23060,7 @@ "file_type": "code", "source_file": "main/utils/connectivity.py", "source_location": "L13", - "community": 523, + "community": 72, "norm_label": "checksingledb()", "id": "utils_connectivity_checksingledb" }, @@ -20765,7 +23069,7 @@ "file_type": "code", "source_file": "main/app/prometheus/_summarizer_legacy.py", "source_location": "L1", - "community": 189, + "community": 524, "norm_label": "_summarizer_legacy.py", "id": "main_app_prometheus_summarizer_legacy_py" }, @@ -20774,7 +23078,7 @@ "file_type": "code", "source_file": "main/app/prometheus/_summarizer_legacy.py", "source_location": "L19", - "community": 189, + "community": 524, "norm_label": "gettokenizer()", "id": "prometheus_summarizer_legacy_gettokenizer" }, @@ -20783,7 +23087,7 @@ "file_type": "code", "source_file": "main/app/prometheus/_summarizer_legacy.py", "source_location": "L31", - "community": 189, + "community": 524, "norm_label": "counttokens()", "id": "prometheus_summarizer_legacy_counttokens" }, @@ -20792,7 +23096,7 @@ "file_type": "code", "source_file": "main/app/prometheus/_summarizer_legacy.py", "source_location": "L44", - "community": 189, + "community": 524, "norm_label": "smarttruncate()", "id": "prometheus_summarizer_legacy_smarttruncate" }, @@ -20801,7 +23105,7 @@ "file_type": "code", "source_file": "main/app/prometheus/_summarizer_legacy.py", "source_location": "L110", - "community": 189, + "community": 524, "norm_label": "prometheussummarizer", "id": "prometheus_summarizer_legacy_prometheussummarizer" }, @@ -20810,7 +23114,7 @@ "file_type": "code", "source_file": "main/app/prometheus/_summarizer_legacy.py", "source_location": "L111", - "community": 189, + "community": 524, "norm_label": ".shouldsummarize()", "id": "prometheus_summarizer_legacy_prometheussummarizer_shouldsummarize" }, @@ -20819,7 +23123,7 @@ "file_type": "code", "source_file": "main/app/prometheus/_summarizer_legacy.py", "source_location": "L117", - "community": 189, + "community": 524, "norm_label": ".getsummarizablechunk()", "id": "prometheus_summarizer_legacy_prometheussummarizer_getsummarizablechunk" }, @@ -20828,7 +23132,7 @@ "file_type": "code", "source_file": "main/app/prometheus/_summarizer_legacy.py", "source_location": "L128", - "community": 189, + "community": 524, "norm_label": ".consolidate()", "id": "prometheus_summarizer_legacy_prometheussummarizer_consolidate" }, @@ -20837,7 +23141,7 @@ "file_type": "code", "source_file": "main/app/prometheus/_summarizer_legacy.py", "source_location": "L186", - "community": 189, + "community": 524, "norm_label": ".summarize()", "id": "prometheus_summarizer_legacy_prometheussummarizer_summarize" }, @@ -20846,7 +23150,7 @@ "file_type": "code", "source_file": "main/app/prometheus/_summarizer_legacy.py", "source_location": "L237", - "community": 189, + "community": 524, "norm_label": ".getepisodes()", "id": "prometheus_summarizer_legacy_prometheussummarizer_getepisodes" }, @@ -20864,7 +23168,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L27", - "community": 222, + "community": 194, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_27" }, @@ -21026,7 +23330,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L48", - "community": 53, + "community": 222, "norm_label": "applyupdate()", "id": "prometheus_memory_applyupdate" }, @@ -21935,7 +24239,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L18", - "community": 152, + "community": 136, "norm_label": "search user's saved memories, preferences, and past analysis context. use", "id": "prometheus_tools_rationale_18" }, @@ -21944,7 +24248,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L44", - "community": 528, + "community": 503, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_44" }, @@ -21953,7 +24257,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L81", - "community": 16, + "community": 521, "norm_label": "retrieve values from the harness state. use this to recall intermediate results,", "id": "prometheus_tools_rationale_81" }, @@ -21962,7 +24266,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L96", - "community": 546, + "community": 221, "norm_label": "store a value in the harness state for this session. use this to save inter", "id": "prometheus_tools_rationale_96" }, @@ -21971,7 +24275,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L114", - "community": 546, + "community": 221, "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", "id": "prometheus_tools_rationale_114" }, @@ -22691,7 +24995,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L26", - "community": 222, + "community": 194, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_26" }, @@ -28154,7 +30458,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L1", - "community": 251, + "community": 561, "norm_label": "conftest.py", "id": "tests_conftest_py" }, @@ -28163,7 +30467,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L13", - "community": 251, + "community": 561, "norm_label": "_reset_rate_limiter()", "id": "tests_conftest_reset_rate_limiter" }, @@ -28172,7 +30476,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L20", - "community": 251, + "community": 561, "norm_label": "pytest_configure()", "id": "tests_conftest_pytest_configure" }, @@ -28181,7 +30485,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L33", - "community": 251, + "community": 561, "norm_label": "_patch_secret_key()", "id": "tests_conftest_patch_secret_key" }, @@ -28190,7 +30494,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L48", - "community": 251, + "community": 561, "norm_label": "dbsession()", "id": "tests_conftest_dbsession" }, @@ -28199,7 +30503,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L60", - "community": 251, + "community": 561, "norm_label": "sampleuserdata()", "id": "tests_conftest_sampleuserdata" }, @@ -28208,7 +30512,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L71", - "community": 251, + "community": 561, "norm_label": "sampleapikeydata()", "id": "tests_conftest_sampleapikeydata" }, @@ -28217,7 +30521,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L76", - "community": 251, + "community": 561, "norm_label": "sampleprometheussessiondata()", "id": "tests_conftest_sampleprometheussessiondata" }, @@ -28226,7 +30530,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L81", - "community": 535, + "community": 561, "norm_label": "stocks_http_client()", "id": "tests_conftest_stocks_http_client" }, @@ -28235,7 +30539,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L106", - "community": 535, + "community": 561, "norm_label": "client()", "id": "tests_conftest_client" }, @@ -28244,7 +30548,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L14", - "community": 251, + "community": 561, "norm_label": "reset slowapi in-memory rate limiter between every test.", "id": "tests_conftest_rationale_14" }, @@ -28253,7 +30557,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L21", - "community": 251, + "community": 561, "norm_label": "set required env vars before test collection. config.py eagerly instantia", "id": "tests_conftest_rationale_21" }, @@ -28262,7 +30566,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L82", - "community": 535, + "community": 561, "norm_label": "testclient with stocks router + verifyapikey + getcurrentuser overrides.", "id": "tests_conftest_rationale_82" }, @@ -28271,7 +30575,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L107", - "community": 535, + "community": 561, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_107" }, @@ -28379,7 +30683,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L7", - "community": 504, + "community": 511, "norm_label": "testbuildsystempromptstate", "id": "tests_test_agent_state_integration_testbuildsystempromptstate" }, @@ -28388,7 +30692,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L8", - "community": 504, + "community": 511, "norm_label": ".test_build_system_prompt_no_state()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_no_state" }, @@ -28397,7 +30701,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L13", - "community": 504, + "community": 511, "norm_label": ".test_build_system_prompt_with_state()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_with_state" }, @@ -28406,7 +30710,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L21", - "community": 504, + "community": 511, "norm_label": ".test_build_system_prompt_empty_state()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_empty_state" }, @@ -28415,7 +30719,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L27", - "community": 504, + "community": 511, "norm_label": ".test_build_system_prompt_state_after_memories()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_state_after_memories" }, @@ -28424,7 +30728,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L37", - "community": 504, + "community": 511, "norm_label": ".test_build_system_prompt_multiple_state_entries()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_multiple_state_entries" }, @@ -28505,7 +30809,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L9", - "community": 504, + "community": 511, "norm_label": "system prompt should work without state parameter.", "id": "tests_test_agent_state_integration_rationale_9" }, @@ -28514,7 +30818,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L14", - "community": 504, + "community": 511, "norm_label": "system prompt should include state context when provided.", "id": "tests_test_agent_state_integration_rationale_14" }, @@ -28523,7 +30827,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L22", - "community": 504, + "community": 511, "norm_label": "system prompt should not include state section when empty.", "id": "tests_test_agent_state_integration_rationale_22" }, @@ -28532,7 +30836,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L28", - "community": 504, + "community": 511, "norm_label": "state section should appear after memories section.", "id": "tests_test_agent_state_integration_rationale_28" }, @@ -28541,7 +30845,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L38", - "community": 504, + "community": 511, "norm_label": "all state entries should appear in the prompt.", "id": "tests_test_agent_state_integration_rationale_38" }, @@ -28595,7 +30899,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L1", - "community": 604, + "community": 602, "norm_label": "test_api_key_quota_atomic.py", "id": "tests_test_api_key_quota_atomic_py" }, @@ -28604,7 +30908,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L18", - "community": 604, + "community": 602, "norm_label": "samplekeydata()", "id": "tests_test_api_key_quota_atomic_samplekeydata" }, @@ -28658,7 +30962,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L150", - "community": 608, + "community": 26, "norm_label": ".test_invalid_api_key_returns_zero_rows()", "id": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_invalid_api_key_returns_zero_rows" }, @@ -28667,7 +30971,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L164", - "community": 608, + "community": 26, "norm_label": ".test_multiple_keys_independent_quotas()", "id": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_multiple_keys_independent_quotas" }, @@ -28739,7 +31043,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L1", - "community": 604, + "community": 602, "norm_label": "tests for atomic api key quota enforcement (race condition fix). verifies tha", "id": "tests_test_api_key_quota_atomic_rationale_1" }, @@ -28748,7 +31052,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L19", - "community": 604, + "community": 602, "norm_label": "sample api key data for tests.", "id": "tests_test_api_key_quota_atomic_rationale_19" }, @@ -28802,7 +31106,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L151", - "community": 608, + "community": 26, "norm_label": "test that invalid api key returns zero rows affected.", "id": "tests_test_api_key_quota_atomic_rationale_151" }, @@ -28811,7 +31115,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L165", - "community": 608, + "community": 26, "norm_label": "test that multiple api keys have independent quotas.", "id": "tests_test_api_key_quota_atomic_rationale_165" }, @@ -28883,7 +31187,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L1", - "community": 560, + "community": 538, "norm_label": "test_auth_util.py", "id": "tests_test_auth_util_py" }, @@ -28982,7 +31286,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L69", - "community": 560, + "community": 538, "norm_label": "testsessionexpiryconfig", "id": "tests_test_auth_util_testsessionexpiryconfig" }, @@ -28991,7 +31295,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L70", - "community": 560, + "community": 538, "norm_label": ".test_session_expiry_days_is_30()", "id": "tests_test_auth_util_testsessionexpiryconfig_test_session_expiry_days_is_30" }, @@ -29000,7 +31304,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L73", - "community": 560, + "community": 538, "norm_label": ".test_session_expiry_hours_calculation()", "id": "tests_test_auth_util_testsessionexpiryconfig_test_session_expiry_hours_calculation" }, @@ -29009,7 +31313,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L78", - "community": 560, + "community": 538, "norm_label": ".test_default_token_expiry_equals_30_days()", "id": "tests_test_auth_util_testsessionexpiryconfig_test_default_token_expiry_equals_30_days" }, @@ -29072,7 +31376,7 @@ "file_type": "code", "source_file": "tests/test_config.py", "source_location": "L1", - "community": 586, + "community": 102, "norm_label": "test_config.py", "id": "tests_test_config_py" }, @@ -29081,7 +31385,7 @@ "file_type": "code", "source_file": "tests/test_config.py", "source_location": "L5", - "community": 586, + "community": 102, "norm_label": "testconfig", "id": "tests_test_config_testconfig" }, @@ -29099,7 +31403,7 @@ "file_type": "code", "source_file": "tests/test_config.py", "source_location": "L12", - "community": 586, + "community": 102, "norm_label": ".test_prometheus_getitem()", "id": "tests_test_config_testconfig_test_prometheus_getitem" }, @@ -29117,7 +31421,7 @@ "file_type": "code", "source_file": "tests/test_config.py", "source_location": "L22", - "community": 586, + "community": 102, "norm_label": ".test_base_mansa_settings_get()", "id": "tests_test_config_testconfig_test_base_mansa_settings_get" }, @@ -29135,7 +31439,7 @@ "file_type": "code", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L8", - "community": 624, + "community": 621, "norm_label": "testcheckmysqlconnection", "id": "tests_test_connectivity_coverage_testcheckmysqlconnection" }, @@ -29225,7 +31529,7 @@ "file_type": "code", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L114", - "community": 623, + "community": 618, "norm_label": "testcheckserviceconnection", "id": "tests_test_connectivity_coverage_testcheckserviceconnection" }, @@ -29315,7 +31619,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L9", - "community": 624, + "community": 621, "norm_label": "checkmysqlconnection \u2014 success, errors, engine=none paths.", "id": "tests_test_connectivity_coverage_rationale_9" }, @@ -29324,7 +31628,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L115", - "community": 623, + "community": 618, "norm_label": "checkserviceconnection \u2014 success, not found, errors.", "id": "tests_test_connectivity_coverage_rationale_115" }, @@ -29432,7 +31736,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L146", - "community": 45, + "community": 120, "norm_label": "testregisterendpoint", "id": "tests_test_controllers_coverage_testregisterendpoint" }, @@ -29477,7 +31781,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L215", - "community": 45, + "community": 120, "norm_label": "testloginendpoint", "id": "tests_test_controllers_coverage_testloginendpoint" }, @@ -29504,7 +31808,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L257", - "community": 45, + "community": 120, "norm_label": "testlogoutendpoint", "id": "tests_test_controllers_coverage_testlogoutendpoint" }, @@ -29594,7 +31898,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L390", - "community": 45, + "community": 120, "norm_label": "testgooglecallback", "id": "tests_test_controllers_coverage_testgooglecallback" }, @@ -29801,7 +32105,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L727", - "community": 120, + "community": 498, "norm_label": "testrevokesession", "id": "tests_test_controllers_coverage_testrevokesession" }, @@ -29810,7 +32114,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L730", - "community": 120, + "community": 498, "norm_label": ".test_revoke_session_success()", "id": "tests_test_controllers_coverage_testrevokesession_test_revoke_session_success" }, @@ -29819,7 +32123,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L757", - "community": 120, + "community": 498, "norm_label": ".test_revoke_session_not_found()", "id": "tests_test_controllers_coverage_testrevokesession_test_revoke_session_not_found" }, @@ -29828,7 +32132,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L779", - "community": 120, + "community": 498, "norm_label": ".test_revoke_session_failure()", "id": "tests_test_controllers_coverage_testrevokesession_test_revoke_session_failure" }, @@ -29837,7 +32141,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L805", - "community": 221, + "community": 616, "norm_label": "testrevokeallsessions", "id": "tests_test_controllers_coverage_testrevokeallsessions" }, @@ -29846,7 +32150,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L808", - "community": 221, + "community": 616, "norm_label": ".test_revoke_all_sessions()", "id": "tests_test_controllers_coverage_testrevokeallsessions_test_revoke_all_sessions" }, @@ -29855,7 +32159,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L835", - "community": 45, + "community": 626, "norm_label": "testprometheushealth", "id": "tests_test_controllers_coverage_testprometheushealth" }, @@ -29864,7 +32168,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L838", - "community": 45, + "community": 626, "norm_label": ".test_health()", "id": "tests_test_controllers_coverage_testprometheushealth_test_health" }, @@ -29972,7 +32276,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L997", - "community": 99, + "community": 535, "norm_label": "testprometheusdeletesession", "id": "tests_test_controllers_coverage_testprometheusdeletesession" }, @@ -29981,7 +32285,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1000", - "community": 99, + "community": 535, "norm_label": ".test_delete_session_success()", "id": "tests_test_controllers_coverage_testprometheusdeletesession_test_delete_session_success" }, @@ -29990,7 +32294,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1010", - "community": 99, + "community": 535, "norm_label": ".test_delete_session_not_found()", "id": "tests_test_controllers_coverage_testprometheusdeletesession_test_delete_session_not_found" }, @@ -30026,7 +32330,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1085", - "community": 148, + "community": 498, "norm_label": ".test_chat_existing_session_not_owner()", "id": "tests_test_controllers_coverage_testprometheuschat_test_chat_existing_session_not_owner" }, @@ -30035,7 +32339,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1121", - "community": 99, + "community": 148, "norm_label": ".test_chat_generic_exception()", "id": "tests_test_controllers_coverage_testprometheuschat_test_chat_generic_exception" }, @@ -30044,7 +32348,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1144", - "community": 605, + "community": 604, "norm_label": "teststocksapihealth", "id": "tests_test_controllers_coverage_teststocksapihealth" }, @@ -30053,7 +32357,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1147", - "community": 605, + "community": 604, "norm_label": ".test_health()", "id": "tests_test_controllers_coverage_teststocksapihealth_test_health" }, @@ -30080,7 +32384,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1172", - "community": 14, + "community": 605, "norm_label": "teststocksapifundamental", "id": "tests_test_controllers_coverage_teststocksapifundamental" }, @@ -30089,7 +32393,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1175", - "community": 14, + "community": 605, "norm_label": ".test_get_fundamental()", "id": "tests_test_controllers_coverage_teststocksapifundamental_test_get_fundamental" }, @@ -30134,7 +32438,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1229", - "community": 568, + "community": 620, "norm_label": "testaddroletouser", "id": "tests_test_controllers_coverage_testaddroletouser" }, @@ -30143,7 +32447,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1232", - "community": 568, + "community": 623, "norm_label": ".test_add_role_success()", "id": "tests_test_controllers_coverage_testaddroletouser_test_add_role_success" }, @@ -30152,7 +32456,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1249", - "community": 493, + "community": 625, "norm_label": ".test_add_role_already_has_role()", "id": "tests_test_controllers_coverage_testaddroletouser_test_add_role_already_has_role" }, @@ -30161,7 +32465,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1263", - "community": 568, + "community": 529, "norm_label": ".test_add_role_user_not_found()", "id": "tests_test_controllers_coverage_testaddroletouser_test_add_role_user_not_found" }, @@ -30170,7 +32474,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1275", - "community": 493, + "community": 563, "norm_label": "testgetcurrentuser", "id": "tests_test_controllers_coverage_testgetcurrentuser" }, @@ -30179,7 +32483,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1278", - "community": 493, + "community": 563, "norm_label": "._make_mock_request()", "id": "tests_test_controllers_coverage_testgetcurrentuser_make_mock_request" }, @@ -30188,7 +32492,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1282", - "community": 493, + "community": 563, "norm_label": ".test_get_current_user_valid_session()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_valid_session" }, @@ -30197,7 +32501,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1307", - "community": 493, + "community": 568, "norm_label": ".test_get_current_user_session_revoked()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_session_revoked" }, @@ -30206,7 +32510,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1323", - "community": 493, + "community": 609, "norm_label": ".test_get_current_user_not_found()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_not_found" }, @@ -30215,7 +32519,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1340", - "community": 493, + "community": 614, "norm_label": ".test_get_current_user_generic_exception()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_generic_exception" }, @@ -30224,7 +32528,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1357", - "community": 493, + "community": 617, "norm_label": ".test_get_current_user_no_session_id()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_no_session_id" }, @@ -30242,7 +32546,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1384", - "community": 43, + "community": 45, "norm_label": ".test_empty_password_raises()", "id": "tests_test_controllers_coverage_testhashpasswordempty_test_empty_password_raises" }, @@ -30251,7 +32555,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1391", - "community": 524, + "community": 546, "norm_label": "testverifyaccesstoken", "id": "tests_test_controllers_coverage_testverifyaccesstoken" }, @@ -30260,7 +32564,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1394", - "community": 524, + "community": 546, "norm_label": ".test_expired_token()", "id": "tests_test_controllers_coverage_testverifyaccesstoken_test_expired_token" }, @@ -30269,7 +32573,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1410", - "community": 524, + "community": 592, "norm_label": ".test_invalid_token()", "id": "tests_test_controllers_coverage_testverifyaccesstoken_test_invalid_token" }, @@ -30377,7 +32681,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L147", - "community": 45, + "community": 120, "norm_label": "covers lines 44-54, 63, 66-71: register success, valueerror, generic exception.", "id": "tests_test_controllers_coverage_rationale_147" }, @@ -30422,7 +32726,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L216", - "community": 45, + "community": 120, "norm_label": "covers lines 87-93, 102: login success and failure paths.", "id": "tests_test_controllers_coverage_rationale_216" }, @@ -30449,7 +32753,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L258", - "community": 45, + "community": 120, "norm_label": "covers lines 107, 109-130, 133: logout token extraction and revocation.", "id": "tests_test_controllers_coverage_rationale_258" }, @@ -30467,7 +32771,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L281", - "community": 45, + "community": 120, "norm_label": "covers lines 111-113: token extracted from authorization bearer header.", "id": "tests_test_controllers_coverage_rationale_281" }, @@ -30539,7 +32843,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L391", - "community": 45, + "community": 120, "norm_label": "covers lines 155-156, 158, 160-168, 170-177, 179-184, 186, 190-204: googlecallba", "id": "tests_test_controllers_coverage_rationale_391" }, @@ -30674,7 +32978,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L728", - "community": 120, + "community": 498, "norm_label": "covers lines 126-136: delete /user/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_728" }, @@ -30683,7 +32987,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L731", - "community": 120, + "community": 498, "norm_label": "covers lines 126, 131, 135-136.", "id": "tests_test_controllers_coverage_rationale_731" }, @@ -30692,7 +32996,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L758", - "community": 120, + "community": 498, "norm_label": "covers lines 127-129: session not found.", "id": "tests_test_controllers_coverage_rationale_758" }, @@ -30701,7 +33005,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L780", - "community": 120, + "community": 498, "norm_label": "covers lines 132-133: revokesession returns false.", "id": "tests_test_controllers_coverage_rationale_780" }, @@ -30710,7 +33014,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L806", - "community": 221, + "community": 616, "norm_label": "covers lines 143, 145, 147-148: post /user/sessions/revoke-all.", "id": "tests_test_controllers_coverage_rationale_806" }, @@ -30719,7 +33023,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L809", - "community": 221, + "community": 616, "norm_label": "covers lines 143, 145, 147-148.", "id": "tests_test_controllers_coverage_rationale_809" }, @@ -30728,7 +33032,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L836", - "community": 45, + "community": 626, "norm_label": "covers line 24: get /prometheus/health.", "id": "tests_test_controllers_coverage_rationale_836" }, @@ -30818,7 +33122,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L998", - "community": 99, + "community": 535, "norm_label": "covers lines 95-98: delete /prometheus/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_998" }, @@ -30827,7 +33131,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1001", - "community": 99, + "community": 535, "norm_label": "covers lines 95-98: session deleted.", "id": "tests_test_controllers_coverage_rationale_1001" }, @@ -30836,7 +33140,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1011", - "community": 99, + "community": 535, "norm_label": "covers lines 96-97: session not found.", "id": "tests_test_controllers_coverage_rationale_1011" }, @@ -30872,7 +33176,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1086", - "community": 148, + "community": 498, "norm_label": "covers lines 120-121: session ownership check fails.", "id": "tests_test_controllers_coverage_rationale_1086" }, @@ -30881,7 +33185,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1122", - "community": 99, + "community": 148, "norm_label": "generic exception in chat propagates via sse error event.", "id": "tests_test_controllers_coverage_rationale_1122" }, @@ -30890,7 +33194,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1145", - "community": 605, + "community": 604, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1145" }, @@ -30908,7 +33212,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1173", - "community": 14, + "community": 605, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1173" }, @@ -30953,7 +33257,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1230", - "community": 568, + "community": 620, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1230" }, @@ -30962,7 +33266,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1233", - "community": 568, + "community": 623, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1233" }, @@ -30971,7 +33275,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1250", - "community": 493, + "community": 625, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1250" }, @@ -30980,7 +33284,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1264", - "community": 568, + "community": 529, "norm_label": "covers lines 19-20: user not found raises 404.", "id": "tests_test_controllers_coverage_rationale_1264" }, @@ -30989,7 +33293,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1276", - "community": 493, + "community": 563, "norm_label": "covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: usermanager.getc", "id": "tests_test_controllers_coverage_rationale_1276" }, @@ -30998,7 +33302,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1283", - "community": 493, + "community": 563, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1283" }, @@ -31007,7 +33311,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1308", - "community": 493, + "community": 568, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1308" }, @@ -31016,7 +33320,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1324", - "community": 493, + "community": 609, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1324" }, @@ -31025,7 +33329,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1341", - "community": 493, + "community": 614, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1341" }, @@ -31034,7 +33338,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1358", - "community": 493, + "community": 617, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1358" }, @@ -31043,7 +33347,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1382", - "community": 524, + "community": 546, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1382" }, @@ -31052,7 +33356,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1392", - "community": 524, + "community": 546, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1392" }, @@ -31061,7 +33365,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1395", - "community": 524, + "community": 546, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1395" }, @@ -31070,7 +33374,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1411", - "community": 524, + "community": 592, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1411" }, @@ -31673,7 +33977,7 @@ "file_type": "code", "source_file": "tests/test_error_handlers.py", "source_location": "L25", - "community": 120, + "community": 498, "norm_label": "app()", "id": "tests_test_error_handlers_app" }, @@ -31961,7 +34265,7 @@ "file_type": "code", "source_file": "tests/test_harness_state.py", "source_location": "L1", - "community": 586, + "community": 8, "norm_label": "test_harness_state.py", "id": "tests_test_harness_state_py" }, @@ -32069,7 +34373,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L1", - "community": 611, + "community": 610, "norm_label": "test_http_session_coverage.py", "id": "tests_test_http_session_coverage_py" }, @@ -32078,7 +34382,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L8", - "community": 611, + "community": 610, "norm_label": "testgetsession", "id": "tests_test_http_session_coverage_testgetsession" }, @@ -32087,7 +34391,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L9", - "community": 611, + "community": 610, "norm_label": ".test_returns_same_session()", "id": "tests_test_http_session_coverage_testgetsession_test_returns_same_session" }, @@ -32096,7 +34400,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L16", - "community": 611, + "community": 610, "norm_label": ".test_returns_requests_session()", "id": "tests_test_http_session_coverage_testgetsession_test_returns_requests_session" }, @@ -32105,7 +34409,7 @@ "file_type": "rationale", "source_file": "tests/test_http_session_coverage.py", "source_location": "L1", - "community": 611, + "community": 610, "norm_label": "tests for main/utils/http_session.py \u2014 covers all branches.", "id": "tests_test_http_session_coverage_rationale_1" }, @@ -32123,7 +34427,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L14", - "community": 607, + "community": 25, "norm_label": "testregistervalidation", "id": "tests_test_input_validation_testregistervalidation" }, @@ -32132,7 +34436,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L17", - "community": 607, + "community": 25, "norm_label": ".test_valid_registration()", "id": "tests_test_input_validation_testregistervalidation_test_valid_registration" }, @@ -32141,7 +34445,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L25", - "community": 607, + "community": 25, "norm_label": ".test_username_too_short()", "id": "tests_test_input_validation_testregistervalidation_test_username_too_short" }, @@ -32150,7 +34454,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L32", - "community": 607, + "community": 25, "norm_label": ".test_username_too_long()", "id": "tests_test_input_validation_testregistervalidation_test_username_too_long" }, @@ -32159,7 +34463,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L39", - "community": 607, + "community": 25, "norm_label": ".test_email_too_short()", "id": "tests_test_input_validation_testregistervalidation_test_email_too_short" }, @@ -32168,7 +34472,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L46", - "community": 607, + "community": 25, "norm_label": ".test_password_too_short()", "id": "tests_test_input_validation_testregistervalidation_test_password_too_short" }, @@ -32177,7 +34481,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L54", - "community": 610, + "community": 25, "norm_label": "testloginvalidation", "id": "tests_test_input_validation_testloginvalidation" }, @@ -32186,7 +34490,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L57", - "community": 610, + "community": 25, "norm_label": ".test_valid_login_payload()", "id": "tests_test_input_validation_testloginvalidation_test_valid_login_payload" }, @@ -32195,7 +34499,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L65", - "community": 610, + "community": 25, "norm_label": ".test_username_too_short()", "id": "tests_test_input_validation_testloginvalidation_test_username_too_short" }, @@ -32204,7 +34508,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L72", - "community": 610, + "community": 25, "norm_label": ".test_password_too_short()", "id": "tests_test_input_validation_testloginvalidation_test_password_too_short" }, @@ -32276,7 +34580,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L129", - "community": 609, + "community": 25, "norm_label": "testchatvalidation", "id": "tests_test_input_validation_testchatvalidation" }, @@ -32285,7 +34589,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L132", - "community": 609, + "community": 25, "norm_label": ".test_empty_text()", "id": "tests_test_input_validation_testchatvalidation_test_empty_text" }, @@ -32294,7 +34598,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L140", - "community": 609, + "community": 25, "norm_label": ".test_text_too_long()", "id": "tests_test_input_validation_testchatvalidation_test_text_too_long" }, @@ -32303,7 +34607,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L148", - "community": 609, + "community": 25, "norm_label": ".test_max_length_boundary()", "id": "tests_test_input_validation_testchatvalidation_test_max_length_boundary" }, @@ -32357,7 +34661,7 @@ "file_type": "rationale", "source_file": "tests/test_input_validation.py", "source_location": "L15", - "community": 607, + "community": 25, "norm_label": "post /auth/register \u2014 validates username, email, password via body(...)", "id": "tests_test_input_validation_rationale_15" }, @@ -32366,7 +34670,7 @@ "file_type": "rationale", "source_file": "tests/test_input_validation.py", "source_location": "L55", - "community": 610, + "community": 25, "norm_label": "post /auth/login \u2014 validates username, password via body(...)", "id": "tests_test_input_validation_rationale_55" }, @@ -32393,7 +34697,7 @@ "file_type": "rationale", "source_file": "tests/test_input_validation.py", "source_location": "L130", - "community": 609, + "community": 25, "norm_label": "post /prometheus/chat/stream \u2014 validates query via body(...)", "id": "tests_test_input_validation_rationale_130" }, @@ -32555,7 +34859,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L8", - "community": 140, + "community": 231, "norm_label": "_create_memory()", "id": "tests_test_memory_dedup_create_memory" }, @@ -32564,7 +34868,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L12", - "community": 140, + "community": 231, "norm_label": "_count_memories()", "id": "tests_test_memory_dedup_count_memories" }, @@ -32573,7 +34877,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L20", - "community": 140, + "community": 231, "norm_label": "_get_memory()", "id": "tests_test_memory_dedup_get_memory" }, @@ -32591,7 +34895,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L29", - "community": 140, + "community": 231, "norm_label": ".test_exact_same_key_updates()", "id": "tests_test_memory_dedup_testexactsamekeyupdates_test_exact_same_key_updates" }, @@ -32609,7 +34913,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L37", - "community": 140, + "community": 231, "norm_label": ".test_similar_key_merges()", "id": "tests_test_memory_dedup_testsimilarkeymerges_test_similar_key_merges" }, @@ -32627,7 +34931,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L47", - "community": 140, + "community": 231, "norm_label": ".test_different_keys_no_merge()", "id": "tests_test_memory_dedup_testdifferentkeysnomerge_test_different_keys_no_merge" }, @@ -32645,7 +34949,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L56", - "community": 140, + "community": 231, "norm_label": ".test_merge_boosts_score()", "id": "tests_test_memory_dedup_testmergeboostsscore_test_merge_boosts_score" }, @@ -32663,7 +34967,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L65", - "community": 140, + "community": 231, "norm_label": ".test_merge_increments_access()", "id": "tests_test_memory_dedup_testmergeincrementsaccess_test_merge_increments_access" }, @@ -32681,7 +34985,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L74", - "community": 140, + "community": 231, "norm_label": ".test_threshold_boundary()", "id": "tests_test_memory_dedup_testthresholdboundary_test_threshold_boundary" }, @@ -32690,7 +34994,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L38", - "community": 140, + "community": 231, "norm_label": "keys with jaccard > 0.8 should merge.", "id": "tests_test_memory_dedup_rationale_38" }, @@ -32699,7 +35003,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L48", - "community": 140, + "community": 231, "norm_label": "keys with low similarity should not merge.", "id": "tests_test_memory_dedup_rationale_48" }, @@ -32708,7 +35012,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L75", - "community": 140, + "community": 231, "norm_label": "keys with jaccard <= 0.8 should not merge.", "id": "tests_test_memory_dedup_rationale_75" }, @@ -32744,7 +35048,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L46", - "community": 518, + "community": 95, "norm_label": "testdecay", "id": "tests_test_memory_maintenance_testdecay" }, @@ -32753,7 +35057,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L47", - "community": 518, + "community": 95, "norm_label": ".test_active_memory_decays()", "id": "tests_test_memory_maintenance_testdecay_test_active_memory_decays" }, @@ -32762,7 +35066,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L54", - "community": 518, + "community": 95, "norm_label": ".test_zero_access_count_still_decays()", "id": "tests_test_memory_maintenance_testdecay_test_zero_access_count_still_decays" }, @@ -32771,7 +35075,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L61", - "community": 518, + "community": 95, "norm_label": ".test_high_score_decays_proportionally()", "id": "tests_test_memory_maintenance_testdecay_test_high_score_decays_proportionally" }, @@ -32780,7 +35084,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L67", - "community": 518, + "community": 95, "norm_label": ".test_very_low_score_stays_above_zero()", "id": "tests_test_memory_maintenance_testdecay_test_very_low_score_stays_above_zero" }, @@ -32789,7 +35093,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L74", - "community": 518, + "community": 95, "norm_label": ".test_multiple_users_all_decayed()", "id": "tests_test_memory_maintenance_testdecay_test_multiple_users_all_decayed" }, @@ -32798,7 +35102,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L84", - "community": 140, + "community": 518, "norm_label": "testarchive", "id": "tests_test_memory_maintenance_testarchive" }, @@ -32807,7 +35111,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L85", - "community": 614, + "community": 518, "norm_label": ".test_dead_memory_archived()", "id": "tests_test_memory_maintenance_testarchive_test_dead_memory_archived" }, @@ -32816,7 +35120,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L92", - "community": 617, + "community": 518, "norm_label": ".test_low_score_but_recent_not_archived()", "id": "tests_test_memory_maintenance_testarchive_test_low_score_but_recent_not_archived" }, @@ -32834,7 +35138,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L106", - "community": 613, + "community": 518, "norm_label": ".test_accessed_memory_not_archived()", "id": "tests_test_memory_maintenance_testarchive_test_accessed_memory_not_archived" }, @@ -32861,7 +35165,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L133", - "community": 592, + "community": 518, "norm_label": "testdecayandarchivetogether", "id": "tests_test_memory_maintenance_testdecayandarchivetogether" }, @@ -32870,7 +35174,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L134", - "community": 592, + "community": 518, "norm_label": ".test_decay_then_archive_check()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_decay_then_archive_check" }, @@ -32879,7 +35183,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L143", - "community": 592, + "community": 518, "norm_label": ".test_score_above_threshold_after_decay_not_archived()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_score_above_threshold_after_decay_not_archived" }, @@ -32888,7 +35192,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L150", - "community": 592, + "community": 518, "norm_label": ".test_score_just_below_threshold_archived()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_score_just_below_threshold_archived" }, @@ -32897,7 +35201,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L156", - "community": 592, + "community": 518, "norm_label": ".test_days_just_below_threshold_not_archived()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_days_just_below_threshold_not_archived" }, @@ -32906,7 +35210,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L163", - "community": 592, + "community": 518, "norm_label": ".test_days_just_above_threshold_archived()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_days_just_above_threshold_archived" }, @@ -32924,7 +35228,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L171", - "community": 584, + "community": 95, "norm_label": ".test_no_memories_does_not_crash()", "id": "tests_test_memory_maintenance_testemptydatabase_test_no_memories_does_not_crash" }, @@ -32942,7 +35246,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L55", - "community": 518, + "community": 95, "norm_label": "decay applies to all active memories, not just accessed ones.", "id": "tests_test_memory_maintenance_rationale_55" }, @@ -32951,7 +35255,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L68", - "community": 518, + "community": 95, "norm_label": "basescore should never reach exactly 0 from decay alone.", "id": "tests_test_memory_maintenance_rationale_68" }, @@ -32960,7 +35264,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L86", - "community": 614, + "community": 518, "norm_label": "score below threshold + accesscount=0 + 90+ days \u2192 archived.", "id": "tests_test_memory_maintenance_rationale_86" }, @@ -32969,7 +35273,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L93", - "community": 617, + "community": 518, "norm_label": "low score but accessed recently \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_93" }, @@ -32987,7 +35291,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L107", - "community": 613, + "community": 518, "norm_label": "even with low score, if accessed \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_107" }, @@ -33005,7 +35309,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L135", - "community": 592, + "community": 518, "norm_label": "decay happens first, then archive check with new scores.", "id": "tests_test_memory_maintenance_rationale_135" }, @@ -33014,7 +35318,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L144", - "community": 592, + "community": 518, "norm_label": "score that decays to >= threshold stays alive. 0.12 * 0.90 = 0.108 >= 0.1.", "id": "tests_test_memory_maintenance_rationale_144" }, @@ -33023,7 +35327,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L157", - "community": 592, + "community": 518, "norm_label": "89 days with low score \u2192 not archived (need > 90).", "id": "tests_test_memory_maintenance_rationale_157" }, @@ -33104,7 +35408,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L40", - "community": 140, + "community": 636, "norm_label": ".test_unchanged()", "id": "tests_test_memory_manager_testupsertmemory_test_unchanged" }, @@ -33185,7 +35489,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L102", - "community": 140, + "community": 635, "norm_label": ".test_returns_memories()", "id": "tests_test_memory_manager_testgetusermemories_test_returns_memories" }, @@ -33275,7 +35579,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L23", - "community": 561, + "community": 590, "norm_label": "testmemorytoolfunctions", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions" }, @@ -33284,7 +35588,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L26", - "community": 561, + "community": 590, "norm_label": ".test_search_memory_has_docstring()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_search_memory_has_docstring" }, @@ -33293,7 +35597,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L30", - "community": 561, + "community": 590, "norm_label": ".test_save_memory_has_docstring()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_save_memory_has_docstring" }, @@ -33302,7 +35606,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L34", - "community": 561, + "community": 590, "norm_label": ".test_search_memory_signature()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_search_memory_signature" }, @@ -33311,7 +35615,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L39", - "community": 561, + "community": 590, "norm_label": ".test_save_memory_signature()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_save_memory_signature" }, @@ -33320,7 +35624,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L46", - "community": 561, + "community": 590, "norm_label": ".test_search_memory_has_type_hints()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_search_memory_has_type_hints" }, @@ -33329,7 +35633,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L50", - "community": 561, + "community": 590, "norm_label": ".test_save_memory_has_type_hints()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_save_memory_has_type_hints" }, @@ -33338,7 +35642,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L54", - "community": 561, + "community": 590, "norm_label": ".test_memory_tools_is_list_of_callables()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_memory_tools_is_list_of_callables" }, @@ -33347,7 +35651,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L60", - "community": 561, + "community": 502, "norm_label": ".test_memory_tool_names_unchanged()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_memory_tool_names_unchanged" }, @@ -33356,7 +35660,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L64", - "community": 615, + "community": 502, "norm_label": "testtoolregistry", "id": "tests_test_memory_tools_wiring_testtoolregistry" }, @@ -33365,7 +35669,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L67", - "community": 615, + "community": 502, "norm_label": ".test_registry_contains_memory_tools()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_contains_memory_tools" }, @@ -33374,7 +35678,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L71", - "community": 615, + "community": 502, "norm_label": ".test_registry_values_are_callable()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_values_are_callable" }, @@ -33383,7 +35687,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L75", - "community": 615, + "community": 502, "norm_label": ".test_registry_matches_tool_names()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_matches_tool_names" }, @@ -33392,7 +35696,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L79", - "community": 589, + "community": 628, "norm_label": "testmakechatincludesmemorytools", "id": "tests_test_memory_tools_wiring_testmakechatincludesmemorytools" }, @@ -33410,7 +35714,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L112", - "community": 529, + "community": 615, "norm_label": "testdispatchroutesmemorytools", "id": "tests_test_memory_tools_wiring_testdispatchroutesmemorytools" }, @@ -33455,7 +35759,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L24", - "community": 561, + "community": 590, "norm_label": "verify the actual async tool functions have correct signatures.", "id": "tests_test_memory_tools_wiring_rationale_24" }, @@ -33464,7 +35768,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L65", - "community": 615, + "community": 502, "norm_label": "tool_registry pattern must work correctly.", "id": "tests_test_memory_tools_wiring_rationale_65" }, @@ -33473,7 +35777,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L80", - "community": 589, + "community": 628, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_80" }, @@ -33482,7 +35786,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L113", - "community": 529, + "community": 615, "norm_label": "dispatchtoolcall must route memory tool names via tool_registry.", "id": "tests_test_memory_tools_wiring_rationale_113" }, @@ -33599,7 +35903,7 @@ "file_type": "code", "source_file": "tests/test_models.py", "source_location": "L1", - "community": 61, + "community": 125, "norm_label": "test_models.py", "id": "tests_test_models_py" }, @@ -33815,7 +36119,7 @@ "file_type": "code", "source_file": "tests/test_models.py", "source_location": "L162", - "community": 61, + "community": 125, "norm_label": "testprometheussessionmodel", "id": "tests_test_models_testprometheussessionmodel" }, @@ -33824,7 +36128,7 @@ "file_type": "code", "source_file": "tests/test_models.py", "source_location": "L163", - "community": 61, + "community": 125, "norm_label": ".test_create_session()", "id": "tests_test_models_testprometheussessionmodel_test_create_session" }, @@ -33833,7 +36137,7 @@ "file_type": "code", "source_file": "tests/test_models.py", "source_location": "L172", - "community": 61, + "community": 125, "norm_label": ".test_default_history()", "id": "tests_test_models_testprometheussessionmodel_test_default_history" }, @@ -34760,7 +37064,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L919", - "community": 58, + "community": 631, "norm_label": "test_get_google_sso_with_redirect()", "id": "tests_test_prometheus_auth_coverage_test_get_google_sso_with_redirect" }, @@ -34769,7 +37073,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L938", - "community": 58, + "community": 631, "norm_label": "test_get_google_sso_default_redirect()", "id": "tests_test_prometheus_auth_coverage_test_get_google_sso_default_redirect" }, @@ -34886,7 +37190,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L44", - "community": 530, + "community": 587, "norm_label": "testmemorytoolfunctions", "id": "tests_test_prometheus_tools_testmemorytoolfunctions" }, @@ -34895,7 +37199,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L45", - "community": 530, + "community": 587, "norm_label": ".test_search_memory_has_docstring()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_search_memory_has_docstring" }, @@ -34904,7 +37208,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L49", - "community": 530, + "community": 587, "norm_label": ".test_save_memory_has_docstring()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_save_memory_has_docstring" }, @@ -34913,7 +37217,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L53", - "community": 530, + "community": 587, "norm_label": ".test_search_memory_signature()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_search_memory_signature" }, @@ -34922,7 +37226,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L59", - "community": 530, + "community": 587, "norm_label": ".test_save_memory_signature()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_save_memory_signature" }, @@ -34931,7 +37235,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L66", - "community": 530, + "community": 587, "norm_label": ".test_search_memory_has_type_hints()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_search_memory_has_type_hints" }, @@ -34940,7 +37244,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L71", - "community": 530, + "community": 587, "norm_label": ".test_save_memory_has_type_hints()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_save_memory_has_type_hints" }, @@ -34949,7 +37253,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L77", - "community": 530, + "community": 587, "norm_label": ".test_memory_tools_is_list_of_callables()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_memory_tools_is_list_of_callables" }, @@ -34958,7 +37262,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L83", - "community": 530, + "community": 587, "norm_label": ".test_memory_tool_names_unchanged()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_memory_tool_names_unchanged" }, @@ -35048,7 +37352,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L126", - "community": 585, + "community": 630, "norm_label": "testgeminicompatibility", "id": "tests_test_prometheus_tools_testgeminicompatibility" }, @@ -35066,7 +37370,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L135", - "community": 585, + "community": 630, "norm_label": ".test_no_harnessstate_in_any_signature()", "id": "tests_test_prometheus_tools_testgeminicompatibility_test_no_harnessstate_in_any_signature" }, @@ -35075,7 +37379,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L151", - "community": 616, + "community": 633, "norm_label": "testtoolregistry", "id": "tests_test_prometheus_tools_testtoolregistry" }, @@ -35084,7 +37388,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L152", - "community": 616, + "community": 633, "norm_label": ".test_registry_contains_memory_tools()", "id": "tests_test_prometheus_tools_testtoolregistry_test_registry_contains_memory_tools" }, @@ -35093,7 +37397,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L156", - "community": 616, + "community": 633, "norm_label": ".test_registry_values_are_callable()", "id": "tests_test_prometheus_tools_testtoolregistry_test_registry_values_are_callable" }, @@ -35102,7 +37406,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L160", - "community": 616, + "community": 633, "norm_label": ".test_registry_matches_tool_names()", "id": "tests_test_prometheus_tools_testtoolregistry_test_registry_matches_tool_names" }, @@ -35120,7 +37424,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_tools.py", "source_location": "L127", - "community": 585, + "community": 630, "norm_label": "every function in tool_registry must have gemini-safe signatures. custom cl", "id": "tests_test_prometheus_tools_rationale_127" }, @@ -35129,7 +37433,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_tools.py", "source_location": "L136", - "community": 585, + "community": 630, "norm_label": "regression: harnessstate must never leak into tool signatures.", "id": "tests_test_prometheus_tools_rationale_136" }, @@ -35399,7 +37703,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L1", - "community": 511, + "community": 504, "norm_label": "test_request_id.py", "id": "tests_test_request_id_py" }, @@ -35408,7 +37712,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L14", - "community": 511, + "community": 504, "norm_label": "app()", "id": "tests_test_request_id_app" }, @@ -35417,7 +37721,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L30", - "community": 511, + "community": 504, "norm_label": "client()", "id": "tests_test_request_id_client" }, @@ -35426,7 +37730,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L34", - "community": 511, + "community": 504, "norm_label": "testrequestidmiddleware", "id": "tests_test_request_id_testrequestidmiddleware" }, @@ -35435,7 +37739,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L35", - "community": 511, + "community": 504, "norm_label": ".test_generates_uuid_when_no_header()", "id": "tests_test_request_id_testrequestidmiddleware_test_generates_uuid_when_no_header" }, @@ -35444,7 +37748,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L44", - "community": 511, + "community": 504, "norm_label": ".test_returns_generated_uuid_in_body()", "id": "tests_test_request_id_testrequestidmiddleware_test_returns_generated_uuid_in_body" }, @@ -35453,7 +37757,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L51", - "community": 511, + "community": 504, "norm_label": ".test_uses_client_provided_request_id()", "id": "tests_test_request_id_testrequestidmiddleware_test_uses_client_provided_request_id" }, @@ -35462,7 +37766,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L57", - "community": 511, + "community": 504, "norm_label": ".test_response_header_matches_request()", "id": "tests_test_request_id_testrequestidmiddleware_test_response_header_matches_request" }, @@ -35471,7 +37775,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L62", - "community": 511, + "community": 504, "norm_label": ".test_different_requests_get_different_ids()", "id": "tests_test_request_id_testrequestidmiddleware_test_different_requests_get_different_ids" }, @@ -35480,7 +37784,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L67", - "community": 511, + "community": 504, "norm_label": ".test_context_var_available_in_route()", "id": "tests_test_request_id_testrequestidmiddleware_test_context_var_available_in_route" }, @@ -35489,7 +37793,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L72", - "community": 511, + "community": 504, "norm_label": ".test_empty_x_request_id_header_generates_uuid()", "id": "tests_test_request_id_testrequestidmiddleware_test_empty_x_request_id_header_generates_uuid" }, @@ -35498,7 +37802,7 @@ "file_type": "code", "source_file": "tests/test_request_id.py", "source_location": "L81", - "community": 511, + "community": 504, "norm_label": ".test_middleware_preserves_response_body()", "id": "tests_test_request_id_testrequestidmiddleware_test_middleware_preserves_response_body" }, @@ -35831,7 +38135,7 @@ "file_type": "code", "source_file": "tests/test_roles_coverage.py", "source_location": "L83", - "community": 45, + "community": 491, "norm_label": "testpermissionall", "id": "tests_test_roles_coverage_testpermissionall" }, @@ -35840,7 +38144,7 @@ "file_type": "code", "source_file": "tests/test_roles_coverage.py", "source_location": "L84", - "community": 45, + "community": 491, "norm_label": ".test_all_includes_all_permissions()", "id": "tests_test_roles_coverage_testpermissionall_test_all_includes_all_permissions" }, @@ -36281,7 +38585,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L6", - "community": 576, + "community": 544, "norm_label": "testsandboxtooldefinitions", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions" }, @@ -36290,7 +38594,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L7", - "community": 576, + "community": 544, "norm_label": ".test_execute_code_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_execute_code_in_registry" }, @@ -36299,7 +38603,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L10", - "community": 576, + "community": 544, "norm_label": ".test_read_file_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_read_file_in_registry" }, @@ -36308,7 +38612,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L13", - "community": 576, + "community": 544, "norm_label": ".test_write_file_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_write_file_in_registry" }, @@ -36317,7 +38621,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L16", - "community": 576, + "community": 544, "norm_label": ".test_list_files_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_list_files_in_registry" }, @@ -36326,7 +38630,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L19", - "community": 576, + "community": 544, "norm_label": ".test_execute_code_has_docstring()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_execute_code_has_docstring" }, @@ -36758,7 +39062,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L1", - "community": 16, + "community": 521, "norm_label": "test_state_tools.py", "id": "tests_test_state_tools_py" }, @@ -36767,7 +39071,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L15", - "community": 601, + "community": 16, "norm_label": "teststatetoolfunctions", "id": "tests_test_state_tools_teststatetoolfunctions" }, @@ -36776,7 +39080,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L16", - "community": 601, + "community": 16, "norm_label": ".test_get_state_has_docstring()", "id": "tests_test_state_tools_teststatetoolfunctions_test_get_state_has_docstring" }, @@ -36785,7 +39089,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L20", - "community": 601, + "community": 16, "norm_label": ".test_set_state_has_docstring()", "id": "tests_test_state_tools_teststatetoolfunctions_test_set_state_has_docstring" }, @@ -36794,7 +39098,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L24", - "community": 601, + "community": 16, "norm_label": ".test_get_state_signature()", "id": "tests_test_state_tools_teststatetoolfunctions_test_get_state_signature" }, @@ -36803,7 +39107,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L31", - "community": 601, + "community": 16, "norm_label": ".test_set_state_signature()", "id": "tests_test_state_tools_teststatetoolfunctions_test_set_state_signature" }, @@ -36812,7 +39116,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L38", - "community": 601, + "community": 16, "norm_label": ".test_get_state_has_type_hints()", "id": "tests_test_state_tools_teststatetoolfunctions_test_get_state_has_type_hints" }, @@ -36821,7 +39125,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L44", - "community": 601, + "community": 16, "norm_label": ".test_set_state_has_type_hints()", "id": "tests_test_state_tools_teststatetoolfunctions_test_set_state_has_type_hints" }, @@ -36830,7 +39134,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L50", - "community": 601, + "community": 16, "norm_label": ".test_state_tools_in_registry()", "id": "tests_test_state_tools_teststatetoolfunctions_test_state_tools_in_registry" }, @@ -36839,7 +39143,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L56", - "community": 601, + "community": 16, "norm_label": ".test_registry_has_all_tools()", "id": "tests_test_state_tools_teststatetoolfunctions_test_registry_has_all_tools" }, @@ -36848,7 +39152,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L60", - "community": 16, + "community": 521, "norm_label": "testgetstate", "id": "tests_test_state_tools_testgetstate" }, @@ -36857,7 +39161,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L62", - "community": 16, + "community": 521, "norm_label": "test_get_state_specific_key()", "id": "tests_test_state_tools_test_get_state_specific_key" }, @@ -36866,7 +39170,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L69", - "community": 16, + "community": 521, "norm_label": "test_get_state_all()", "id": "tests_test_state_tools_test_get_state_all" }, @@ -36875,7 +39179,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L77", - "community": 16, + "community": 521, "norm_label": "test_get_state_missing_key()", "id": "tests_test_state_tools_test_get_state_missing_key" }, @@ -36884,7 +39188,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L83", - "community": 16, + "community": 521, "norm_label": "test_get_state_no_state()", "id": "tests_test_state_tools_test_get_state_no_state" }, @@ -36893,7 +39197,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L88", - "community": 16, + "community": 521, "norm_label": "testsetstate", "id": "tests_test_state_tools_testsetstate" }, @@ -36902,7 +39206,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L90", - "community": 16, + "community": 521, "norm_label": "test_set_state()", "id": "tests_test_state_tools_test_set_state" }, @@ -36911,7 +39215,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L97", - "community": 546, + "community": 221, "norm_label": "test_set_state_no_state()", "id": "tests_test_state_tools_test_set_state_no_state" }, @@ -36920,7 +39224,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L102", - "community": 16, + "community": 521, "norm_label": "teststatedispatch", "id": "tests_test_state_tools_teststatedispatch" }, @@ -36929,7 +39233,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L104", - "community": 16, + "community": 521, "norm_label": "test_dispatch_get_state()", "id": "tests_test_state_tools_test_dispatch_get_state" }, @@ -36938,7 +39242,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L114", - "community": 16, + "community": 521, "norm_label": "test_dispatch_set_state()", "id": "tests_test_state_tools_test_dispatch_set_state" }, @@ -37208,7 +39512,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L152", - "community": 603, + "community": 596, "norm_label": "testverifyapikey", "id": "tests_test_stocks_api_coverage_testverifyapikey" }, @@ -37487,7 +39791,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L451", - "community": 136, + "community": 162, "norm_label": ".test_deserialize_mixed_string_none_parses_json()", "id": "tests_test_stocks_api_coverage_testdeserializejsoncolumns_test_deserialize_mixed_string_none_parses_json" }, @@ -37505,7 +39809,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L498", - "community": 136, + "community": 162, "norm_label": "testfilterbysearchterms", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms" }, @@ -37514,7 +39818,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L501", - "community": 136, + "community": 162, "norm_label": "._make_manager()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_make_manager" }, @@ -37523,7 +39827,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L509", - "community": 136, + "community": 162, "norm_label": ".test_filter_empty_search_returns_all()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_empty_search_returns_all" }, @@ -37532,7 +39836,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L515", - "community": 136, + "community": 162, "norm_label": ".test_filter_ticker_index_hit()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_ticker_index_hit" }, @@ -37541,7 +39845,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L523", - "community": 136, + "community": 162, "norm_label": ".test_filter_multiple_terms_index()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_multiple_terms_index" }, @@ -37550,7 +39854,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L530", - "community": 136, + "community": 162, "norm_label": ".test_filter_no_index_match_fallback_to_str()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_no_index_match_fallback_to_str" }, @@ -37559,7 +39863,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L538", - "community": 136, + "community": 162, "norm_label": ".test_filter_fallback_multiple_terms()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_fallback_multiple_terms" }, @@ -37568,7 +39872,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L545", - "community": 136, + "community": 162, "norm_label": ".test_filter_case_insensitive()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_case_insensitive" }, @@ -37820,7 +40124,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L766", - "community": 17, + "community": 39, "norm_label": ".test_fundamental_with_invalid_date()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_with_invalid_date" }, @@ -37874,7 +40178,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L819", - "community": 17, + "community": 39, "norm_label": ".test_fundamental_empty_search_string_no_dedup()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_empty_search_string_no_dedup" }, @@ -37883,7 +40187,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L828", - "community": 17, + "community": 39, "norm_label": ".test_fundamental_no_time_column()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_no_time_column" }, @@ -37928,7 +40232,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L890", - "community": 39, + "community": 17, "norm_label": ".test_fundamental_search_fallback_string_match()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_search_fallback_string_match" }, @@ -38216,7 +40520,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1265", - "community": 588, + "community": 22, "norm_label": ".test_http_route_search_required()", "id": "tests_test_stocks_api_coverage_testquerylivecotation_test_http_route_search_required" }, @@ -38252,7 +40556,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1315", - "community": 606, + "community": 22, "norm_label": ".test_cotations_search_required()", "id": "tests_test_stocks_api_coverage_testquerylivecotation_test_cotations_search_required" }, @@ -38288,7 +40592,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L153", - "community": 603, + "community": 596, "norm_label": "tests covering key.py lines 15-40. uses asyncio.run() since pytest-asyncio", "id": "tests_test_stocks_api_coverage_rationale_153" }, @@ -38441,7 +40745,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L452", - "community": 136, + "community": 162, "norm_label": "regression: is_string_dtype fails when column has strings + none (pandas 2.x).", "id": "tests_test_stocks_api_coverage_rationale_452" }, @@ -38459,7 +40763,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L499", - "community": 136, + "community": 162, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_499" }, @@ -38558,7 +40862,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L767", - "community": 17, + "community": 39, "norm_label": "invalid date -> inner 400 passes through (not wrapped as 500).", "id": "tests_test_stocks_api_coverage_rationale_767" }, @@ -38567,7 +40871,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L820", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_820" }, @@ -38576,7 +40880,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L829", - "community": 17, + "community": 39, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_829" }, @@ -38621,7 +40925,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L891", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_891" }, @@ -38711,7 +41015,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1266", - "community": 588, + "community": 22, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1266" }, @@ -38720,7 +41024,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1316", - "community": 606, + "community": 22, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1316" }, @@ -39737,7 +42041,7 @@ "file_type": "code", "source_file": "tests/test_thread_safety.py", "source_location": "L21", - "community": 574, + "community": 184, "norm_label": "testgetsession", "id": "tests_test_thread_safety_testgetsession" }, @@ -39746,7 +42050,7 @@ "file_type": "code", "source_file": "tests/test_thread_safety.py", "source_location": "L24", - "community": 574, + "community": 184, "norm_label": ".test_same_session_within_same_thread()", "id": "tests_test_thread_safety_testgetsession_test_same_session_within_same_thread" }, @@ -39755,7 +42059,7 @@ "file_type": "code", "source_file": "tests/test_thread_safety.py", "source_location": "L32", - "community": 574, + "community": 184, "norm_label": ".test_different_sessions_in_different_threads()", "id": "tests_test_thread_safety_testgetsession_test_different_sessions_in_different_threads" }, @@ -39764,7 +42068,7 @@ "file_type": "code", "source_file": "tests/test_thread_safety.py", "source_location": "L52", - "community": 574, + "community": 184, "norm_label": ".test_isolation_under_high_concurrency()", "id": "tests_test_thread_safety_testgetsession_test_isolation_under_high_concurrency" }, @@ -39773,7 +42077,7 @@ "file_type": "code", "source_file": "tests/test_thread_safety.py", "source_location": "L73", - "community": 574, + "community": 184, "norm_label": ".test_session_is_requests_session()", "id": "tests_test_thread_safety_testgetsession_test_session_is_requests_session" }, @@ -39854,7 +42158,7 @@ "file_type": "rationale", "source_file": "tests/test_thread_safety.py", "source_location": "L22", - "community": 574, + "community": 184, "norm_label": "verify that getsession() returns per-thread session instances.", "id": "tests_test_thread_safety_rationale_22" }, @@ -39863,7 +42167,7 @@ "file_type": "rationale", "source_file": "tests/test_thread_safety.py", "source_location": "L25", - "community": 574, + "community": 184, "norm_label": "calling getsession() twice in the same thread returns the same object.", "id": "tests_test_thread_safety_rationale_25" }, @@ -39872,7 +42176,7 @@ "file_type": "rationale", "source_file": "tests/test_thread_safety.py", "source_location": "L33", - "community": 574, + "community": 184, "norm_label": "two threads must not share a session object.", "id": "tests_test_thread_safety_rationale_33" }, @@ -39881,7 +42185,7 @@ "file_type": "rationale", "source_file": "tests/test_thread_safety.py", "source_location": "L53", - "community": 574, + "community": 184, "norm_label": "with 20 concurrent threads, every thread must get its own session.", "id": "tests_test_thread_safety_rationale_53" }, @@ -39890,7 +42194,7 @@ "file_type": "rationale", "source_file": "tests/test_thread_safety.py", "source_location": "L74", - "community": 574, + "community": 184, "norm_label": "the returned object must be a real requests.session.", "id": "tests_test_thread_safety_rationale_74" }, @@ -39962,7 +42266,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L1", - "community": 584, + "community": 95, "norm_label": "test_type_aware_decay.py", "id": "tests_test_type_aware_decay_py" }, @@ -39971,7 +42275,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L11", - "community": 584, + "community": 95, "norm_label": "_create()", "id": "tests_test_type_aware_decay_create" }, @@ -39980,7 +42284,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L29", - "community": 584, + "community": 95, "norm_label": "testtypeawaredecay", "id": "tests_test_type_aware_decay_testtypeawaredecay" }, @@ -39989,7 +42293,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L30", - "community": 584, + "community": 95, "norm_label": ".test_preference_decays_slowly()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_preference_decays_slowly" }, @@ -39998,7 +42302,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L36", - "community": 584, + "community": 95, "norm_label": ".test_context_decays_fast()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_context_decays_fast" }, @@ -40007,7 +42311,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L42", - "community": 584, + "community": 95, "norm_label": ".test_analysis_decays_normally()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_analysis_decays_normally" }, @@ -40016,7 +42320,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L48", - "community": 584, + "community": 95, "norm_label": ".test_feedback_decays_medium()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_feedback_decays_medium" }, @@ -40025,7 +42329,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L54", - "community": 584, + "community": 95, "norm_label": ".test_unknown_type_uses_default()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_unknown_type_uses_default" }, @@ -40034,7 +42338,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L60", - "community": 584, + "community": 95, "norm_label": ".test_mixed_types_all_correct()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_mixed_types_all_correct" }, @@ -40043,7 +42347,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L76", - "community": 584, + "community": 95, "norm_label": ".test_preference_survives_longer()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_preference_survives_longer" }, @@ -40052,7 +42356,7 @@ "file_type": "rationale", "source_file": "tests/test_type_aware_decay.py", "source_location": "L77", - "community": 584, + "community": 95, "norm_label": "after 10 cycles, preference (0.99^10) > context (0.90^10).", "id": "tests_test_type_aware_decay_rationale_77" }, @@ -40061,7 +42365,7 @@ "file_type": "code", "source_file": "tests/test_user_deps.py", "source_location": "L1", - "community": 519, + "community": 98, "norm_label": "test_user_deps.py", "id": "tests_test_user_deps_py" }, @@ -40205,7 +42509,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L6", - "community": 72, + "community": 21, "norm_label": "testbatchcosinesimilarity", "id": "tests_test_vector_utils_testbatchcosinesimilarity" }, @@ -40214,7 +42518,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L7", - "community": 72, + "community": 21, "norm_label": ".test_empty_matrix()", "id": "tests_test_vector_utils_testbatchcosinesimilarity_test_empty_matrix" }, @@ -40223,7 +42527,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L11", - "community": 72, + "community": 21, "norm_label": ".test_single_row()", "id": "tests_test_vector_utils_testbatchcosinesimilarity_test_single_row" }, @@ -40232,7 +42536,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L17", - "community": 72, + "community": 21, "norm_label": ".test_multiple_rows()", "id": "tests_test_vector_utils_testbatchcosinesimilarity_test_multiple_rows" }, @@ -40241,7 +42545,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L32", - "community": 72, + "community": 21, "norm_label": ".test_zero_query()", "id": "tests_test_vector_utils_testbatchcosinesimilarity_test_zero_query" }, @@ -41618,7 +43922,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1083", - "community": 148, + "community": 498, "norm_label": "covers lines 114-115: session ownership check fails.", "id": "tests_test_controllers_coverage_rationale_1083" }, @@ -41627,7 +43931,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1120", - "community": 99, + "community": 148, "norm_label": "generic exception in chat propagates to fastapi's default 500 handler.", "id": "tests_test_controllers_coverage_rationale_1120" }, @@ -41636,7 +43940,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1138", - "community": 605, + "community": 604, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1138" }, @@ -41654,7 +43958,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1166", - "community": 14, + "community": 605, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1166" }, @@ -41699,7 +44003,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1223", - "community": 568, + "community": 620, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1223" }, @@ -41708,7 +44012,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1226", - "community": 568, + "community": 623, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1226" }, @@ -41717,7 +44021,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1243", - "community": 493, + "community": 625, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1243" }, @@ -41726,7 +44030,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1257", - "community": 568, + "community": 529, "norm_label": "covers lines 19-20: user not found raises 404.", "id": "tests_test_controllers_coverage_rationale_1257" }, @@ -41735,7 +44039,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1269", - "community": 493, + "community": 563, "norm_label": "covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: usermanager.getc", "id": "tests_test_controllers_coverage_rationale_1269" }, @@ -41744,7 +44048,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1301", - "community": 493, + "community": 568, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1301" }, @@ -41753,7 +44057,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1317", - "community": 493, + "community": 609, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1317" }, @@ -41762,7 +44066,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1334", - "community": 493, + "community": 614, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1334" }, @@ -41771,7 +44075,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1351", - "community": 493, + "community": 617, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1351" }, @@ -41789,7 +44093,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1385", - "community": 524, + "community": 546, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1385" }, @@ -41798,7 +44102,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1388", - "community": 524, + "community": 546, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1388" }, @@ -41807,7 +44111,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1404", - "community": 524, + "community": 592, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1404" }, @@ -41933,7 +44237,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L16", - "community": 152, + "community": 136, "norm_label": "search user's saved memories, preferences, and past analysis context. use", "id": "prometheus_tools_rationale_16" }, @@ -41942,7 +44246,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L42", - "community": 528, + "community": 503, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_42" }, @@ -41951,7 +44255,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L79", - "community": 16, + "community": 521, "norm_label": "retrieve values from the harness state. use this to recall intermediate results,", "id": "prometheus_tools_rationale_79" }, @@ -41960,7 +44264,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L147", - "community": 573, + "community": 588, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_147" }, @@ -41978,7 +44282,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L30", - "community": 140, + "community": 231, "norm_label": "keys with jaccard > 0.8 should merge.", "id": "tests_test_memory_dedup_rationale_30" }, @@ -41987,7 +44291,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L40", - "community": 140, + "community": 231, "norm_label": "keys with low similarity should not merge.", "id": "tests_test_memory_dedup_rationale_40" }, @@ -41996,7 +44300,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L67", - "community": 140, + "community": 231, "norm_label": "keys with jaccard <= 0.8 should not merge.", "id": "tests_test_memory_dedup_rationale_67" }, @@ -42266,7 +44570,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L131", - "community": 573, + "community": 588, "norm_label": "read a file from the sandbox filesystem. args: path: absolute pa", "id": "prometheus_tools_rationale_131" }, @@ -42464,7 +44768,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L130", - "community": 573, + "community": 588, "norm_label": "read a file from the sandbox filesystem. args: path: absolute pa", "id": "prometheus_tools_rationale_130" }, @@ -42473,7 +44777,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L7", - "community": 575, + "community": 528, "norm_label": "testagentsandboxintegration", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration" }, @@ -42482,7 +44786,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L8", - "community": 575, + "community": 528, "norm_label": ".test_build_system_prompt_includes_sandbox_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_includes_sandbox_instructions" }, @@ -42491,7 +44795,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L14", - "community": 575, + "community": 528, "norm_label": ".test_build_system_prompt_includes_state_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_includes_state_instructions" }, @@ -42500,7 +44804,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L19", - "community": 575, + "community": 528, "norm_label": ".test_build_system_prompt_with_state()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_with_state" }, @@ -42590,7 +44894,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L15", - "community": 152, + "community": 136, "norm_label": "search user's saved memories, preferences, and past analysis context. use", "id": "prometheus_tools_rationale_15" }, @@ -42599,7 +44903,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L41", - "community": 528, + "community": 503, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_41" }, @@ -42608,7 +44912,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L78", - "community": 16, + "community": 521, "norm_label": "retrieve values from the harness state. use this to recall intermediate results,", "id": "prometheus_tools_rationale_78" }, @@ -42617,7 +44921,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L93", - "community": 546, + "community": 221, "norm_label": "store a value in the harness state for this session. use this to save inter", "id": "prometheus_tools_rationale_93" }, @@ -44813,7 +47117,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L119", - "community": 546, + "community": 221, "norm_label": "test_set_state_no_state_returns_error()", "id": "tests_test_prometheus_tools_test_set_state_no_state_returns_error" }, @@ -44831,7 +47135,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_tools.py", "source_location": "L128", - "community": 585, + "community": 630, "norm_label": "every function in tool_registry must have gemini-safe signatures. custom cl", "id": "tests_test_prometheus_tools_rationale_128" }, @@ -44840,7 +47144,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_tools.py", "source_location": "L137", - "community": 585, + "community": 630, "norm_label": "regression: harnessstate must never leak into tool signatures.", "id": "tests_test_prometheus_tools_rationale_137" }, @@ -44849,7 +47153,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L1", - "community": 105, + "community": 135, "norm_label": "cache.py", "id": "main_app_prometheus_cache_py" }, @@ -44858,7 +47162,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L7", - "community": 105, + "community": 135, "norm_label": "resultcache", "id": "prometheus_cache_resultcache" }, @@ -44867,7 +47171,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L8", - "community": 105, + "community": 135, "norm_label": ".__init__()", "id": "prometheus_cache_resultcache_init" }, @@ -44876,7 +47180,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L11", - "community": 105, + "community": 135, "norm_label": ".cachepath()", "id": "prometheus_cache_resultcache_cachepath" }, @@ -44885,7 +47189,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L15", - "community": 105, + "community": 135, "norm_label": ".get()", "id": "prometheus_cache_resultcache_get" }, @@ -44894,7 +47198,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L21", - "community": 105, + "community": 135, "norm_label": ".set()", "id": "prometheus_cache_resultcache_set" }, @@ -44903,7 +47207,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L31", - "community": 105, + "community": 135, "norm_label": ".invalidate()", "id": "prometheus_cache_resultcache_invalidate" }, @@ -44912,7 +47216,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L38", - "community": 105, + "community": 135, "norm_label": ".exists()", "id": "prometheus_cache_resultcache_exists" }, @@ -44957,7 +47261,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L139", - "community": 571, + "community": 576, "norm_label": "read_sandbox_file()", "id": "prometheus_tools_read_sandbox_file" }, @@ -44966,7 +47270,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L151", - "community": 571, + "community": 576, "norm_label": "upload_to_sandbox()", "id": "prometheus_tools_upload_to_sandbox" }, @@ -44975,7 +47279,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L165", - "community": 571, + "community": 576, "norm_label": "check_cache()", "id": "prometheus_tools_check_cache" }, @@ -44984,7 +47288,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L17", - "community": 152, + "community": 136, "norm_label": "search user's saved memories, preferences, and past analysis context. use", "id": "prometheus_tools_rationale_17" }, @@ -44993,7 +47297,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L109", - "community": 546, + "community": 221, "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", "id": "prometheus_tools_rationale_109" }, @@ -45002,7 +47306,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L140", - "community": 571, + "community": 576, "norm_label": "read a file from the sandbox filesystem. args: path: absolute pa", "id": "prometheus_tools_rationale_140" }, @@ -45011,7 +47315,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L152", - "community": 571, + "community": 576, "norm_label": "upload a file to the sandbox filesystem. use this to push data files (csv,", "id": "prometheus_tools_rationale_152" }, @@ -45020,7 +47324,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L166", - "community": 571, + "community": 576, "norm_label": "check if a computed result exists in the cache. use before executing expens", "id": "prometheus_tools_rationale_166" }, @@ -45029,7 +47333,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L9", - "community": 575, + "community": 528, "norm_label": ".test_build_system_prompt_no_state()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_no_state" }, @@ -45038,7 +47342,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L20", - "community": 575, + "community": 528, "norm_label": ".test_build_system_prompt_empty_state()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_empty_state" }, @@ -45047,7 +47351,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L25", - "community": 575, + "community": 528, "norm_label": ".test_system_prompt_includes_state_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_system_prompt_includes_state_instructions" }, @@ -45056,7 +47360,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L30", - "community": 575, + "community": 528, "norm_label": ".test_system_prompt_includes_sandbox_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_system_prompt_includes_sandbox_instructions" }, @@ -45065,7 +47369,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L34", - "community": 575, + "community": 528, "norm_label": ".test_system_prompt_includes_cache_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_system_prompt_includes_cache_instructions" }, @@ -45074,7 +47378,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L38", - "community": 575, + "community": 528, "norm_label": ".test_makechat_uses_tool_registry()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_makechat_uses_tool_registry" }, @@ -45245,7 +47549,7 @@ "file_type": "code", "source_file": "tests/test_config_sandbox.py", "source_location": "L1", - "community": 586, + "community": 102, "norm_label": "test_config_sandbox.py", "id": "tests_test_config_sandbox_py" }, @@ -45254,7 +47558,7 @@ "file_type": "code", "source_file": "tests/test_config_sandbox.py", "source_location": "L5", - "community": 586, + "community": 102, "norm_label": "testsandboxconfig", "id": "tests_test_config_sandbox_testsandboxconfig" }, @@ -45263,7 +47567,7 @@ "file_type": "code", "source_file": "tests/test_config_sandbox.py", "source_location": "L6", - "community": 586, + "community": 102, "norm_label": ".test_sandbox_defaults()", "id": "tests_test_config_sandbox_testsandboxconfig_test_sandbox_defaults" }, @@ -45272,7 +47576,7 @@ "file_type": "code", "source_file": "tests/test_config_sandbox.py", "source_location": "L13", - "community": 586, + "community": 102, "norm_label": ".test_sandbox_fields_exist()", "id": "tests_test_config_sandbox_testsandboxconfig_test_sandbox_fields_exist" }, @@ -45281,7 +47585,7 @@ "file_type": "code", "source_file": "tests/test_config_sandbox.py", "source_location": "L21", - "community": 586, + "community": 102, "norm_label": ".test_sandbox_types()", "id": "tests_test_config_sandbox_testsandboxconfig_test_sandbox_types" }, @@ -45542,7 +47846,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L12", - "community": 576, + "community": 544, "norm_label": ".test_read_sandbox_file_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_read_sandbox_file_in_registry" }, @@ -45551,7 +47855,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L15", - "community": 576, + "community": 544, "norm_label": ".test_check_cache_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_check_cache_in_registry" }, @@ -45560,7 +47864,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L23", - "community": 576, + "community": 544, "norm_label": ".test_read_sandbox_file_has_docstring()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_read_sandbox_file_has_docstring" }, @@ -45569,7 +47873,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L28", - "community": 576, + "community": 544, "norm_label": ".test_check_cache_has_docstring()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_check_cache_has_docstring" }, @@ -45902,7 +48206,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L19", - "community": 105, + "community": 135, "norm_label": "._cache_path()", "id": "prometheus_cache_resultcache_cache_path" }, @@ -45911,7 +48215,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L1", - "community": 105, + "community": 135, "norm_label": "resultcache \u2014 sha256-keyed file-based cache for computed results.", "id": "prometheus_cache_rationale_1" }, @@ -45920,7 +48224,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L10", - "community": 105, + "community": 135, "norm_label": "file-based cache keyed by sha256 of code. stores results as json under:", "id": "prometheus_cache_rationale_10" }, @@ -45929,7 +48233,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L24", - "community": 105, + "community": 135, "norm_label": "return cached result dict or none if miss.", "id": "prometheus_cache_rationale_24" }, @@ -45938,7 +48242,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L31", - "community": 105, + "community": 135, "norm_label": "store result with timestamp.", "id": "prometheus_cache_rationale_31" }, @@ -45947,7 +48251,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L42", - "community": 105, + "community": 135, "norm_label": "delete all cached results for a session.", "id": "prometheus_cache_rationale_42" }, @@ -45956,7 +48260,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L50", - "community": 105, + "community": 135, "norm_label": "check if a result exists for the given code.", "id": "prometheus_cache_rationale_50" }, @@ -46298,7 +48602,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L77", - "community": 16, + "community": 521, "norm_label": "retrieve values from the harness state. use this to recall intermediate results,", "id": "prometheus_tools_rationale_77" }, @@ -46361,7 +48665,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L104", - "community": 16, + "community": 521, "norm_label": "executestatetool()", "id": "prometheus_tools_executestatetool" }, @@ -46370,7 +48674,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L13", - "community": 152, + "community": 136, "norm_label": "search user's saved memories, preferences, and past analysis context. use t", "id": "prometheus_tools_rationale_13" }, @@ -46379,7 +48683,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L39", - "community": 528, + "community": 503, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_39" }, @@ -46388,7 +48692,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L44", - "community": 601, + "community": 16, "norm_label": ".test_state_tools_is_list_of_callables()", "id": "tests_test_state_tools_teststatetoolfunctions_test_state_tools_is_list_of_callables" }, @@ -46397,7 +48701,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L50", - "community": 601, + "community": 16, "norm_label": ".test_state_tool_names()", "id": "tests_test_state_tools_teststatetoolfunctions_test_state_tool_names" }, @@ -46406,7 +48710,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L54", - "community": 16, + "community": 521, "norm_label": "testexecutestatetool", "id": "tests_test_state_tools_testexecutestatetool" }, @@ -46415,7 +48719,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L84", - "community": 16, + "community": 521, "norm_label": "test_unknown_tool()", "id": "tests_test_state_tools_test_unknown_tool" }, @@ -46442,7 +48746,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/state.py", "source_location": "L22", - "community": 63, + "community": 502, "norm_label": "store a value in state. marks state as changed for context injection.", "id": "prometheus_state_rationale_22" }, @@ -46496,7 +48800,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L12", - "community": 152, + "community": 136, "norm_label": "search user's saved memories, preferences, and past analysis context. use t", "id": "prometheus_tools_rationale_12" }, @@ -46505,7 +48809,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L38", - "community": 528, + "community": 503, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_38" }, @@ -46559,7 +48863,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L46", - "community": 602, + "community": 84, "norm_label": "executememorytool()", "id": "prometheus_tools_executememorytool" }, @@ -46568,7 +48872,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L29", - "community": 528, + "community": 503, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_29" }, @@ -46577,7 +48881,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L52", - "community": 140, + "community": 231, "norm_label": "keys with low similarity should not merge.", "id": "tests_test_memory_dedup_rationale_52" }, @@ -46586,7 +48890,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L85", - "community": 140, + "community": 231, "norm_label": "keys with jaccard <= 0.8 should not merge.", "id": "tests_test_memory_dedup_rationale_85" }, @@ -46703,7 +49007,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L52", - "community": 589, + "community": 628, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_52" }, @@ -46712,7 +49016,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L89", - "community": 529, + "community": 615, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_89" }, @@ -46739,7 +49043,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L57", - "community": 589, + "community": 628, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_57" }, @@ -46748,7 +49052,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L92", - "community": 529, + "community": 615, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_92" }, @@ -46757,7 +49061,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L17", - "community": 53, + "community": 222, "norm_label": "_normalize_key()", "id": "prometheus_memory_normalize_key" }, @@ -46775,7 +49079,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L54", - "community": 518, + "community": 95, "norm_label": "decay applies to all active memories, not just accessed ones.", "id": "tests_test_memory_maintenance_rationale_54" }, @@ -46784,7 +49088,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L67", - "community": 518, + "community": 95, "norm_label": "basescore should never reach exactly 0 from decay alone.", "id": "tests_test_memory_maintenance_rationale_67" }, @@ -46793,7 +49097,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L85", - "community": 614, + "community": 518, "norm_label": "score below threshold + accesscount=0 + 90+ days \u2192 archived.", "id": "tests_test_memory_maintenance_rationale_85" }, @@ -46802,7 +49106,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L92", - "community": 617, + "community": 518, "norm_label": "low score but accessed recently \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_92" }, @@ -46820,7 +49124,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L106", - "community": 613, + "community": 518, "norm_label": "even with low score, if accessed \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_106" }, @@ -46838,7 +49142,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L134", - "community": 592, + "community": 518, "norm_label": "decay happens first, then archive check with new scores.", "id": "tests_test_memory_maintenance_rationale_134" }, @@ -46847,7 +49151,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L143", - "community": 592, + "community": 518, "norm_label": "score that decays to >= threshold stays alive. 0.11 * 0.95 = 0.1045 >= 0.1.", "id": "tests_test_memory_maintenance_rationale_143" }, @@ -46856,7 +49160,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L156", - "community": 592, + "community": 518, "norm_label": "89 days with low score \u2192 not archived (need > 90).", "id": "tests_test_memory_maintenance_rationale_156" }, @@ -46865,7 +49169,7 @@ "file_type": "code", "source_file": "main/utils/models/loader.py", "source_location": "L23", - "community": 602, + "community": 84, "norm_label": "embed()", "id": "models_loader_embed" }, @@ -47045,7 +49349,7 @@ "file_type": "code", "source_file": "main/utils/models/loader.py", "source_location": "L11", - "community": 602, + "community": 536, "norm_label": "_downloadmodel()", "id": "models_loader_downloadmodel" }, @@ -47162,7 +49466,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1258", - "community": 568, + "community": 529, "norm_label": "covers lines 19-20: user not found raises 404.", "id": "tests_test_controllers_coverage_rationale_1258" }, @@ -47171,7 +49475,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1270", - "community": 493, + "community": 563, "norm_label": "covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: usermanager.getc", "id": "tests_test_controllers_coverage_rationale_1270" }, @@ -47180,7 +49484,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1277", - "community": 493, + "community": 620, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1277" }, @@ -47189,7 +49493,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1302", - "community": 493, + "community": 568, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1302" }, @@ -47198,7 +49502,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1318", - "community": 493, + "community": 609, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1318" }, @@ -47207,7 +49511,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1335", - "community": 493, + "community": 614, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1335" }, @@ -47216,7 +49520,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1352", - "community": 493, + "community": 617, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1352" }, @@ -47234,7 +49538,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1386", - "community": 524, + "community": 546, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1386" }, @@ -47243,7 +49547,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1389", - "community": 493, + "community": 614, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1389" }, @@ -47252,7 +49556,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1405", - "community": 524, + "community": 592, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1405" }, @@ -47504,7 +49808,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L56", - "community": 589, + "community": 628, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_56" }, @@ -47513,7 +49817,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L91", - "community": 529, + "community": 615, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_91" }, @@ -47522,7 +49826,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L1", - "community": 72, + "community": 131, "norm_label": "vector.py", "id": "main_utils_vector_py" }, @@ -47531,7 +49835,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L8", - "community": 72, + "community": 21, "norm_label": "batchcosinesimilarity()", "id": "utils_vector_batchcosinesimilarity" }, @@ -47837,7 +50141,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L48", - "community": 589, + "community": 628, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_48" }, @@ -47846,7 +50150,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L76", - "community": 529, + "community": 615, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_76" }, @@ -47900,7 +50204,7 @@ "file_type": "code", "source_file": "main/app/prometheus/agent.py", "source_location": "L91", - "community": 602, + "community": 116, "norm_label": "executememorytool()", "id": "prometheus_agent_executememorytool" }, @@ -47936,7 +50240,7 @@ "file_type": "code", "source_file": "main/controller/prometheus_controller.py", "source_location": "L177", - "community": 602, + "community": 84, "norm_label": "creatememory()", "id": "controller_prometheus_controller_creatememory" }, @@ -47954,7 +50258,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L1", - "community": 474, + "community": 493, "norm_label": "test_memory_controller.py", "id": "tests_test_memory_controller_py" }, @@ -47963,7 +50267,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L10", - "community": 67, + "community": 493, "norm_label": "testmemorycontrollerroutes", "id": "tests_test_memory_controller_testmemorycontrollerroutes" }, @@ -47972,7 +50276,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L11", - "community": 67, + "community": 493, "norm_label": ".test_get_memories_endpoint_exists()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_get_memories_endpoint_exists" }, @@ -47981,7 +50285,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L15", - "community": 67, + "community": 493, "norm_label": ".test_post_memories_endpoint_exists()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_post_memories_endpoint_exists" }, @@ -47990,7 +50294,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L19", - "community": 67, + "community": 493, "norm_label": ".test_delete_memories_endpoint_exists()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_delete_memories_endpoint_exists" }, @@ -47999,7 +50303,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L23", - "community": 67, + "community": 493, "norm_label": ".test_get_memories_rejects_unauthenticated()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_get_memories_rejects_unauthenticated" }, @@ -48008,7 +50312,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L38", - "community": 67, + "community": 498, "norm_label": ".test_get_memories_rejects_basic_user()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_get_memories_rejects_basic_user" }, @@ -48017,7 +50321,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L65", - "community": 474, + "community": 493, "norm_label": "testmemoryendpointsintegration", "id": "tests_test_memory_controller_testmemoryendpointsintegration" }, @@ -48026,7 +50330,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L67", - "community": 474, + "community": 493, "norm_label": "test_get_memories_calls_manager()", "id": "tests_test_memory_controller_test_get_memories_calls_manager" }, @@ -48035,7 +50339,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L90", - "community": 474, + "community": 493, "norm_label": "test_create_memory_calls_manager()", "id": "tests_test_memory_controller_test_create_memory_calls_manager" }, @@ -48044,7 +50348,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L111", - "community": 474, + "community": 493, "norm_label": "test_create_memory_limit_reached()", "id": "tests_test_memory_controller_test_create_memory_limit_reached" }, @@ -48053,7 +50357,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L126", - "community": 474, + "community": 493, "norm_label": "test_delete_memory_calls_manager()", "id": "tests_test_memory_controller_test_delete_memory_calls_manager" }, @@ -48062,7 +50366,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L135", - "community": 474, + "community": 493, "norm_label": "test_delete_memory_not_found()", "id": "tests_test_memory_controller_test_delete_memory_not_found" }, @@ -48071,7 +50375,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L141", - "community": 474, + "community": 493, "norm_label": ".test_create_memory_missing_key()", "id": "tests_test_memory_controller_testmemoryendpointsintegration_test_create_memory_missing_key" }, @@ -48080,7 +50384,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L145", - "community": 474, + "community": 493, "norm_label": ".test_create_memory_missing_value()", "id": "tests_test_memory_controller_testmemoryendpointsintegration_test_create_memory_missing_value" }, @@ -48098,7 +50402,7 @@ "file_type": "rationale", "source_file": "main/utils/vector.py", "source_location": "L6", - "community": 72, + "community": 131, "norm_label": "vectorized cosine similarity: one query against n embeddings.", "id": "utils_vector_rationale_6" }, @@ -48620,7 +50924,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L138", - "community": 104, + "community": 53, "norm_label": "_fulltext_search()", "id": "prometheus_memory_fulltext_search" }, @@ -48746,7 +51050,7 @@ "file_type": "code", "source_file": "main/controller/prometheus_controller.py", "source_location": "L177", - "community": 602, + "community": 84, "norm_label": "create_memory()", "id": "controller_prometheus_controller_create_memory" }, @@ -48764,7 +51068,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L5", - "community": 72, + "community": 131, "norm_label": "pack_vector()", "id": "utils_vector_pack_vector" }, @@ -48773,7 +51077,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L11", - "community": 72, + "community": 131, "norm_label": "unpack_vector()", "id": "utils_vector_unpack_vector" }, @@ -48791,7 +51095,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L28", - "community": 72, + "community": 21, "norm_label": "batch_cosine_similarity()", "id": "utils_vector_batch_cosine_similarity" }, @@ -48809,7 +51113,7 @@ "file_type": "rationale", "source_file": "main/utils/vector.py", "source_location": "L12", - "community": 72, + "community": 131, "norm_label": "unpack mysql blob to float list.", "id": "utils_vector_rationale_12" }, @@ -48827,7 +51131,7 @@ "file_type": "rationale", "source_file": "main/utils/vector.py", "source_location": "L29", - "community": 72, + "community": 21, "norm_label": "vectorized cosine similarity: one query against n embeddings.", "id": "utils_vector_rationale_29" }, @@ -48845,7 +51149,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L11", - "community": 67, + "community": 493, "norm_label": "verify memory endpoints exist and are wired correctly.", "id": "tests_test_memory_controller_rationale_11" }, @@ -48854,7 +51158,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L14", - "community": 67, + "community": 493, "norm_label": "get /prometheus/memories exists.", "id": "tests_test_memory_controller_rationale_14" }, @@ -48863,7 +51167,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L20", - "community": 67, + "community": 493, "norm_label": "post /prometheus/memories exists.", "id": "tests_test_memory_controller_rationale_20" }, @@ -48872,7 +51176,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L25", - "community": 67, + "community": 493, "norm_label": "delete /prometheus/memories/{id} exists.", "id": "tests_test_memory_controller_rationale_25" }, @@ -48881,7 +51185,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L30", - "community": 67, + "community": 493, "norm_label": "get /memories requires authentication.", "id": "tests_test_memory_controller_rationale_30" }, @@ -48890,7 +51194,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L47", - "community": 67, + "community": 498, "norm_label": "get /memories requires use_prometheus (basic user role denied).", "id": "tests_test_memory_controller_rationale_47" }, @@ -48899,7 +51203,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L75", - "community": 474, + "community": 493, "norm_label": "full integration tests using mocked memorymanager.", "id": "tests_test_memory_controller_rationale_75" }, @@ -48953,7 +51257,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L141", - "community": 474, + "community": 493, "norm_label": "post /memories rejects missing key.", "id": "tests_test_memory_controller_rationale_141" }, @@ -48962,7 +51266,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L146", - "community": 474, + "community": 493, "norm_label": "post /memories rejects missing value.", "id": "tests_test_memory_controller_rationale_146" }, @@ -49016,7 +51320,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L43", - "community": 140, + "community": 636, "norm_label": "returns unchanged when value is identical.", "id": "tests_test_memory_manager_rationale_43" }, @@ -49070,7 +51374,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L107", - "community": 140, + "community": 635, "norm_label": "returns paginated memories.", "id": "tests_test_memory_manager_rationale_107" }, @@ -49133,7 +51437,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L11", - "community": 72, + "community": 131, "norm_label": "testpackunpack", "id": "tests_test_vector_utils_testpackunpack" }, @@ -49142,7 +51446,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L12", - "community": 72, + "community": 131, "norm_label": ".test_roundtrip()", "id": "tests_test_vector_utils_testpackunpack_test_roundtrip" }, @@ -49151,7 +51455,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L20", - "community": 72, + "community": 131, "norm_label": ".test_empty()", "id": "tests_test_vector_utils_testpackunpack_test_empty" }, @@ -49160,7 +51464,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L26", - "community": 72, + "community": 131, "norm_label": ".test_384_dims()", "id": "tests_test_vector_utils_testpackunpack_test_384_dims" }, @@ -49223,7 +51527,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L13", - "community": 72, + "community": 131, "norm_label": "pack \u2192 unpack preserves values.", "id": "tests_test_vector_utils_rationale_13" }, @@ -49232,7 +51536,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L21", - "community": 72, + "community": 131, "norm_label": "empty list roundtrips.", "id": "tests_test_vector_utils_rationale_21" }, @@ -49241,7 +51545,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L27", - "community": 72, + "community": 131, "norm_label": "384-dim vector packs to 1536 bytes.", "id": "tests_test_vector_utils_rationale_27" }, @@ -49295,7 +51599,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L68", - "community": 72, + "community": 21, "norm_label": "empty matrix \u2192 empty array.", "id": "tests_test_vector_utils_rationale_68" }, @@ -49304,7 +51608,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L73", - "community": 72, + "community": 21, "norm_label": "single row matches cosine_similarity.", "id": "tests_test_vector_utils_rationale_73" }, @@ -49313,7 +51617,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L80", - "community": 72, + "community": 21, "norm_label": "multiple rows ranked correctly.", "id": "tests_test_vector_utils_rationale_80" }, @@ -49322,7 +51626,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L93", - "community": 72, + "community": 21, "norm_label": "zero query \u2192 all zeros.", "id": "tests_test_vector_utils_rationale_93" }, @@ -50330,7 +52634,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L13", - "community": 251, + "community": 561, "norm_label": "set required env vars before test collection. config.py eagerly instantia", "id": "tests_conftest_rationale_13" }, @@ -50339,7 +52643,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L74", - "community": 535, + "community": 561, "norm_label": "testclient with stocks router + verifyapikey + getcurrentuser overrides.", "id": "tests_conftest_rationale_74" }, @@ -50348,7 +52652,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L99", - "community": 535, + "community": 561, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_99" }, @@ -50447,7 +52751,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L724", - "community": 120, + "community": 498, "norm_label": "covers lines 126-136: delete /user/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_724" }, @@ -50456,7 +52760,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L727", - "community": 120, + "community": 498, "norm_label": "covers lines 126, 131, 135-136.", "id": "tests_test_controllers_coverage_rationale_727" }, @@ -50465,7 +52769,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L754", - "community": 120, + "community": 498, "norm_label": "covers lines 127-129: session not found.", "id": "tests_test_controllers_coverage_rationale_754" }, @@ -50474,7 +52778,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L776", - "community": 120, + "community": 498, "norm_label": "covers lines 132-133: revokesession returns false.", "id": "tests_test_controllers_coverage_rationale_776" }, @@ -50483,7 +52787,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L802", - "community": 221, + "community": 616, "norm_label": "covers lines 143, 145, 147-148: post /user/sessions/revoke-all.", "id": "tests_test_controllers_coverage_rationale_802" }, @@ -50492,7 +52796,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L805", - "community": 221, + "community": 616, "norm_label": "covers lines 143, 145, 147-148.", "id": "tests_test_controllers_coverage_rationale_805" }, @@ -50501,7 +52805,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L832", - "community": 45, + "community": 626, "norm_label": "covers line 24: get /prometheus/health.", "id": "tests_test_controllers_coverage_rationale_832" }, @@ -50591,7 +52895,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L994", - "community": 99, + "community": 535, "norm_label": "covers lines 95-98: delete /prometheus/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_994" }, @@ -50600,7 +52904,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L997", - "community": 99, + "community": 535, "norm_label": "covers lines 95-98: session deleted.", "id": "tests_test_controllers_coverage_rationale_997" }, @@ -50609,7 +52913,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1007", - "community": 99, + "community": 535, "norm_label": "covers lines 96-97: session not found.", "id": "tests_test_controllers_coverage_rationale_1007" }, @@ -50645,7 +52949,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1079", - "community": 148, + "community": 498, "norm_label": "covers lines 114-115: session ownership check fails.", "id": "tests_test_controllers_coverage_rationale_1079" }, @@ -50654,7 +52958,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1116", - "community": 99, + "community": 148, "norm_label": "generic exception in chat propagates to fastapi's default 500 handler.", "id": "tests_test_controllers_coverage_rationale_1116" }, @@ -50663,7 +52967,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1134", - "community": 605, + "community": 604, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1134" }, @@ -50681,7 +52985,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1162", - "community": 14, + "community": 605, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1162" }, @@ -50726,7 +53030,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1219", - "community": 568, + "community": 620, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1219" }, @@ -50735,7 +53039,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1222", - "community": 568, + "community": 623, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1222" }, @@ -50744,7 +53048,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1239", - "community": 493, + "community": 625, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1239" }, @@ -50753,7 +53057,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1254", - "community": 568, + "community": 529, "norm_label": "covers lines 19-20: user not found raises 404.", "id": "tests_test_controllers_coverage_rationale_1254" }, @@ -50762,7 +53066,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1266", - "community": 493, + "community": 563, "norm_label": "covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: usermanager.getc", "id": "tests_test_controllers_coverage_rationale_1266" }, @@ -50771,7 +53075,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1273", - "community": 493, + "community": 563, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1273" }, @@ -50780,7 +53084,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1298", - "community": 493, + "community": 568, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1298" }, @@ -50789,7 +53093,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1314", - "community": 493, + "community": 609, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1314" }, @@ -50798,7 +53102,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1331", - "community": 493, + "community": 614, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1331" }, @@ -50807,7 +53111,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1348", - "community": 493, + "community": 617, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1348" }, @@ -50816,7 +53120,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1372", - "community": 45, + "community": 609, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1372" }, @@ -50825,7 +53129,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1401", - "community": 524, + "community": 592, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1401" }, @@ -51059,7 +53363,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L722", - "community": 120, + "community": 498, "norm_label": "covers lines 126-136: delete /user/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_722" }, @@ -51068,7 +53372,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L725", - "community": 120, + "community": 498, "norm_label": "covers lines 126, 131, 135-136.", "id": "tests_test_controllers_coverage_rationale_725" }, @@ -51077,7 +53381,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L752", - "community": 120, + "community": 498, "norm_label": "covers lines 127-129: session not found.", "id": "tests_test_controllers_coverage_rationale_752" }, @@ -51086,7 +53390,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L774", - "community": 120, + "community": 498, "norm_label": "covers lines 132-133: revokesession returns false.", "id": "tests_test_controllers_coverage_rationale_774" }, @@ -51095,7 +53399,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L800", - "community": 221, + "community": 616, "norm_label": "covers lines 143, 145, 147-148: post /user/sessions/revoke-all.", "id": "tests_test_controllers_coverage_rationale_800" }, @@ -51104,7 +53408,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L803", - "community": 221, + "community": 616, "norm_label": "covers lines 143, 145, 147-148.", "id": "tests_test_controllers_coverage_rationale_803" }, @@ -51113,7 +53417,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L830", - "community": 45, + "community": 626, "norm_label": "covers line 24: get /prometheus/health.", "id": "tests_test_controllers_coverage_rationale_830" }, @@ -51203,7 +53507,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L992", - "community": 99, + "community": 535, "norm_label": "covers lines 95-98: delete /prometheus/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_992" }, @@ -51212,7 +53516,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L995", - "community": 99, + "community": 535, "norm_label": "covers lines 95-98: session deleted.", "id": "tests_test_controllers_coverage_rationale_995" }, @@ -51221,7 +53525,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1005", - "community": 99, + "community": 535, "norm_label": "covers lines 96-97: session not found.", "id": "tests_test_controllers_coverage_rationale_1005" }, @@ -51257,7 +53561,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1078", - "community": 148, + "community": 498, "norm_label": "covers lines 114-115: session ownership check fails.", "id": "tests_test_controllers_coverage_rationale_1078" }, @@ -51266,7 +53570,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1115", - "community": 99, + "community": 148, "norm_label": "generic exception in chat propagates to fastapi's default 500 handler.", "id": "tests_test_controllers_coverage_rationale_1115" }, @@ -51275,7 +53579,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1133", - "community": 605, + "community": 604, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1133" }, @@ -51293,7 +53597,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1161", - "community": 14, + "community": 605, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1161" }, @@ -51329,7 +53633,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1218", - "community": 568, + "community": 620, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1218" }, @@ -51338,7 +53642,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1221", - "community": 568, + "community": 623, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1221" }, @@ -51347,7 +53651,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1238", - "community": 493, + "community": 625, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1238" }, @@ -51356,7 +53660,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1253", - "community": 568, + "community": 529, "norm_label": "covers lines 19-20: user not found raises 404.", "id": "tests_test_controllers_coverage_rationale_1253" }, @@ -51365,7 +53669,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1265", - "community": 493, + "community": 563, "norm_label": "covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: usermanager.getc", "id": "tests_test_controllers_coverage_rationale_1265" }, @@ -51374,7 +53678,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1272", - "community": 493, + "community": 563, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1272" }, @@ -51383,7 +53687,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1297", - "community": 493, + "community": 625, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1297" }, @@ -51392,7 +53696,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1313", - "community": 493, + "community": 609, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1313" }, @@ -51401,7 +53705,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1330", - "community": 493, + "community": 614, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1330" }, @@ -51410,7 +53714,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1347", - "community": 493, + "community": 617, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1347" }, @@ -51428,7 +53732,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1381", - "community": 524, + "community": 546, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1381" }, @@ -51437,7 +53741,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1384", - "community": 524, + "community": 546, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1384" }, @@ -51446,7 +53750,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1400", - "community": 524, + "community": 592, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1400" }, @@ -51572,7 +53876,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L14", - "community": 95, + "community": 135, "norm_label": "testcachelrueviction", "id": "tests_test_cache_testcachelrueviction" }, @@ -51581,7 +53885,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L17", - "community": 95, + "community": 135, "norm_label": "._make_manager()", "id": "tests_test_cache_testcachelrueviction_make_manager" }, @@ -51590,7 +53894,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L22", - "community": 95, + "community": 135, "norm_label": ".test_query_cache_starts_empty()", "id": "tests_test_cache_testcachelrueviction_test_query_cache_starts_empty" }, @@ -51599,7 +53903,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L26", - "community": 95, + "community": 135, "norm_label": ".test_query_cache_max_size_constant()", "id": "tests_test_cache_testcachelrueviction_test_query_cache_max_size_constant" }, @@ -51608,7 +53912,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L29", - "community": 95, + "community": 135, "norm_label": ".test_lru_eviction_when_over_limit()", "id": "tests_test_cache_testcachelrueviction_test_lru_eviction_when_over_limit" }, @@ -51617,7 +53921,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L50", - "community": 95, + "community": 135, "norm_label": ".test_move_to_end_on_cache_hit()", "id": "tests_test_cache_testcachelrueviction_test_move_to_end_on_cache_hit" }, @@ -51626,7 +53930,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L68", - "community": 95, + "community": 135, "norm_label": ".test_clear_query_cache()", "id": "tests_test_cache_testcachelrueviction_test_clear_query_cache" }, @@ -51635,7 +53939,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L77", - "community": 95, + "community": 135, "norm_label": ".test_none_columns_key_is_none()", "id": "tests_test_cache_testcachelrueviction_test_none_columns_key_is_none" }, @@ -51644,7 +53948,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L83", - "community": 95, + "community": 135, "norm_label": ".test_columns_key_is_tuple()", "id": "tests_test_cache_testcachelrueviction_test_columns_key_is_tuple" }, @@ -51689,7 +53993,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L107", - "community": 95, + "community": 135, "norm_label": "testcachettllogic", "id": "tests_test_cache_testcachettllogic" }, @@ -51698,7 +54002,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L108", - "community": 95, + "community": 135, "norm_label": "._make_manager()", "id": "tests_test_cache_testcachettllogic_make_manager" }, @@ -51707,7 +54011,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L112", - "community": 95, + "community": 135, "norm_label": ".test_expired_entry_detected()", "id": "tests_test_cache_testcachettllogic_test_expired_entry_detected" }, @@ -51716,7 +54020,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L123", - "community": 95, + "community": 135, "norm_label": ".test_fresh_entry_detected()", "id": "tests_test_cache_testcachettllogic_test_fresh_entry_detected" }, @@ -51725,7 +54029,7 @@ "file_type": "rationale", "source_file": "tests/test_cache.py", "source_location": "L15", - "community": 95, + "community": 135, "norm_label": "tests for stockscachemanager querycache lru eviction.", "id": "tests_test_cache_rationale_15" }, @@ -51734,7 +54038,7 @@ "file_type": "rationale", "source_file": "tests/test_cache.py", "source_location": "L18", - "community": 95, + "community": 135, "norm_label": "create a stockscachemanager with a mock db engine.", "id": "tests_test_cache_rationale_18" }, @@ -51743,7 +54047,7 @@ "file_type": "rationale", "source_file": "tests/test_cache.py", "source_location": "L78", - "community": 95, + "community": 135, "norm_label": "when columns is none, cache key should be none.", "id": "tests_test_cache_rationale_78" }, @@ -51797,7 +54101,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L229", - "community": 603, + "community": 596, "norm_label": "tests covering key.py lines 15-40. uses asyncio.run() since pytest-asyncio", "id": "tests_test_stocks_api_coverage_rationale_229" }, @@ -51941,7 +54245,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L528", - "community": 136, + "community": 162, "norm_label": "regression: is_string_dtype fails when column has strings + none (pandas 2.x).", "id": "tests_test_stocks_api_coverage_rationale_528" }, @@ -51959,7 +54263,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L575", - "community": 136, + "community": 162, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_575" }, @@ -52049,7 +54353,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L843", - "community": 17, + "community": 39, "norm_label": "invalid date -> inner 400 passes through (not wrapped as 500).", "id": "tests_test_stocks_api_coverage_rationale_843" }, @@ -52112,7 +54416,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L967", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_967" }, @@ -52202,7 +54506,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1342", - "community": 588, + "community": 22, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1342" }, @@ -52211,7 +54515,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1392", - "community": 606, + "community": 22, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1392" }, @@ -52337,7 +54641,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1344", - "community": 588, + "community": 22, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1344" }, @@ -52346,7 +54650,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1394", - "community": 606, + "community": 22, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1394" }, @@ -52526,7 +54830,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1400", - "community": 588, + "community": 22, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1400" }, @@ -52535,7 +54839,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1468", - "community": 606, + "community": 22, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1468" }, @@ -52562,7 +54866,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L228", - "community": 603, + "community": 596, "norm_label": "tests covering key.py lines 15-40. uses asyncio.run() since pytest-asyncio", "id": "tests_test_stocks_api_coverage_rationale_228" }, @@ -52706,7 +55010,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L527", - "community": 136, + "community": 162, "norm_label": "regression: is_string_dtype fails when column has strings + none (pandas 2.x).", "id": "tests_test_stocks_api_coverage_rationale_527" }, @@ -52724,7 +55028,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L574", - "community": 136, + "community": 162, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_574" }, @@ -52823,7 +55127,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L895", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_895" }, @@ -52832,7 +55136,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L904", - "community": 17, + "community": 39, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_904" }, @@ -52868,7 +55172,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L964", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_964" }, @@ -52958,7 +55262,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1396", - "community": 588, + "community": 22, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1396" }, @@ -52967,7 +55271,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1464", - "community": 606, + "community": 22, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1464" }, @@ -52994,7 +55298,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1388", - "community": 588, + "community": 22, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1388" }, @@ -53003,7 +55307,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1456", - "community": 606, + "community": 22, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1456" }, @@ -53039,7 +55343,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1297", - "community": 120, + "community": 498, "norm_label": ".test_cotations_search_required()", "id": "tests_test_stocks_api_coverage_testquerycotations_test_cotations_search_required" }, @@ -53048,7 +55352,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1298", - "community": 120, + "community": 498, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1298" }, @@ -53093,7 +55397,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1288", - "community": 120, + "community": 498, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1288" }, @@ -53102,7 +55406,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L832", - "community": 17, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_832" }, @@ -53111,7 +55415,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L885", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_885" }, @@ -53120,7 +55424,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L894", - "community": 17, + "community": 39, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_894" }, @@ -53156,7 +55460,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L954", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_954" }, @@ -53867,7 +56171,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L63", - "community": 81, + "community": 560, "norm_label": "getrealtimecotation()", "id": "controller_stocksapi_controller_getrealtimecotation" }, @@ -53975,7 +56279,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L23", - "community": 81, + "community": 560, "norm_label": "apikeytest()", "id": "controller_stocksapi_controller_apikeytest" }, @@ -54029,7 +56333,7 @@ "file_type": "code", "source_file": "main/utils/http_session.py", "source_location": "L18", - "community": 578, + "community": 627, "norm_label": "cleanup()", "id": "utils_http_session_cleanup" }, @@ -54038,7 +56342,7 @@ "file_type": "code", "source_file": "main/utils/pagination.py", "source_location": "L1", - "community": 482, + "community": 186, "norm_label": "pagination.py", "id": "main_utils_pagination_py" }, @@ -54047,7 +56351,7 @@ "file_type": "code", "source_file": "main/utils/pagination.py", "source_location": "L4", - "community": 482, + "community": 186, "norm_label": "paginationparams", "id": "utils_pagination_paginationparams" }, @@ -54056,7 +56360,7 @@ "file_type": "code", "source_file": "main/utils/pagination.py", "source_location": "L5", - "community": 482, + "community": 186, "norm_label": ".__init__()", "id": "utils_pagination_paginationparams_init" }, @@ -54065,7 +56369,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L9", - "community": 251, + "community": 561, "norm_label": "set required env vars before test collection. config.py eagerly instantia", "id": "tests_conftest_rationale_9" }, @@ -54074,7 +56378,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L75", - "community": 535, + "community": 561, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_75" }, @@ -54083,7 +56387,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L20", - "community": 604, + "community": 602, "norm_label": "dbsession()", "id": "tests_test_api_key_quota_atomic_dbsession" }, @@ -54092,7 +56396,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L21", - "community": 604, + "community": 602, "norm_label": "create an in-memory sqlite database for testing.", "id": "tests_test_api_key_quota_atomic_rationale_21" }, @@ -54101,7 +56405,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L34", - "community": 604, + "community": 602, "norm_label": "sample api key data for tests.", "id": "tests_test_api_key_quota_atomic_rationale_34" }, @@ -54155,7 +56459,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L166", - "community": 608, + "community": 26, "norm_label": "test that invalid api key returns zero rows affected.", "id": "tests_test_api_key_quota_atomic_rationale_166" }, @@ -54164,7 +56468,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L180", - "community": 608, + "community": 26, "norm_label": "test that multiple api keys have independent quotas.", "id": "tests_test_api_key_quota_atomic_rationale_180" }, @@ -54254,7 +56558,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1194", - "community": 45, + "community": 14, "norm_label": "teststocksapikeytest", "id": "tests_test_controllers_coverage_teststocksapikeytest" }, @@ -54299,7 +56603,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L148", - "community": 45, + "community": 120, "norm_label": "covers lines 44-54, 63, 66-71: register success, valueerror, generic exception.", "id": "tests_test_controllers_coverage_rationale_148" }, @@ -54326,7 +56630,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L228", - "community": 45, + "community": 120, "norm_label": "covers lines 87-93, 102: login success and failure paths.", "id": "tests_test_controllers_coverage_rationale_228" }, @@ -54434,7 +56738,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L425", - "community": 45, + "community": 120, "norm_label": "covers lines 155-156, 158, 160-168, 170-177, 179-184, 186, 190-204: googlecallba", "id": "tests_test_controllers_coverage_rationale_425" }, @@ -54551,7 +56855,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L767", - "community": 120, + "community": 498, "norm_label": "covers lines 126-136: delete /user/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_767" }, @@ -54560,7 +56864,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L770", - "community": 120, + "community": 498, "norm_label": "covers lines 126, 131, 135-136.", "id": "tests_test_controllers_coverage_rationale_770" }, @@ -54569,7 +56873,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L797", - "community": 120, + "community": 498, "norm_label": "covers lines 127-129: session not found.", "id": "tests_test_controllers_coverage_rationale_797" }, @@ -54578,7 +56882,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L819", - "community": 120, + "community": 498, "norm_label": "covers lines 132-133: revokesession returns false.", "id": "tests_test_controllers_coverage_rationale_819" }, @@ -54587,7 +56891,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L845", - "community": 221, + "community": 616, "norm_label": "covers lines 143, 145, 147-148: post /user/sessions/revoke-all.", "id": "tests_test_controllers_coverage_rationale_845" }, @@ -54596,7 +56900,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L848", - "community": 221, + "community": 616, "norm_label": "covers lines 143, 145, 147-148.", "id": "tests_test_controllers_coverage_rationale_848" }, @@ -54605,7 +56909,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L875", - "community": 45, + "community": 626, "norm_label": "covers line 24: get /prometheus/health.", "id": "tests_test_controllers_coverage_rationale_875" }, @@ -54695,7 +56999,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1037", - "community": 99, + "community": 535, "norm_label": "covers lines 95-98: delete /prometheus/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_1037" }, @@ -54704,7 +57008,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1040", - "community": 99, + "community": 535, "norm_label": "covers lines 95-98: session deleted.", "id": "tests_test_controllers_coverage_rationale_1040" }, @@ -54713,7 +57017,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1050", - "community": 99, + "community": 535, "norm_label": "covers lines 96-97: session not found.", "id": "tests_test_controllers_coverage_rationale_1050" }, @@ -54749,7 +57053,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1123", - "community": 148, + "community": 498, "norm_label": "covers lines 114-115: session ownership check fails.", "id": "tests_test_controllers_coverage_rationale_1123" }, @@ -54758,7 +57062,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1160", - "community": 99, + "community": 148, "norm_label": "covers line 125, 126-128: generic exception in chat.", "id": "tests_test_controllers_coverage_rationale_1160" }, @@ -54767,7 +57071,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1181", - "community": 605, + "community": 604, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1181" }, @@ -54794,7 +57098,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1220", - "community": 14, + "community": 605, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1220" }, @@ -54830,7 +57134,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1280", - "community": 568, + "community": 623, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1280" }, @@ -54839,7 +57143,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1312", - "community": 568, + "community": 529, "norm_label": "covers lines 19-20: user not found raises 404.", "id": "tests_test_controllers_coverage_rationale_1312" }, @@ -54848,7 +57152,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1356", - "community": 493, + "community": 568, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1356" }, @@ -54857,7 +57161,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1406", - "community": 493, + "community": 617, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1406" }, @@ -54875,7 +57179,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1440", - "community": 524, + "community": 546, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1440" }, @@ -54884,7 +57188,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1443", - "community": 524, + "community": 546, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1443" }, @@ -54893,7 +57197,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1459", - "community": 524, + "community": 592, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1459" }, @@ -54929,7 +57233,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L9", - "community": 611, + "community": 610, "norm_label": ".test_creates_new_session()", "id": "tests_test_http_session_coverage_testgetsession_test_creates_new_session" }, @@ -54938,7 +57242,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L28", - "community": 578, + "community": 627, "norm_label": "testcleanup", "id": "tests_test_http_session_coverage_testcleanup" }, @@ -54947,7 +57251,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L29", - "community": 578, + "community": 627, "norm_label": ".test_cleanup_closes_session()", "id": "tests_test_http_session_coverage_testcleanup_test_cleanup_closes_session" }, @@ -54956,7 +57260,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L37", - "community": 578, + "community": 627, "norm_label": ".test_cleanup_no_session()", "id": "tests_test_http_session_coverage_testcleanup_test_cleanup_no_session" }, @@ -54965,7 +57269,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L46", - "community": 578, + "community": 627, "norm_label": ".test_cleanup_exception_during_close()", "id": "tests_test_http_session_coverage_testcleanup_test_cleanup_exception_during_close" }, @@ -54992,7 +57296,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L37", - "community": 482, + "community": 186, "norm_label": "testpaginationparams", "id": "tests_test_pagination_testpaginationparams" }, @@ -55001,7 +57305,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L38", - "community": 482, + "community": 186, "norm_label": ".test_defaults()", "id": "tests_test_pagination_testpaginationparams_test_defaults" }, @@ -55010,7 +57314,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L46", - "community": 482, + "community": 186, "norm_label": ".test_custom_limit()", "id": "tests_test_pagination_testpaginationparams_test_custom_limit" }, @@ -55019,7 +57323,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L52", - "community": 482, + "community": 186, "norm_label": ".test_custom_offset()", "id": "tests_test_pagination_testpaginationparams_test_custom_offset" }, @@ -55028,7 +57332,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L59", - "community": 482, + "community": 186, "norm_label": ".test_limit_and_offset()", "id": "tests_test_pagination_testpaginationparams_test_limit_and_offset" }, @@ -55037,7 +57341,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L67", - "community": 482, + "community": 186, "norm_label": ".test_limit_exceeds_max_rejected()", "id": "tests_test_pagination_testpaginationparams_test_limit_exceeds_max_rejected" }, @@ -55046,7 +57350,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L71", - "community": 482, + "community": 186, "norm_label": ".test_limit_zero_rejected()", "id": "tests_test_pagination_testpaginationparams_test_limit_zero_rejected" }, @@ -55055,7 +57359,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L75", - "community": 482, + "community": 186, "norm_label": ".test_negative_offset_rejected()", "id": "tests_test_pagination_testpaginationparams_test_negative_offset_rejected" }, @@ -55064,7 +57368,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L79", - "community": 482, + "community": 186, "norm_label": ".test_offset_beyond_total()", "id": "tests_test_pagination_testpaginationparams_test_offset_beyond_total" }, @@ -55073,7 +57377,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L84", - "community": 482, + "community": 186, "norm_label": ".test_limit_equals_max()", "id": "tests_test_pagination_testpaginationparams_test_limit_equals_max" }, @@ -55379,7 +57683,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L227", - "community": 603, + "community": 596, "norm_label": "tests covering key.py lines 15-40. uses asyncio.run() since pytest-asyncio", "id": "tests_test_stocks_api_coverage_rationale_227" }, @@ -55523,7 +57827,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L526", - "community": 136, + "community": 162, "norm_label": "regression: is_string_dtype fails when column has strings + none (pandas 2.x).", "id": "tests_test_stocks_api_coverage_rationale_526" }, @@ -55541,7 +57845,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L573", - "community": 136, + "community": 162, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_573" }, @@ -55622,7 +57926,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L831", - "community": 17, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_831" }, @@ -55631,7 +57935,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L884", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_884" }, @@ -55640,7 +57944,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L893", - "community": 17, + "community": 39, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_893" }, @@ -55685,7 +57989,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L953", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_953" }, @@ -55892,7 +58196,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L827", - "community": 17, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_827" }, @@ -55901,7 +58205,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L876", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_876" }, @@ -55982,7 +58286,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L826", - "community": 17, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_826" }, @@ -56018,7 +58322,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L943", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_943" }, @@ -56117,7 +58421,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L780", - "community": 17, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_780" }, @@ -56126,7 +58430,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L828", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_828" }, @@ -56135,7 +58439,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L837", - "community": 17, + "community": 39, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_837" }, @@ -56171,7 +58475,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L897", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_897" }, @@ -56180,7 +58484,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L8", - "community": 624, + "community": 621, "norm_label": "checkmysqlconnection \u2014 success, errors, engine=none paths.", "id": "tests_test_connectivity_coverage_rationale_8" }, @@ -56189,7 +58493,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L105", - "community": 623, + "community": 618, "norm_label": "checkserviceconnection \u2014 success, not found, errors.", "id": "tests_test_connectivity_coverage_rationale_105" }, @@ -56288,7 +58592,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L781", - "community": 17, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_781" }, @@ -56297,7 +58601,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L838", - "community": 17, + "community": 39, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_838" }, @@ -56360,7 +58664,7 @@ "file_type": "code", "source_file": "main/utils/errors.py", "source_location": "L27", - "community": 572, + "community": 569, "norm_label": "_build_error_response()", "id": "utils_errors_build_error_response" }, @@ -56369,7 +58673,7 @@ "file_type": "code", "source_file": "main/utils/errors.py", "source_location": "L37", - "community": 572, + "community": 569, "norm_label": "http_exception_handler()", "id": "utils_errors_http_exception_handler" }, @@ -56378,7 +58682,7 @@ "file_type": "code", "source_file": "main/utils/errors.py", "source_location": "L44", - "community": 572, + "community": 569, "norm_label": "validation_exception_handler()", "id": "utils_errors_validation_exception_handler" }, @@ -56387,7 +58691,7 @@ "file_type": "code", "source_file": "main/utils/errors.py", "source_location": "L56", - "community": 572, + "community": 569, "norm_label": "generic_exception_handler()", "id": "utils_errors_generic_exception_handler" }, @@ -56396,7 +58700,7 @@ "file_type": "code", "source_file": "main/utils/errors.py", "source_location": "L65", - "community": 120, + "community": 498, "norm_label": "register_error_handlers()", "id": "utils_errors_register_error_handlers" }, @@ -56405,7 +58709,7 @@ "file_type": "code", "source_file": "main/utils/http_session.py", "source_location": "L9", - "community": 574, + "community": 184, "norm_label": "get_session()", "id": "utils_http_session_get_session" }, @@ -56414,7 +58718,7 @@ "file_type": "rationale", "source_file": "main/utils/http_session.py", "source_location": "L10", - "community": 574, + "community": 184, "norm_label": "return a requests.session for the current thread. sessions are created la", "id": "utils_http_session_rationale_10" }, @@ -56423,7 +58727,7 @@ "file_type": "rationale", "source_file": "main/utils/http_session.py", "source_location": "L23", - "community": 578, + "community": 627, "norm_label": "close the main thread's session at interpreter shutdown.", "id": "utils_http_session_rationale_23" }, @@ -56828,7 +59132,7 @@ "file_type": "rationale", "source_file": "main/utils/http_session.py", "source_location": "L9", - "community": 574, + "community": 184, "norm_label": "return a requests.session for the current thread. sessions are created la", "id": "utils_http_session_rationale_9" }, @@ -57206,7 +59510,7 @@ "file_type": "rationale", "source_file": "main/utils/errors.py", "source_location": "L68", - "community": 120, + "community": 498, "norm_label": "register exception handlers on the fastapi app. note: httpexception and r", "id": "utils_errors_rationale_68" }, @@ -57323,7 +59627,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L522", - "community": 136, + "community": 162, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_522" }, @@ -57404,7 +59708,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L775", - "community": 17, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_775" }, @@ -57413,7 +59717,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L823", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_823" }, @@ -57449,7 +59753,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L892", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_892" }, @@ -57467,7 +59771,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L62", - "community": 535, + "community": 561, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_62" }, @@ -57476,7 +59780,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L61", - "community": 535, + "community": 561, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_61" }, @@ -57485,7 +59789,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L57", - "community": 535, + "community": 561, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_57" }, @@ -57494,7 +59798,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L49", - "community": 535, + "community": 561, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_49" }, @@ -57764,7 +60068,7 @@ "file_type": "document", "source_file": "CODE_REVIEW_REPORT.md", "source_location": "L217", - "community": 587, + "community": 634, "norm_label": "category 8: testing gaps (medium)", "id": "server_code_review_report_category_8_testing_gaps_medium" }, @@ -57773,7 +60077,7 @@ "file_type": "document", "source_file": "CODE_REVIEW_REPORT.md", "source_location": "L219", - "community": 587, + "community": 634, "norm_label": "issue 8.1 \u2014 no integration tests for full request lifecycle", "id": "server_code_review_report_issue_8_1_no_integration_tests_for_full_request_lifecycle" }, @@ -57782,7 +60086,7 @@ "file_type": "document", "source_file": "CODE_REVIEW_REPORT.md", "source_location": "L223", - "community": 587, + "community": 634, "norm_label": "issue 8.2 \u2014 no tests for scraper, stocks query, or cache", "id": "server_code_review_report_issue_8_2_no_tests_for_scraper_stocks_query_or_cache" }, @@ -57791,7 +60095,7 @@ "file_type": "document", "source_file": "CODE_REVIEW_REPORT.md", "source_location": "L230", - "community": 587, + "community": 634, "norm_label": "issue 8.3 \u2014 no tests for google oauth callback", "id": "server_code_review_report_issue_8_3_no_tests_for_google_oauth_callback" }, @@ -57800,7 +60104,7 @@ "file_type": "document", "source_file": "CODE_REVIEW_REPORT.md", "source_location": "L234", - "community": 587, + "community": 634, "norm_label": "issue 8.4 \u2014 no tests for session cleanup", "id": "server_code_review_report_issue_8_4_no_tests_for_session_cleanup" }, @@ -57863,7 +60167,7 @@ "file_type": "rationale", "source_file": "main/utils/errors.py", "source_location": "L67", - "community": 120, + "community": 498, "norm_label": "register exception handlers on the fastapi app. note: httpexception and r", "id": "utils_errors_rationale_67" }, @@ -57881,7 +60185,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L1", - "community": 502, + "community": 613, "norm_label": "test_stocks_cache.py", "id": "tests_test_stocks_cache_py" }, @@ -57998,7 +60302,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L109", - "community": 502, + "community": 613, "norm_label": "testconnectionpool", "id": "tests_test_stocks_cache_testconnectionpool" }, @@ -58007,7 +60311,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L112", - "community": 502, + "community": 613, "norm_label": ".test_stocks_engine_has_pool_configuration()", "id": "tests_test_stocks_cache_testconnectionpool_test_stocks_engine_has_pool_configuration" }, @@ -58016,7 +60320,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L121", - "community": 502, + "community": 613, "norm_label": "testlazydeserialization", "id": "tests_test_stocks_cache_testlazydeserialization" }, @@ -58025,7 +60329,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L124", - "community": 502, + "community": 613, "norm_label": ".test_query_manager_has_deserialize_method()", "id": "tests_test_stocks_cache_testlazydeserialization_test_query_manager_has_deserialize_method" }, @@ -58034,7 +60338,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L135", - "community": 600, + "community": 572, "norm_label": "testqueryoptimization", "id": "tests_test_stocks_cache_testqueryoptimization" }, @@ -58043,7 +60347,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L138", - "community": 600, + "community": 572, "norm_label": ".test_all_optimizations_present()", "id": "tests_test_stocks_cache_testqueryoptimization_test_all_optimizations_present" }, @@ -58052,7 +60356,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L153", - "community": 600, + "community": 572, "norm_label": ".test_query_filter_uses_optimization()", "id": "tests_test_stocks_cache_testqueryoptimization_test_query_filter_uses_optimization" }, @@ -58124,7 +60428,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L299", - "community": 563, + "community": 613, "norm_label": "testfilterbysearchterms", "id": "tests_test_stocks_cache_testfilterbysearchterms" }, @@ -58133,7 +60437,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L302", - "community": 563, + "community": 613, "norm_label": ".test_filter_with_tickerindex()", "id": "tests_test_stocks_cache_testfilterbysearchterms_test_filter_with_tickerindex" }, @@ -58142,7 +60446,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L308", - "community": 502, + "community": 613, "norm_label": "testqueryperformance", "id": "tests_test_stocks_cache_testqueryperformance" }, @@ -58151,7 +60455,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L311", - "community": 502, + "community": 613, "norm_label": ".test_query_response_time_under_1_second()", "id": "tests_test_stocks_cache_testqueryperformance_test_query_response_time_under_1_second" }, @@ -58268,7 +60572,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L110", - "community": 502, + "community": 613, "norm_label": "tests for connection pool configuration", "id": "tests_test_stocks_cache_rationale_110" }, @@ -58277,7 +60581,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L113", - "community": 502, + "community": 613, "norm_label": "stocks engine should have optimized pool settings", "id": "tests_test_stocks_cache_rationale_113" }, @@ -58286,7 +60590,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L122", - "community": 502, + "community": 613, "norm_label": "tests for lazy json deserialization", "id": "tests_test_stocks_cache_rationale_122" }, @@ -58295,7 +60599,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L125", - "community": 502, + "community": 613, "norm_label": "query manager should have deserialize method", "id": "tests_test_stocks_cache_rationale_125" }, @@ -58304,7 +60608,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L136", - "community": 600, + "community": 572, "norm_label": "integration tests for all query optimizations", "id": "tests_test_stocks_cache_rationale_136" }, @@ -58313,7 +60617,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L139", - "community": 600, + "community": 572, "norm_label": "all optimizations should be implemented", "id": "tests_test_stocks_cache_rationale_139" }, @@ -58322,7 +60626,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L154", - "community": 600, + "community": 572, "norm_label": "query filter should use ticker index", "id": "tests_test_stocks_cache_rationale_154" }, @@ -58394,7 +60698,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L300", - "community": 563, + "community": 613, "norm_label": "tests for optimized search filtering", "id": "tests_test_stocks_cache_rationale_300" }, @@ -58403,7 +60707,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L303", - "community": 563, + "community": 613, "norm_label": "filter should use ticker index for o(1) lookup", "id": "tests_test_stocks_cache_rationale_303" }, @@ -58412,7 +60716,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L309", - "community": 502, + "community": 613, "norm_label": "performance tests for query operations", "id": "tests_test_stocks_cache_rationale_309" }, @@ -58421,7 +60725,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L312", - "community": 502, + "community": 613, "norm_label": "query should respond within 1 second", "id": "tests_test_stocks_cache_rationale_312" }, @@ -58556,7 +60860,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L112", - "community": 502, + "community": 613, "norm_label": "tests for connection pool configuration", "id": "tests_test_stocks_cache_rationale_112" }, @@ -58565,7 +60869,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L115", - "community": 502, + "community": 613, "norm_label": "stocks engine should have optimized pool settings", "id": "tests_test_stocks_cache_rationale_115" }, @@ -58574,7 +60878,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L124", - "community": 502, + "community": 613, "norm_label": "tests for lazy json deserialization", "id": "tests_test_stocks_cache_rationale_124" }, @@ -58583,7 +60887,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L127", - "community": 502, + "community": 613, "norm_label": "query manager should have deserialize method", "id": "tests_test_stocks_cache_rationale_127" }, @@ -58592,7 +60896,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L138", - "community": 600, + "community": 572, "norm_label": "integration tests for all query optimizations", "id": "tests_test_stocks_cache_rationale_138" }, @@ -58601,7 +60905,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L141", - "community": 600, + "community": 572, "norm_label": "all optimizations should be implemented", "id": "tests_test_stocks_cache_rationale_141" }, @@ -58610,7 +60914,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L156", - "community": 600, + "community": 572, "norm_label": "query filter should use ticker index", "id": "tests_test_stocks_cache_rationale_156" }, @@ -58682,7 +60986,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L302", - "community": 563, + "community": 613, "norm_label": "tests for optimized search filtering", "id": "tests_test_stocks_cache_rationale_302" }, @@ -58691,7 +60995,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L305", - "community": 563, + "community": 613, "norm_label": "filter should use ticker index for o(1) lookup", "id": "tests_test_stocks_cache_rationale_305" }, @@ -58700,7 +61004,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L311", - "community": 502, + "community": 613, "norm_label": "performance tests for query operations", "id": "tests_test_stocks_cache_rationale_311" }, @@ -58709,7 +61013,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L314", - "community": 502, + "community": 613, "norm_label": "query should respond within 1 second", "id": "tests_test_stocks_cache_rationale_314" }, @@ -58781,7 +61085,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L304", - "community": 563, + "community": 613, "norm_label": ".test_filter_with_tickerindex()", "id": "tests_test_stocks_cache_testfilterbysearchterms_test_filter_with_tickerIndex" }, @@ -58790,7 +61094,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L1", - "community": 101, + "community": 586, "norm_label": "test_stocks_optimization.py", "id": "tests_test_stocks_optimization_py" }, @@ -58799,7 +61103,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L17", - "community": 503, + "community": 42, "norm_label": "testtickerindex", "id": "tests_test_stocks_optimization_testtickerindex" }, @@ -58808,7 +61112,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L20", - "community": 503, + "community": 42, "norm_label": ".test_tickerindex_built_after_cache_load()", "id": "tests_test_stocks_optimization_testtickerindex_test_tickerIndex_built_after_cache_load" }, @@ -58817,7 +61121,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L28", - "community": 503, + "community": 42, "norm_label": ".test_tickerindex_contains_all_tickers()", "id": "tests_test_stocks_optimization_testtickerindex_test_tickerIndex_contains_all_tickers" }, @@ -58826,7 +61130,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L38", - "community": 503, + "community": 42, "norm_label": ".test_tickerindex_case_insensitive()", "id": "tests_test_stocks_optimization_testtickerindex_test_tickerIndex_case_insensitive" }, @@ -58835,7 +61139,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L47", - "community": 503, + "community": 42, "norm_label": ".test_ticker_lookup_returns_valid_index()", "id": "tests_test_stocks_optimization_testtickerindex_test_ticker_lookup_returns_valid_index" }, @@ -58844,7 +61148,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L58", - "community": 503, + "community": 42, "norm_label": ".test_tickerindex_rebuilt_on_cache_refresh()", "id": "tests_test_stocks_optimization_testtickerindex_test_tickerIndex_rebuilt_on_cache_refresh" }, @@ -58907,7 +61211,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L111", - "community": 101, + "community": 586, "norm_label": "testconnectionpool", "id": "tests_test_stocks_optimization_testconnectionpool" }, @@ -58916,7 +61220,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L114", - "community": 101, + "community": 586, "norm_label": ".test_stocks_engine_has_pool_configuration()", "id": "tests_test_stocks_optimization_testconnectionpool_test_stocks_engine_has_pool_configuration" }, @@ -58925,7 +61229,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L123", - "community": 101, + "community": 63, "norm_label": "testlazydeserialization", "id": "tests_test_stocks_optimization_testlazydeserialization" }, @@ -58934,7 +61238,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L126", - "community": 101, + "community": 63, "norm_label": ".test_query_manager_has_deserialize_method()", "id": "tests_test_stocks_optimization_testlazydeserialization_test_query_manager_has_deserialize_method" }, @@ -58943,7 +61247,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L137", - "community": 184, + "community": 586, "norm_label": "testqueryoptimization", "id": "tests_test_stocks_optimization_testqueryoptimization" }, @@ -58952,7 +61256,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L140", - "community": 184, + "community": 586, "norm_label": ".test_all_optimizations_present()", "id": "tests_test_stocks_optimization_testqueryoptimization_test_all_optimizations_present" }, @@ -58961,7 +61265,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L155", - "community": 184, + "community": 586, "norm_label": ".test_query_filter_uses_optimization()", "id": "tests_test_stocks_optimization_testqueryoptimization_test_query_filter_uses_optimization" }, @@ -59033,7 +61337,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L301", - "community": 498, + "community": 586, "norm_label": "testfilterbysearchterms", "id": "tests_test_stocks_optimization_testfilterbysearchterms" }, @@ -59042,7 +61346,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L304", - "community": 498, + "community": 586, "norm_label": ".test_filter_with_tickerindex()", "id": "tests_test_stocks_optimization_testfilterbysearchterms_test_filter_with_tickerIndex" }, @@ -59051,7 +61355,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L310", - "community": 101, + "community": 586, "norm_label": "testqueryperformance", "id": "tests_test_stocks_optimization_testqueryperformance" }, @@ -59060,7 +61364,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L313", - "community": 101, + "community": 586, "norm_label": ".test_query_response_time_under_1_second()", "id": "tests_test_stocks_optimization_testqueryperformance_test_query_response_time_under_1_second" }, @@ -59069,7 +61373,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L18", - "community": 503, + "community": 42, "norm_label": "tests for dynamic ticker index feature", "id": "tests_test_stocks_optimization_rationale_18" }, @@ -59078,7 +61382,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L21", - "community": 503, + "community": 42, "norm_label": "ticker index should be built when cache is loaded", "id": "tests_test_stocks_optimization_rationale_21" }, @@ -59087,7 +61391,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L29", - "community": 503, + "community": 42, "norm_label": "ticker index should contain all tickers from cache", "id": "tests_test_stocks_optimization_rationale_29" }, @@ -59096,7 +61400,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L39", - "community": 503, + "community": 42, "norm_label": "ticker index should be case-insensitive", "id": "tests_test_stocks_optimization_rationale_39" }, @@ -59105,7 +61409,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L48", - "community": 503, + "community": 42, "norm_label": "looking up ticker should return valid row index", "id": "tests_test_stocks_optimization_rationale_48" }, @@ -59114,7 +61418,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L59", - "community": 503, + "community": 42, "norm_label": "ticker index should be rebuilt when cache refreshes", "id": "tests_test_stocks_optimization_rationale_59" }, @@ -59177,7 +61481,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L112", - "community": 101, + "community": 586, "norm_label": "tests for connection pool configuration", "id": "tests_test_stocks_optimization_rationale_112" }, @@ -59186,7 +61490,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L115", - "community": 101, + "community": 586, "norm_label": "stocks engine should have optimized pool settings", "id": "tests_test_stocks_optimization_rationale_115" }, @@ -59195,7 +61499,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L124", - "community": 101, + "community": 63, "norm_label": "tests for lazy json deserialization", "id": "tests_test_stocks_optimization_rationale_124" }, @@ -59204,7 +61508,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L127", - "community": 101, + "community": 63, "norm_label": "query manager should have deserialize method", "id": "tests_test_stocks_optimization_rationale_127" }, @@ -59213,7 +61517,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L138", - "community": 184, + "community": 586, "norm_label": "integration tests for all query optimizations", "id": "tests_test_stocks_optimization_rationale_138" }, @@ -59222,7 +61526,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L141", - "community": 184, + "community": 586, "norm_label": "all optimizations should be implemented", "id": "tests_test_stocks_optimization_rationale_141" }, @@ -59231,7 +61535,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L156", - "community": 184, + "community": 586, "norm_label": "query filter should use ticker index", "id": "tests_test_stocks_optimization_rationale_156" }, @@ -59303,7 +61607,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L302", - "community": 498, + "community": 586, "norm_label": "tests for optimized search filtering", "id": "tests_test_stocks_optimization_rationale_302" }, @@ -59312,7 +61616,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L305", - "community": 498, + "community": 586, "norm_label": "filter should use ticker index for o(1) lookup", "id": "tests_test_stocks_optimization_rationale_305" }, @@ -59321,7 +61625,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L311", - "community": 101, + "community": 586, "norm_label": "performance tests for query operations", "id": "tests_test_stocks_optimization_rationale_311" }, @@ -59330,7 +61634,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L314", - "community": 101, + "community": 586, "norm_label": "query should respond within 1 second", "id": "tests_test_stocks_optimization_rationale_314" }, @@ -59348,7 +61652,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L173", - "community": 498, + "community": 586, "norm_label": "tests for optimized search filtering", "id": "tests_test_stocks_optimization_rationale_173" }, @@ -59357,7 +61661,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L176", - "community": 498, + "community": 586, "norm_label": "filter should use ticker index for o(1) lookup", "id": "tests_test_stocks_optimization_rationale_176" }, @@ -59366,7 +61670,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L182", - "community": 101, + "community": 586, "norm_label": "performance tests for query operations", "id": "tests_test_stocks_optimization_rationale_182" }, @@ -59375,7 +61679,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L185", - "community": 101, + "community": 586, "norm_label": "query should respond within 1 second", "id": "tests_test_stocks_optimization_rationale_185" }, @@ -59658,7 +61962,7 @@ "label": "FastAPI", "file_type": "rationale", "source_file": "README.md", - "community": 519, + "community": 152, "norm_label": "fastapi", "id": "fastapi" }, @@ -59698,7 +62002,7 @@ "label": "Authentication System", "file_type": "document", "source_file": "docs/authentication.md", - "community": 560, + "community": 538, "norm_label": "authentication system", "id": "authentication" }, @@ -59706,7 +62010,7 @@ "label": "JWT Authentication", "file_type": "rationale", "source_file": "docs/authentication.md", - "community": 560, + "community": 538, "norm_label": "jwt authentication", "id": "jwt" }, @@ -59714,7 +62018,7 @@ "label": "Google OAuth", "file_type": "rationale", "source_file": "docs/authentication.md", - "community": 560, + "community": 538, "norm_label": "google oauth", "id": "google_oauth" }, @@ -59802,7 +62106,7 @@ "label": "Pytest Testing", "file_type": "rationale", "source_file": "pyproject.toml", - "community": 586, + "community": 491, "norm_label": "pytest testing", "id": "pytest" }, @@ -60446,6 +62750,86 @@ "source": "server_config_config", "target": "utils_logging_config_discordhandler" }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L17", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_wallet_service_entrycreate", + "target": "server_config_config" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L17", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_wallet_service_entryupdate", + "target": "server_config_config" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L17", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_wallet_service_targetupsert", + "target": "server_config_config" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L17", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_wallet_service_ratingupsert", + "target": "server_config_config" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/service/wallet_service.py", + "source_location": "L13", + "weight": 0.8, + "confidence_score": 0.5, + "source": "service_wallet_service_entrycreate", + "target": "server_config_config" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/service/wallet_service.py", + "source_location": "L13", + "weight": 0.8, + "confidence_score": 0.5, + "source": "service_wallet_service_entryupdate", + "target": "server_config_config" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/service/wallet_service.py", + "source_location": "L13", + "weight": 0.8, + "confidence_score": 0.5, + "source": "service_wallet_service_targetupsert", + "target": "server_config_config" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/service/wallet_service.py", + "source_location": "L13", + "weight": 0.8, + "confidence_score": 0.5, + "source": "service_wallet_service_ratingupsert", + "target": "server_config_config" + }, { "relation": "uses", "confidence": "INFERRED", @@ -64962,6 +67346,17 @@ "source": "controller_authentication_controller_introspect", "target": "authentication_introspect_introspecttoken" }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/auth.py", + "source_location": "L27", + "weight": 1.0, + "source": "wallet_auth_getwalletidentity", + "target": "authentication_introspect_introspecttoken" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -67169,6 +69564,66 @@ "source": "orunmila_memory_memorycandidate", "target": "utils_roles_roles" }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L15", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_entries_entrycreate", + "target": "basemodel" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L26", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_entries_entryupdate", + "target": "basemodel" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L17", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_summary_targetupsert", + "target": "basemodel" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L24", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_summary_ratingupsert", + "target": "basemodel" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L17", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_wallet_controller_walletcreate", + "target": "basemodel" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L160", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_wallet_controller_earningssync", + "target": "basemodel" + }, { "relation": "inherits", "confidence": "EXTRACTED", @@ -67179,6 +69634,86 @@ "source": "utils_errors_errorresponse", "target": "basemodel" }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L44", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_wallet_service_entrycreate", + "target": "basemodel" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L55", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_wallet_service_entryupdate", + "target": "basemodel" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L306", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_wallet_service_targetupsert", + "target": "basemodel" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L313", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_wallet_service_ratingupsert", + "target": "basemodel" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L26", + "weight": 1.0, + "confidence_score": 1.0, + "source": "service_wallet_service_entrycreate", + "target": "basemodel" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L37", + "weight": 1.0, + "confidence_score": 1.0, + "source": "service_wallet_service_entryupdate", + "target": "basemodel" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L293", + "weight": 1.0, + "confidence_score": 1.0, + "source": "service_wallet_service_targetupsert", + "target": "basemodel" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L300", + "weight": 1.0, + "confidence_score": 1.0, + "source": "service_wallet_service_ratingupsert", + "target": "basemodel" + }, { "relation": "inherits", "confidence": "EXTRACTED", @@ -68113,6 +70648,17 @@ "source": "orunmila_stream_bus_streambus_streamresponse", "target": "orunmila_stream_bus_streambus_eventgenerator" }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L7", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_orunmila_tools_py", + "target": "fastapi" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -68183,6 +70729,16 @@ "source": "main_app_orunmila_tools_py", "target": "orunmila_tools_serve_file" }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L183", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_narrate_positions" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -68193,6 +70749,16 @@ "source": "main_app_orunmila_tools_py", "target": "orunmila_tools_dispatchtoolcall" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L22", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_22", + "target": "orunmila_tools_search_memory" + }, { "relation": "rationale_for", "confidence": "EXTRACTED", @@ -68207,10 +70773,10 @@ "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "main/app/orunmila/tools.py", - "source_location": "L52", + "source_location": "L53", "weight": 1.0, "confidence_score": 1.0, - "source": "orunmila_tools_rationale_52", + "source": "orunmila_tools_rationale_53", "target": "orunmila_tools_save_memory" }, { @@ -68224,6 +70790,26 @@ "source": "orunmila_tools_save_memory", "target": "orunmila_vector_embed" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L52", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_52", + "target": "orunmila_tools_save_memory" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L95", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_95", + "target": "orunmila_tools_execute_code" + }, { "relation": "rationale_for", "confidence": "EXTRACTED", @@ -68234,6 +70820,16 @@ "source": "orunmila_tools_rationale_94", "target": "orunmila_tools_execute_code" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L116", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_116", + "target": "orunmila_tools_read_file" + }, { "relation": "rationale_for", "confidence": "EXTRACTED", @@ -68244,6 +70840,16 @@ "source": "orunmila_tools_rationale_115", "target": "orunmila_tools_read_file" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L130", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_130", + "target": "orunmila_tools_write_file" + }, { "relation": "rationale_for", "confidence": "EXTRACTED", @@ -68254,6 +70860,16 @@ "source": "orunmila_tools_rationale_129", "target": "orunmila_tools_write_file" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L146", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_146", + "target": "orunmila_tools_list_files" + }, { "relation": "rationale_for", "confidence": "EXTRACTED", @@ -68264,6 +70880,16 @@ "source": "orunmila_tools_rationale_145", "target": "orunmila_tools_list_files" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L159", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_159", + "target": "orunmila_tools_serve_file" + }, { "relation": "rationale_for", "confidence": "EXTRACTED", @@ -68274,6 +70900,115 @@ "source": "orunmila_tools_rationale_158", "target": "orunmila_tools_serve_file" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L184", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_184", + "target": "orunmila_tools_narrate_positions" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L208", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_wallets_getwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L212", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_positions_getpositions" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L217", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_summary_getsummary" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L224", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_earnings_listearnings" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L205", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_wallets_getownedwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L205", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_wallet_service_getownedwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L212", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_wallet_service_getpositions" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L217", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_wallet_service_getsummary" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L224", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_wallet_service_listearnings" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -72706,12739 +75441,17498 @@ "target": "user_user_hasrole" }, { - "relation": "imports_from", - "context": "import", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L6", + "source_file": "main/app/wallet/earnings.py", + "source_location": "L24", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_authentication_controller_py", - "target": "fastapi" + "source": "main_app_wallet_earnings_py", + "target": "wallet_earnings_syncearnings" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L20", + "source_file": "main/app/wallet/earnings.py", + "source_location": "L104", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_authentication_controller_py", - "target": "controller_authentication_controller_issecurescheme" + "source": "main_app_wallet_earnings_py", + "target": "wallet_earnings_listearnings" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L44", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/earnings.py", + "source_location": "L25", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_controller_authentication_controller_py", - "target": "controller_authentication_controller_resolvecookiedomain" + "source": "wallet_earnings_syncearnings", + "target": "wallet_wallets_getwallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/earnings.py", + "source_location": "L45", + "weight": 1.0, + "source": "wallet_earnings_syncearnings", + "target": "wallet_market_data_fetchmarketdividends" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/earnings.py", + "source_location": "L61", + "weight": 1.0, + "source": "wallet_earnings_syncearnings", + "target": "wallet_entries_positionatdate" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/earnings.py", + "source_location": "L80", + "weight": 1.0, + "source": "wallet_earnings_syncearnings", + "target": "models_wallet_earning" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/earnings.py", + "source_location": "L25", + "weight": 1.0, + "source": "wallet_earnings_syncearnings", + "target": "wallet_wallets_getownedwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/earnings.py", + "source_location": "L108", + "weight": 1.0, + "source": "wallet_earnings_listearnings", + "target": "wallet_wallets_getwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/earnings.py", + "source_location": "L105", + "weight": 1.0, + "source": "wallet_earnings_listearnings", + "target": "wallet_wallets_getownedwallet" + }, + { + "relation": "imports_from", + "context": "import", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L32", + "source_file": "main/app/wallet/entries.py", + "source_location": "L5", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_authentication_controller_py", - "target": "controller_authentication_controller_issuesessioncookie" + "source": "main_app_wallet_entries_py", + "target": "fastapi" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L24", + "source_file": "main/app/wallet/entries.py", + "source_location": "L15", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_authentication_controller_py", - "target": "controller_authentication_controller_health" + "source": "main_app_wallet_entries_py", + "target": "wallet_entries_entrycreate" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L29", + "source_file": "main/app/wallet/entries.py", + "source_location": "L26", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_authentication_controller_py", - "target": "controller_authentication_controller_register" + "source": "main_app_wallet_entries_py", + "target": "wallet_entries_entryupdate" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L71", + "source_file": "main/app/wallet/entries.py", + "source_location": "L33", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_authentication_controller_py", - "target": "controller_authentication_controller_login" + "source": "main_app_wallet_entries_py", + "target": "wallet_entries_applyentries" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L100", + "source_file": "main/app/wallet/entries.py", + "source_location": "L52", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_authentication_controller_py", - "target": "controller_authentication_controller_logout" + "source": "main_app_wallet_entries_py", + "target": "wallet_entries_recalcholding" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L253", + "source_file": "main/app/wallet/entries.py", + "source_location": "L81", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_authentication_controller_py", - "target": "controller_authentication_controller_introspect" + "source": "main_app_wallet_entries_py", + "target": "wallet_entries_addentry" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L131", + "source_file": "main/app/wallet/entries.py", + "source_location": "L113", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_authentication_controller_py", - "target": "controller_authentication_controller_googlelogin" + "source": "main_app_wallet_entries_py", + "target": "wallet_entries_listentries" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L146", + "source_file": "main/app/wallet/entries.py", + "source_location": "L128", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_authentication_controller_py", - "target": "controller_authentication_controller_googlecallback" + "source": "main_app_wallet_entries_py", + "target": "wallet_entries_updateentry" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L245", + "source_file": "main/app/wallet/entries.py", + "source_location": "L158", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_authentication_controller_py", - "target": "controller_authentication_controller_requireservicetoken" + "source": "main_app_wallet_entries_py", + "target": "wallet_entries_deleteentry" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L277", + "source_file": "main/app/wallet/entries.py", + "source_location": "L183", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_authentication_controller_py", - "target": "controller_authentication_controller_verifyservicekey" + "source": "main_app_wallet_entries_py", + "target": "wallet_entries_positionatdate" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_entries_entrycreate", + "target": "models_wallet_holding" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_entries_entrycreate", + "target": "models_wallet_transaction" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_walletcreate", + "target": "wallet_entries_entrycreate" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_earningssync", + "target": "wallet_entries_entrycreate" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_entries_entryupdate", + "target": "models_wallet_holding" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_entries_entryupdate", + "target": "models_wallet_transaction" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_walletcreate", + "target": "wallet_entries_entryupdate" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_earningssync", + "target": "wallet_entries_entryupdate" }, { "relation": "calls", "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L39", + "source_file": "main/app/wallet/entries.py", + "source_location": "L67", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_authentication_controller_issecurescheme", - "target": "controller_authentication_controller_issuesessioncookie" + "source": "wallet_entries_recalcholding", + "target": "wallet_entries_applyentries" }, { "relation": "calls", "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L123", + "source_file": "main/app/wallet/entries.py", + "source_location": "L185", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_authentication_controller_issecurescheme", - "target": "controller_authentication_controller_logout" + "source": "wallet_entries_positionatdate", + "target": "wallet_entries_applyentries" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L114", + "source_file": "main/app/wallet/performance.py", + "source_location": "L61", "weight": 1.0, - "source": "controller_authentication_controller_issecurescheme", - "target": "tests_test_controllers_coverage_testissecurescheme_test_is_secure_https" + "source": "wallet_performance_cachedperformance", + "target": "wallet_entries_applyentries" }, { "relation": "calls", "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L121", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L102", "weight": 1.0, - "source": "controller_authentication_controller_issecurescheme", - "target": "tests_test_controllers_coverage_testissecurescheme_test_is_secure_http" + "confidence_score": 1.0, + "source": "wallet_entries_addentry", + "target": "wallet_entries_recalcholding" }, { "relation": "calls", "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L128", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L144", "weight": 1.0, - "source": "controller_authentication_controller_issecurescheme", - "target": "tests_test_controllers_coverage_testissecurescheme_test_is_secure_no_scheme" + "confidence_score": 1.0, + "source": "wallet_entries_updateentry", + "target": "wallet_entries_recalcholding" }, { "relation": "calls", "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L49", + "source_file": "main/app/wallet/entries.py", + "source_location": "L173", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_authentication_controller_issecurescheme", - "target": "controller_authentication_controller_register" + "source": "wallet_entries_deleteentry", + "target": "wallet_entries_recalcholding" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L87", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/entries.py", + "source_location": "L69", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_authentication_controller_issecurescheme", - "target": "controller_authentication_controller_login" + "source": "wallet_entries_recalcholding", + "target": "models_wallet_holding" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L176", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/entries.py", + "source_location": "L82", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_authentication_controller_issecurescheme", - "target": "controller_authentication_controller_googlecallback" + "source": "wallet_entries_addentry", + "target": "wallet_wallets_getwallet" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L58", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/entries.py", + "source_location": "L88", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_authentication_controller_issuesessioncookie", - "target": "controller_authentication_controller_resolvecookiedomain" + "source": "wallet_entries_addentry", + "target": "models_wallet_transaction" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L160", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/entries.py", + "source_location": "L82", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_authentication_controller_logout", - "target": "controller_authentication_controller_resolvecookiedomain" + "source": "wallet_entries_addentry", + "target": "wallet_wallets_getownedwallet" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L81", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/entries.py", + "source_location": "L116", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_authentication_controller_issuesessioncookie", - "target": "controller_authentication_controller_register" + "source": "wallet_entries_listentries", + "target": "wallet_wallets_getwallet" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L107", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/entries.py", + "source_location": "L116", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_authentication_controller_issuesessioncookie", - "target": "controller_authentication_controller_login" + "source": "wallet_entries_listentries", + "target": "wallet_wallets_getownedwallet" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L186", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/entries.py", + "source_location": "L134", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_authentication_controller_issuesessioncookie", - "target": "controller_authentication_controller_googlecallback" + "source": "wallet_entries_updateentry", + "target": "wallet_wallets_getwallet" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/controller/authentication_controller.py", - "source_location": "L257", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/entries.py", + "source_location": "L134", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_authentication_controller_introspect", - "target": "controller_authentication_controller_requireservicetoken" + "source": "wallet_entries_updateentry", + "target": "wallet_wallets_getownedwallet" }, { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L5", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/entries.py", + "source_location": "L164", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_controller_orunmila_controller_py", - "target": "fastapi" + "source": "wallet_entries_deleteentry", + "target": "wallet_wallets_getwallet" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L26", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/entries.py", + "source_location": "L164", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_controller_orunmila_controller_py", - "target": "controller_orunmila_controller_verifysessionownsership" + "source": "wallet_entries_deleteentry", + "target": "wallet_wallets_getownedwallet" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L32", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L25", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_orunmila_controller_py", - "target": "controller_orunmila_controller_health" + "source": "main_app_wallet_market_data_py", + "target": "wallet_market_data_fetchliveprices" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L37", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L50", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_orunmila_controller_py", - "target": "controller_orunmila_controller_getsessions" + "source": "main_app_wallet_market_data_py", + "target": "wallet_market_data_fetchcachedclose" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L56", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L70", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_orunmila_controller_py", - "target": "controller_orunmila_controller_updatesessiontitle" + "source": "main_app_wallet_market_data_py", + "target": "wallet_market_data_fetchmarketdividends" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L71", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L88", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_orunmila_controller_py", - "target": "controller_orunmila_controller_gethistory" + "source": "main_app_wallet_market_data_py", + "target": "wallet_market_data_fetchpadraocloses" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L90", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L16", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_orunmila_controller_py", - "target": "controller_orunmila_controller_deletesession" + "source": "main_app_wallet_market_data_py", + "target": "wallet_market_data_stocksapibase" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L103", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L20", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_orunmila_controller_py", - "target": "controller_orunmila_controller_chat_stream" + "source": "main_app_wallet_market_data_py", + "target": "wallet_market_data_stocksapiheaders" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L154", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/positions.py", + "source_location": "L61", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_controller_orunmila_controller_py", - "target": "controller_orunmila_controller_resumechatstream" + "source": "wallet_positions_pricepass", + "target": "wallet_market_data_fetchliveprices" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L166", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L35", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_controller_orunmila_controller_py", - "target": "controller_orunmila_controller_deleteworkspacefile" + "source": "wallet_summary_getsummary", + "target": "wallet_market_data_fetchliveprices" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L179", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L93", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_controller_orunmila_controller_py", - "target": "controller_orunmila_controller_downloadworkspacefile" + "source": "wallet_summary_getallocation", + "target": "wallet_market_data_fetchliveprices" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L195", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/positions.py", + "source_location": "L84", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_controller_orunmila_controller_py", - "target": "controller_orunmila_controller_listworkspacefiles" + "source": "wallet_positions_getpositions", + "target": "wallet_market_data_fetchliveprices" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L62", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/positions.py", + "source_location": "L64", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_orunmila_controller_updatesessiontitle", - "target": "controller_orunmila_controller_verifysessionownsership" + "source": "wallet_positions_pricepass", + "target": "wallet_market_data_fetchcachedclose" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L76", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L39", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_orunmila_controller_gethistory", - "target": "controller_orunmila_controller_verifysessionownsership" + "source": "wallet_summary_getsummary", + "target": "wallet_market_data_fetchcachedclose" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L114", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L96", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_orunmila_controller_chat_stream", - "target": "controller_orunmila_controller_verifysessionownsership" + "source": "wallet_summary_getallocation", + "target": "wallet_market_data_fetchcachedclose" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L160", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/positions.py", + "source_location": "L87", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_orunmila_controller_resumechatstream", - "target": "controller_orunmila_controller_verifysessionownsership" + "source": "wallet_positions_getpositions", + "target": "wallet_market_data_fetchcachedclose" }, { - "relation": "imports_from", - "context": "import", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L2", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L53", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_stocksapi_controller_py", - "target": "fastapi" + "source": "wallet_market_data_fetchcachedclose", + "target": "wallet_market_data_stocksapibase" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L16", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L55", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_stocksapi_controller_py", - "target": "controller_stocksapi_controller_health" + "source": "wallet_market_data_fetchcachedclose", + "target": "wallet_market_data_stocksapiheaders" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L25", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L73", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_stocksapi_controller_py", - "target": "controller_stocksapi_controller_listfields" + "source": "wallet_market_data_fetchmarketdividends", + "target": "wallet_market_data_stocksapibase" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L24", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L75", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_stocksapi_controller_py", - "target": "controller_stocksapi_controller_gethistorical" + "source": "wallet_market_data_fetchmarketdividends", + "target": "wallet_market_data_stocksapiheaders" }, { - "relation": "contains", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/performance.py", + "source_location": "L47", + "weight": 1.0, + "source": "wallet_performance_cachedperformance", + "target": "wallet_market_data_fetchpadraocloses" + }, + { + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L35", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L91", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_stocksapi_controller_py", - "target": "controller_stocksapi_controller_getfundamental" + "source": "wallet_market_data_fetchpadraocloses", + "target": "wallet_market_data_stocksapibase" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L49", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L93", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_stocksapi_controller_py", - "target": "controller_stocksapi_controller_getcotations" + "source": "wallet_market_data_fetchpadraocloses", + "target": "wallet_market_data_stocksapiheaders" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L60", + "source_file": "main/app/wallet/performance.py", + "source_location": "L21", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_stocksapi_controller_py", - "target": "controller_stocksapi_controller_getlivecotation" + "source": "main_app_wallet_performance_py", + "target": "wallet_performance_cachedperformance" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L23", + "source_file": "main/app/wallet/performance.py", + "source_location": "L145", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_stocksapi_controller_py", - "target": "controller_stocksapi_controller_jsonbytesresponse" + "source": "main_app_wallet_performance_py", + "target": "wallet_performance_getperformance" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L46", + "source_file": "main/app/wallet/performance.py", + "source_location": "L175", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_stocksapi_controller_py", - "target": "controller_stocksapi_controller_generatekey" + "source": "wallet_performance_getperformance", + "target": "wallet_performance_cachedperformance" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/performance.py", + "source_location": "L148", + "weight": 1.0, + "source": "wallet_performance_getperformance", + "target": "wallet_wallets_getwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/performance.py", + "source_location": "L148", + "weight": 1.0, + "source": "wallet_performance_getperformance", + "target": "wallet_wallets_getownedwallet" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L63", + "source_file": "main/app/wallet/positions.py", + "source_location": "L17", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_stocksapi_controller_py", - "target": "controller_stocksapi_controller_getrealtimecotation" + "source": "main_app_wallet_positions_py", + "target": "wallet_positions_fetchxangoscores" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L20", + "source_file": "main/app/wallet/positions.py", + "source_location": "L49", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_controller_stocksapi_controller_py", - "target": "controller_stocksapi_controller_apikeytest" + "source": "main_app_wallet_positions_py", + "target": "wallet_positions_weightof", + "confidence_score": 1.0 }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L45", + "source_file": "main/app/wallet/positions.py", + "source_location": "L53", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_45", - "target": "controller_stocksapi_controller_listfields" + "source": "main_app_wallet_positions_py", + "target": "wallet_positions_pricepass", + "confidence_score": 1.0 }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L47", + "source_file": "main/app/wallet/positions.py", + "source_location": "L75", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_47", - "target": "controller_stocksapi_controller_listfields" + "source": "main_app_wallet_positions_py", + "target": "wallet_positions_rebalancedeltas", + "confidence_score": 1.0 }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L39", + "source_file": "main/app/wallet/positions.py", + "source_location": "L79", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_39", - "target": "controller_stocksapi_controller_listfields" + "source": "main_app_wallet_positions_py", + "target": "wallet_positions_getpositions" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L36", + "source_file": "main/app/wallet/positions.py", + "source_location": "L138", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_36", - "target": "controller_stocksapi_controller_listfields" + "source": "main_app_wallet_positions_py", + "target": "wallet_positions_getrebalance", + "confidence_score": 1.0 }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L40", + "source_file": "main/app/wallet/positions.py", + "source_location": "L29", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_40", - "target": "controller_stocksapi_controller_listfields" + "source": "main_app_wallet_positions_py", + "target": "wallet_positions_scorebuyflag" }, { "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L48", + "source_file": "main/app/wallet/positions.py", + "source_location": "L18", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_48", - "target": "controller_stocksapi_controller_listfields" + "source": "wallet_positions_rationale_18", + "target": "wallet_positions_fetchxangoscores" }, { - "relation": "rationale_for", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L49", + "source_file": "main/app/wallet/positions.py", + "source_location": "L101", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_49", - "target": "controller_stocksapi_controller_listfields" + "source": "wallet_positions_getpositions", + "target": "wallet_positions_fetchxangoscores" }, { "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L30", + "source_file": "main/app/wallet/positions.py", + "source_location": "L21", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_30", - "target": "controller_stocksapi_controller_listfields" + "source": "wallet_positions_rationale_21", + "target": "wallet_positions_fetchxangoscores" }, { "relation": "calls", "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L66", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/positions.py", + "source_location": "L79", "weight": 1.0, - "source": "controller_stocksapi_controller_listfields", - "target": "stocks_api_compressor_getnest" + "source": "wallet_positions_rebalancedeltas", + "target": "wallet_positions_weightof", + "confidence_score": 1.0 }, { - "relation": "rationale_for", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L27", + "source_file": "main/app/wallet/positions.py", + "source_location": "L141", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_27", - "target": "controller_stocksapi_controller_listfields" + "source": "wallet_positions_getrebalance", + "target": "wallet_positions_weightof", + "confidence_score": 1.0 }, { - "relation": "rationale_for", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L26", + "source_file": "main/app/wallet/positions.py", + "source_location": "L94", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_listfields", - "target": "controller_stocksapi_controller_rationale_26" + "source": "wallet_positions_getpositions", + "target": "wallet_positions_pricepass", + "confidence_score": 1.0 }, { - "relation": "rationale_for", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L102", + "source_file": "main/app/wallet/positions.py", + "source_location": "L139", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_102", - "target": "controller_stocksapi_controller_gethistorical" + "source": "wallet_positions_getrebalance", + "target": "wallet_positions_pricepass", + "confidence_score": 1.0 }, { "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L103", + "source_file": "main/app/wallet/positions.py", + "source_location": "L56", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_103", - "target": "controller_stocksapi_controller_gethistorical" + "source": "wallet_positions_rationale_56", + "target": "wallet_positions_pricepass", + "confidence_score": 1.0 }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L95", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/positions.py", + "source_location": "L57", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_95", - "target": "controller_stocksapi_controller_gethistorical" + "source": "wallet_positions_pricepass", + "target": "wallet_wallets_getwallet" }, { - "relation": "rationale_for", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L92", + "source_file": "main/app/wallet/positions.py", + "source_location": "L95", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_92", - "target": "controller_stocksapi_controller_gethistorical" + "source": "wallet_positions_getpositions", + "target": "wallet_positions_rebalancedeltas", + "confidence_score": 1.0 }, { - "relation": "rationale_for", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L96", + "source_file": "main/app/wallet/positions.py", + "source_location": "L140", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_96", - "target": "controller_stocksapi_controller_gethistorical" + "source": "wallet_positions_getrebalance", + "target": "wallet_positions_rebalancedeltas", + "confidence_score": 1.0 }, { "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L104", + "source_file": "main/app/wallet/positions.py", + "source_location": "L78", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_104", - "target": "controller_stocksapi_controller_gethistorical" + "source": "wallet_positions_rationale_78", + "target": "wallet_positions_rebalancedeltas", + "confidence_score": 1.0 }, { - "relation": "rationale_for", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L105", + "source_file": "main/app/wallet/positions.py", + "source_location": "L127", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_105", - "target": "controller_stocksapi_controller_gethistorical" + "source": "wallet_positions_getpositions", + "target": "wallet_positions_scorebuyflag" }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L85", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/positions.py", + "source_location": "L80", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_85", - "target": "controller_stocksapi_controller_gethistorical" + "source": "wallet_positions_getpositions", + "target": "wallet_wallets_getwallet" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L129", + "source_file": "main/app/wallet/positions.py", + "source_location": "L80", "weight": 1.0, - "source": "controller_stocksapi_controller_gethistorical", - "target": "stocks_api_compressor_compressresponse" + "source": "wallet_positions_getpositions", + "target": "wallet_wallets_getownedwallet" }, { - "relation": "rationale_for", + "relation": "imports_from", + "context": "import", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L82", + "source_file": "main/app/wallet/summary.py", + "source_location": "L6", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_82", - "target": "controller_stocksapi_controller_gethistorical" + "source": "main_app_wallet_summary_py", + "target": "fastapi" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L66", + "source_file": "main/app/wallet/summary.py", + "source_location": "L17", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_gethistorical", - "target": "controller_stocksapi_controller_rationale_66" + "source": "main_app_wallet_summary_py", + "target": "wallet_summary_targetupsert" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L65", + "source_file": "main/app/wallet/summary.py", + "source_location": "L24", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_gethistorical", - "target": "controller_stocksapi_controller_rationale_65" + "source": "main_app_wallet_summary_py", + "target": "wallet_summary_ratingupsert" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L173", + "source_file": "main/app/wallet/summary.py", + "source_location": "L30", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_173", - "target": "controller_stocksapi_controller_getfundamental" + "source": "main_app_wallet_summary_py", + "target": "wallet_summary_getsummary" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L167", + "source_file": "main/app/wallet/summary.py", + "source_location": "L88", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_167", - "target": "controller_stocksapi_controller_getfundamental" + "source": "main_app_wallet_summary_py", + "target": "wallet_summary_getallocation" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L168", + "source_file": "main/app/wallet/summary.py", + "source_location": "L118", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_168", - "target": "controller_stocksapi_controller_getfundamental" + "source": "main_app_wallet_summary_py", + "target": "wallet_summary_upserttarget" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L160", + "source_file": "main/app/wallet/summary.py", + "source_location": "L147", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_160", - "target": "controller_stocksapi_controller_getfundamental" + "source": "main_app_wallet_summary_py", + "target": "wallet_summary_set_rating" }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L157", - "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_157", - "target": "controller_stocksapi_controller_getfundamental" + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_targetupsert", + "target": "models_wallet_holding" }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L161", - "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_161", - "target": "controller_stocksapi_controller_getfundamental" + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_targetupsert", + "target": "models_wallet_snapshot" }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L169", - "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_169", - "target": "controller_stocksapi_controller_getfundamental" + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_targetupsert", + "target": "models_wallet_target" }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L165", - "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_165", - "target": "controller_stocksapi_controller_getfundamental" + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L13", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_walletcreate", + "target": "wallet_summary_targetupsert" }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L155", - "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_155", - "target": "controller_stocksapi_controller_getfundamental" + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L13", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_earningssync", + "target": "wallet_summary_targetupsert" }, { - "relation": "calls", - "context": "call", + "relation": "uses", "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L196", - "weight": 1.0, - "source": "controller_stocksapi_controller_getfundamental", - "target": "stocks_api_compressor_compressresponse" + "source_file": "main/app/wallet/summary.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_ratingupsert", + "target": "models_wallet_holding" }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L144", - "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_144", - "target": "controller_stocksapi_controller_getfundamental" + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_ratingupsert", + "target": "models_wallet_snapshot" }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L124", - "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_getfundamental", - "target": "controller_stocksapi_controller_rationale_124" + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_ratingupsert", + "target": "models_wallet_target" }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L123", + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L13", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_walletcreate", + "target": "wallet_summary_ratingupsert" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L13", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_earningssync", + "target": "wallet_summary_ratingupsert" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L31", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_getfundamental", - "target": "controller_stocksapi_controller_rationale_123" + "source": "wallet_summary_getsummary", + "target": "wallet_wallets_getwallet" }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L247", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L31", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_247", - "target": "controller_stocksapi_controller_getcotations" + "source": "wallet_summary_getsummary", + "target": "wallet_wallets_getownedwallet" }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L235", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L89", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_235", - "target": "controller_stocksapi_controller_getcotations" + "source": "wallet_summary_getallocation", + "target": "wallet_wallets_getwallet" }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L236", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L89", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_236", - "target": "controller_stocksapi_controller_getcotations" + "source": "wallet_summary_getallocation", + "target": "wallet_wallets_getownedwallet" }, { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L228", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L119", "weight": 1.0, - "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_228", - "target": "controller_stocksapi_controller_getcotations" + "source": "wallet_summary_upserttarget", + "target": "wallet_wallets_getwallet" }, { - "relation": "rationale_for", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L131", + "weight": 1.0, + "source": "wallet_summary_upserttarget", + "target": "models_wallet_target" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L119", + "weight": 1.0, + "source": "wallet_summary_upserttarget", + "target": "wallet_wallets_getownedwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L148", + "weight": 1.0, + "source": "wallet_summary_set_rating", + "target": "wallet_wallets_getwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L148", + "weight": 1.0, + "source": "wallet_summary_set_rating", + "target": "wallet_wallets_getownedwallet" + }, + { + "relation": "imports_from", + "context": "import", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L225", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L3", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_225", - "target": "controller_stocksapi_controller_getcotations" + "source": "main_app_wallet_wallets_py", + "target": "fastapi" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L229", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L11", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_229", - "target": "controller_stocksapi_controller_getcotations" + "source": "main_app_wallet_wallets_py", + "target": "wallet_wallets_getwallet" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L237", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L21", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_237", - "target": "controller_stocksapi_controller_getcotations" + "source": "main_app_wallet_wallets_py", + "target": "wallet_wallets_createwallet" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L234", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L29", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_234", - "target": "controller_stocksapi_controller_getcotations" + "source": "main_app_wallet_wallets_py", + "target": "wallet_wallets_listwallets" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L238", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L11", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_238", - "target": "controller_stocksapi_controller_getcotations" + "source": "main_app_wallet_wallets_py", + "target": "wallet_wallets_getownedwallet" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L250", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L22", "weight": 1.0, - "source": "controller_stocksapi_controller_getcotations", - "target": "stocks_api_compressor_compressresponse" + "source": "wallet_wallets_createwallet", + "target": "models_wallet_wallet" }, { - "relation": "rationale_for", + "relation": "imports_from", + "context": "import", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L209", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L6", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_209", - "target": "controller_stocksapi_controller_getcotations" + "source": "main_controller_authentication_controller_py", + "target": "fastapi" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L185", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L20", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_getcotations", - "target": "controller_stocksapi_controller_rationale_185" + "source": "main_controller_authentication_controller_py", + "target": "controller_authentication_controller_issecurescheme" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L184", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L44", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_getcotations", - "target": "controller_stocksapi_controller_rationale_184" + "source": "main_controller_authentication_controller_py", + "target": "controller_authentication_controller_resolvecookiedomain" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L307", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L32", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_307", - "target": "controller_stocksapi_controller_getlivecotation" + "source": "main_controller_authentication_controller_py", + "target": "controller_authentication_controller_issuesessioncookie" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L289", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L24", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_289", - "target": "controller_stocksapi_controller_getlivecotation" + "source": "main_controller_authentication_controller_py", + "target": "controller_authentication_controller_health" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L290", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L29", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_290", - "target": "controller_stocksapi_controller_getlivecotation" + "source": "main_controller_authentication_controller_py", + "target": "controller_authentication_controller_register" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L282", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L71", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_282", - "target": "controller_stocksapi_controller_getlivecotation" + "source": "main_controller_authentication_controller_py", + "target": "controller_authentication_controller_login" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L279", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L100", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_279", - "target": "controller_stocksapi_controller_getlivecotation" + "source": "main_controller_authentication_controller_py", + "target": "controller_authentication_controller_logout" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L283", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L253", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_283", - "target": "controller_stocksapi_controller_getlivecotation" + "source": "main_controller_authentication_controller_py", + "target": "controller_authentication_controller_introspect" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L291", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L131", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_291", - "target": "controller_stocksapi_controller_getlivecotation" + "source": "main_controller_authentication_controller_py", + "target": "controller_authentication_controller_googlelogin" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L288", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L146", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_288", - "target": "controller_stocksapi_controller_getlivecotation" + "source": "main_controller_authentication_controller_py", + "target": "controller_authentication_controller_googlecallback" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L296", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L245", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_296", - "target": "controller_stocksapi_controller_getlivecotation" + "source": "main_controller_authentication_controller_py", + "target": "controller_authentication_controller_requireservicetoken" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L286", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L277", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_286", - "target": "controller_stocksapi_controller_getlivecotation" + "source": "main_controller_authentication_controller_py", + "target": "controller_authentication_controller_verifyservicekey" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L39", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_authentication_controller_issecurescheme", + "target": "controller_authentication_controller_issuesessioncookie" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L123", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_authentication_controller_issecurescheme", + "target": "controller_authentication_controller_logout" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L293", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L114", "weight": 1.0, - "source": "controller_stocksapi_controller_getlivecotation", - "target": "stocks_api_compressor_compressresponse" + "source": "controller_authentication_controller_issecurescheme", + "target": "tests_test_controllers_coverage_testissecurescheme_test_is_secure_https" }, { - "relation": "rationale_for", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L121", + "weight": 1.0, + "source": "controller_authentication_controller_issecurescheme", + "target": "tests_test_controllers_coverage_testissecurescheme_test_is_secure_http" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L128", + "weight": 1.0, + "source": "controller_authentication_controller_issecurescheme", + "target": "tests_test_controllers_coverage_testissecurescheme_test_is_secure_no_scheme" + }, + { + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L261", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L49", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_rationale_261", - "target": "controller_stocksapi_controller_getlivecotation" + "source": "controller_authentication_controller_issecurescheme", + "target": "controller_authentication_controller_register" }, { - "relation": "rationale_for", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L233", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L87", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_getlivecotation", - "target": "controller_stocksapi_controller_rationale_233" + "source": "controller_authentication_controller_issecurescheme", + "target": "controller_authentication_controller_login" }, { - "relation": "rationale_for", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/stocksapi_controller.py", - "source_location": "L232", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L176", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_stocksapi_controller_getlivecotation", - "target": "controller_stocksapi_controller_rationale_232" + "source": "controller_authentication_controller_issecurescheme", + "target": "controller_authentication_controller_googlecallback" }, { - "relation": "imports_from", - "context": "import", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/user_controller.py", - "source_location": "L7", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L58", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_user_controller_py", - "target": "fastapi" + "source": "controller_authentication_controller_issuesessioncookie", + "target": "controller_authentication_controller_resolvecookiedomain" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/user_controller.py", - "source_location": "L16", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L160", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_user_controller_py", - "target": "controller_user_controller_sessiontodict" + "source": "controller_authentication_controller_logout", + "target": "controller_authentication_controller_resolvecookiedomain" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/user_controller.py", - "source_location": "L15", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L81", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_user_controller_py", - "target": "controller_user_controller_health" + "source": "controller_authentication_controller_issuesessioncookie", + "target": "controller_authentication_controller_register" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/user_controller.py", - "source_location": "L19", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L107", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_user_controller_py", - "target": "controller_user_controller_getme" + "source": "controller_authentication_controller_issuesessioncookie", + "target": "controller_authentication_controller_login" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/user_controller.py", - "source_location": "L45", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L186", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_user_controller_py", - "target": "controller_user_controller_testadminaccess" + "source": "controller_authentication_controller_issuesessioncookie", + "target": "controller_authentication_controller_googlecallback" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/controller/user_controller.py", - "source_location": "L52", + "source_file": "main/controller/authentication_controller.py", + "source_location": "L257", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_user_controller_py", - "target": "controller_user_controller_getsessions" + "source": "controller_authentication_controller_introspect", + "target": "controller_authentication_controller_requireservicetoken" }, { - "relation": "contains", + "relation": "imports_from", + "context": "import", "confidence": "EXTRACTED", - "source_file": "main/controller/user_controller.py", - "source_location": "L94", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L5", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_user_controller_py", - "target": "controller_user_controller_getcurrentsession" + "source": "main_controller_orunmila_controller_py", + "target": "fastapi" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/user_controller.py", - "source_location": "L115", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L26", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_user_controller_py", - "target": "controller_user_controller_revokesession" + "source": "main_controller_orunmila_controller_py", + "target": "controller_orunmila_controller_verifysessionownsership" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/user_controller.py", - "source_location": "L135", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L32", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_user_controller_py", - "target": "controller_user_controller_revokeallsessions" + "source": "main_controller_orunmila_controller_py", + "target": "controller_orunmila_controller_health" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/user_controller.py", - "source_location": "L23", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L37", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_user_controller_py", - "target": "controller_user_controller_upgradetodeveloperstarter" + "source": "main_controller_orunmila_controller_py", + "target": "controller_orunmila_controller_getsessions" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/user_controller.py", - "source_location": "L34", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L56", "weight": 1.0, "confidence_score": 1.0, - "source": "main_controller_user_controller_py", - "target": "controller_user_controller_upgradetodeveloperenterprise" + "source": "main_controller_orunmila_controller_py", + "target": "controller_orunmila_controller_updatesessiontitle" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/user_controller.py", - "source_location": "L67", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L71", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_user_controller_getsessions", - "target": "controller_user_controller_sessiontodict" + "source": "main_controller_orunmila_controller_py", + "target": "controller_orunmila_controller_gethistory" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/controller/user_controller.py", - "source_location": "L87", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L90", "weight": 1.0, "confidence_score": 1.0, - "source": "controller_user_controller_getcurrentsession", - "target": "controller_user_controller_sessiontodict" + "source": "main_controller_orunmila_controller_py", + "target": "controller_orunmila_controller_deletesession" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/memory.py", - "source_location": "L8", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L103", "weight": 1.0, "confidence_score": 1.0, - "source": "main_models_memory_py", - "target": "models_memory_orunmilamemory" + "source": "main_controller_orunmila_controller_py", + "target": "controller_orunmila_controller_chat_stream" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/memory.py", - "source_location": "L7", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L154", "weight": 1.0, "confidence_score": 1.0, - "source": "main_models_memory_py", - "target": "models_memory_prometheusmemory" + "source": "main_controller_orunmila_controller_py", + "target": "controller_orunmila_controller_resumechatstream" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/memory.py", - "source_location": "L7", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L166", "weight": 1.0, "confidence_score": 1.0, - "source": "main_models_memory_py", - "target": "models_memory_usermemory" + "source": "main_controller_orunmila_controller_py", + "target": "controller_orunmila_controller_deleteworkspacefile" }, { - "relation": "inherits", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/memory.py", - "source_location": "L8", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L179", "weight": 1.0, "confidence_score": 1.0, - "source": "models_memory_orunmilamemory", - "target": "base" - }, - { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/models/memory.py", - "source_location": "L4", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_memory_orunmilamemory", - "target": "models_types_vectortype" - }, - { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/models/memory.py", - "source_location": "L5", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_memory_orunmilamemory", - "target": "models_user_user" + "source": "main_controller_orunmila_controller_py", + "target": "controller_orunmila_controller_downloadworkspacefile" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/service/orunmila_service.py", - "source_location": "L9", - "weight": 0.8, - "confidence_score": 0.5, - "source": "service_orunmila_service_orunmilaservice", - "target": "models_memory_orunmilamemory" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L195", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_controller_orunmila_controller_py", + "target": "controller_orunmila_controller_listworkspacefiles" }, { - "relation": "inherits", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/models/orunmila.py", - "source_location": "L7", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L62", "weight": 1.0, "confidence_score": 1.0, - "source": "models_orunmila_orunmilasession", - "target": "base" + "source": "controller_orunmila_controller_updatesessiontitle", + "target": "controller_orunmila_controller_verifysessionownsership" }, { - "relation": "inherits", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/models/sandbox.py", - "source_location": "L5", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L76", "weight": 1.0, "confidence_score": 1.0, - "source": "models_sandbox_orunmilasandbox", - "target": "base" + "source": "controller_orunmila_controller_gethistory", + "target": "controller_orunmila_controller_verifysessionownsership" }, { - "relation": "inherits", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/models/stocksapi_key.py", - "source_location": "L7", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L114", "weight": 1.0, "confidence_score": 1.0, - "source": "base", - "target": "models_stocksapi_key_stocksapikey" + "source": "controller_orunmila_controller_chat_stream", + "target": "controller_orunmila_controller_verifysessionownsership" }, { - "relation": "inherits", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/models/user.py", - "source_location": "L5", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L160", "weight": 1.0, "confidence_score": 1.0, - "source": "base", - "target": "models_user_user" + "source": "controller_orunmila_controller_resumechatstream", + "target": "controller_orunmila_controller_verifysessionownsership" }, { - "relation": "inherits", + "relation": "imports_from", + "context": "import", "confidence": "EXTRACTED", - "source_file": "main/models/user_session.py", - "source_location": "L5", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L2", "weight": 1.0, "confidence_score": 1.0, - "source": "base", - "target": "models_user_session_usersession" + "source": "main_controller_stocksapi_controller_py", + "target": "fastapi" }, { - "relation": "inherits", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/memory.py", - "source_location": "L7", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L16", "weight": 1.0, "confidence_score": 1.0, - "source": "models_memory_prometheusmemory", - "target": "base" + "source": "main_controller_stocksapi_controller_py", + "target": "controller_stocksapi_controller_health" }, { - "relation": "inherits", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/prometheus.py", - "source_location": "L5", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L25", "weight": 1.0, "confidence_score": 1.0, - "source": "base", - "target": "models_prometheus_prometheussession" + "source": "main_controller_stocksapi_controller_py", + "target": "controller_stocksapi_controller_listfields" }, { - "relation": "inherits", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/sandbox.py", - "source_location": "L5", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L24", "weight": 1.0, "confidence_score": 1.0, - "source": "base", - "target": "models_sandbox_prometheussandbox" + "source": "main_controller_stocksapi_controller_py", + "target": "controller_stocksapi_controller_gethistorical" }, { - "relation": "inherits", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/memory.py", - "source_location": "L7", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L35", "weight": 1.0, "confidence_score": 1.0, - "source": "base", - "target": "models_memory_usermemory" + "source": "main_controller_stocksapi_controller_py", + "target": "controller_stocksapi_controller_getfundamental" }, { - "relation": "inherits", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/harness.py", - "source_location": "L7", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L49", "weight": 1.0, "confidence_score": 1.0, - "source": "base", - "target": "models_harness_loopevent" + "source": "main_controller_stocksapi_controller_py", + "target": "controller_stocksapi_controller_getcotations" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/orunmila.py", - "source_location": "L7", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L60", "weight": 1.0, "confidence_score": 1.0, - "source": "main_models_orunmila_py", - "target": "models_orunmila_orunmilasession" + "source": "main_controller_stocksapi_controller_py", + "target": "controller_stocksapi_controller_getlivecotation" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/models/orunmila.py", - "source_location": "L4", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_orunmila_orunmilasession", - "target": "models_user_user" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L23", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_controller_stocksapi_controller_py", + "target": "controller_stocksapi_controller_jsonbytesresponse" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/sandbox.py", - "source_location": "L5", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L46", "weight": 1.0, "confidence_score": 1.0, - "source": "main_models_sandbox_py", - "target": "models_sandbox_orunmilasandbox" + "source": "main_controller_stocksapi_controller_py", + "target": "controller_stocksapi_controller_generatekey" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/sandbox.py", - "source_location": "L5", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L63", "weight": 1.0, "confidence_score": 1.0, - "source": "main_models_sandbox_py", - "target": "models_sandbox_prometheussandbox" + "source": "main_controller_stocksapi_controller_py", + "target": "controller_stocksapi_controller_getrealtimecotation" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/stocksapi_key.py", - "source_location": "L7", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L20", "weight": 1.0, "confidence_score": 1.0, - "source": "main_models_stocksapi_key_py", - "target": "models_stocksapi_key_stocksapikey" + "source": "main_controller_stocksapi_controller_py", + "target": "controller_stocksapi_controller_apikeytest" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/models/stocksapi_key.py", - "source_location": "L4", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_stocksapi_key_stocksapikey", - "target": "models_user_user" + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L45", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_45", + "target": "controller_stocksapi_controller_listfields" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/stocks_api/key.py", - "source_location": "L58", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L47", "weight": 1.0, - "source": "stocks_api_key_createkey", - "target": "models_stocksapi_key_stocksapikey" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_47", + "target": "controller_stocksapi_controller_listfields" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_api_key_quota_atomic.py", - "source_location": "L15", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement" + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L39", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_39", + "target": "controller_stocksapi_controller_listfields" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_api_key_quota_atomic.py", - "source_location": "L15", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_api_key_quota_atomic_testverifyapikeyintegration" + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L36", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_36", + "target": "controller_stocksapi_controller_listfields" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_models.py", - "source_location": "L3", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_testusermodel" + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L40", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_40", + "target": "controller_stocksapi_controller_listfields" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_models.py", - "source_location": "L3", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_teststocksapikeymodel" + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L48", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_48", + "target": "controller_stocksapi_controller_listfields" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_models.py", - "source_location": "L3", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_testprometheussessionmodel" + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L49", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_49", + "target": "controller_stocksapi_controller_listfields" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_api_key_quota_atomic.py", - "source_location": "L43", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L30", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_normal_quota_check_works" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_30", + "target": "controller_stocksapi_controller_listfields" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_api_key_quota_atomic.py", - "source_location": "L70", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L66", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_atomic_increment_prevents_overuse" + "source": "controller_stocksapi_controller_listfields", + "target": "stocks_api_compressor_getnest" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_api_key_quota_atomic.py", - "source_location": "L111", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L27", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_concurrent_requests_serialized_at_db_level" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_27", + "target": "controller_stocksapi_controller_listfields" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_api_key_quota_atomic.py", - "source_location": "L145", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L26", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_request_at_exact_quota_limit" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_listfields", + "target": "controller_stocksapi_controller_rationale_26" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_api_key_quota_atomic.py", - "source_location": "L181", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L102", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_multiple_keys_independent_quotas" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_102", + "target": "controller_stocksapi_controller_gethistorical" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_api_key_quota_atomic.py", - "source_location": "L216", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L103", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_increment_from_zero" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_103", + "target": "controller_stocksapi_controller_gethistorical" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_api_key_quota_atomic.py", - "source_location": "L240", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L95", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_api_key_quota_atomic_testverifyapikeyintegration_test_verify_api_key_success" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_95", + "target": "controller_stocksapi_controller_gethistorical" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_api_key_quota_atomic.py", - "source_location": "L255", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L92", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_api_key_quota_atomic_testverifyapikeyintegration_test_verify_api_key_quota_exceeded" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_92", + "target": "controller_stocksapi_controller_gethistorical" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L92", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L96", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_teststocksapikeymodel_test_create_api_key" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_96", + "target": "controller_stocksapi_controller_gethistorical" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L101", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L104", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_teststocksapikeymodel_test_is_quota_exceeded_true" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_104", + "target": "controller_stocksapi_controller_gethistorical" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L107", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L105", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_teststocksapikeymodel_test_is_quota_exceeded_false" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_105", + "target": "controller_stocksapi_controller_gethistorical" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L113", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L85", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_teststocksapikeymodel_test_needs_reset_true_no_last_reset" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_85", + "target": "controller_stocksapi_controller_gethistorical" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L118", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L129", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_teststocksapikeymodel_test_needs_reset_true_expired" + "source": "controller_stocksapi_controller_gethistorical", + "target": "stocks_api_compressor_compressresponse" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L124", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L82", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_teststocksapikeymodel_test_needs_reset_false_recent" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_82", + "target": "controller_stocksapi_controller_gethistorical" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L130", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L66", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_teststocksapikeymodel_test_reset_quota" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_gethistorical", + "target": "controller_stocksapi_controller_rationale_66" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L138", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L65", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_teststocksapikeymodel_test_increment_usage" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_gethistorical", + "target": "controller_stocksapi_controller_rationale_65" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L144", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L173", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_teststocksapikeymodel_test_get_remaining_quota" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_173", + "target": "controller_stocksapi_controller_getfundamental" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L150", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L167", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_teststocksapikeymodel_test_get_remaining_quota_exceeded" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_167", + "target": "controller_stocksapi_controller_getfundamental" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L156", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L168", "weight": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "tests_test_models_teststocksapikeymodel_test_toDict" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_168", + "target": "controller_stocksapi_controller_getfundamental" }, { - "relation": "method", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/stocksapi_key.py", - "source_location": "L21", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L160", "weight": 1.0, "confidence_score": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "models_stocksapi_key_stocksapikey_isquotaexceeded" + "source": "controller_stocksapi_controller_rationale_160", + "target": "controller_stocksapi_controller_getfundamental" }, { - "relation": "method", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/stocksapi_key.py", - "source_location": "L24", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L157", "weight": 1.0, "confidence_score": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "models_stocksapi_key_stocksapikey_needsreset" + "source": "controller_stocksapi_controller_rationale_157", + "target": "controller_stocksapi_controller_getfundamental" }, { - "relation": "method", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/stocksapi_key.py", - "source_location": "L32", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L161", "weight": 1.0, "confidence_score": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "models_stocksapi_key_stocksapikey_resetquota" + "source": "controller_stocksapi_controller_rationale_161", + "target": "controller_stocksapi_controller_getfundamental" }, { - "relation": "method", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/stocksapi_key.py", - "source_location": "L36", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L169", "weight": 1.0, "confidence_score": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "models_stocksapi_key_stocksapikey_incrementusage" + "source": "controller_stocksapi_controller_rationale_169", + "target": "controller_stocksapi_controller_getfundamental" }, { - "relation": "method", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/stocksapi_key.py", - "source_location": "L39", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L165", "weight": 1.0, "confidence_score": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "models_stocksapi_key_stocksapikey_getremainingquota" + "source": "controller_stocksapi_controller_rationale_165", + "target": "controller_stocksapi_controller_getfundamental" }, { - "relation": "method", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/stocksapi_key.py", - "source_location": "L42", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L155", "weight": 1.0, "confidence_score": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "models_stocksapi_key_stocksapikey_todict" + "source": "controller_stocksapi_controller_rationale_155", + "target": "controller_stocksapi_controller_getfundamental" }, { - "relation": "method", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L196", + "weight": 1.0, + "source": "controller_stocksapi_controller_getfundamental", + "target": "stocks_api_compressor_compressresponse" + }, + { + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/stocksapi_key.py", - "source_location": "L18", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L144", "weight": 1.0, "confidence_score": 1.0, - "source": "models_stocksapi_key_stocksapikey", - "target": "models_stocksapi_key_stocksapikey_repr" + "source": "controller_stocksapi_controller_rationale_144", + "target": "controller_stocksapi_controller_getfundamental" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/types.py", - "source_location": "L5", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L124", "weight": 1.0, "confidence_score": 1.0, - "source": "main_models_types_py", - "target": "models_types_vectortype" + "source": "controller_stocksapi_controller_getfundamental", + "target": "controller_stocksapi_controller_rationale_124" }, { - "relation": "inherits", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/types.py", - "source_location": "L5", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L123", "weight": 1.0, "confidence_score": 1.0, - "source": "models_types_vectortype", - "target": "typedecorator" + "source": "controller_stocksapi_controller_getfundamental", + "target": "controller_stocksapi_controller_rationale_123" }, { - "relation": "method", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/types.py", - "source_location": "L9", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L247", "weight": 1.0, "confidence_score": 1.0, - "source": "models_types_vectortype", - "target": "models_types_vectortype_init" + "source": "controller_stocksapi_controller_rationale_247", + "target": "controller_stocksapi_controller_getcotations" }, { - "relation": "method", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/types.py", - "source_location": "L13", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L235", "weight": 1.0, "confidence_score": 1.0, - "source": "models_types_vectortype", - "target": "models_types_vectortype_process_bind_param" + "source": "controller_stocksapi_controller_rationale_235", + "target": "controller_stocksapi_controller_getcotations" }, { - "relation": "method", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/types.py", - "source_location": "L21", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L236", "weight": 1.0, "confidence_score": 1.0, - "source": "models_types_vectortype", - "target": "models_types_vectortype_process_result_value" + "source": "controller_stocksapi_controller_rationale_236", + "target": "controller_stocksapi_controller_getcotations" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/models/memory.py", - "source_location": "L4", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_memory_prometheusmemory", - "target": "models_types_vectortype" + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L228", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_228", + "target": "controller_stocksapi_controller_getcotations" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_memory_types.py", - "source_location": "L3", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_types_vectortype", - "target": "tests_test_memory_types_testvectortype" + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L225", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_225", + "target": "controller_stocksapi_controller_getcotations" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_memory_types.py", - "source_location": "L9", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L229", "weight": 1.0, - "source": "models_types_vectortype", - "target": "tests_test_memory_types_testvectortype_test_roundtrip" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_229", + "target": "controller_stocksapi_controller_getcotations" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_memory_types.py", - "source_location": "L19", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L237", "weight": 1.0, - "source": "models_types_vectortype", - "target": "tests_test_memory_types_testvectortype_test_none_roundtrip" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_237", + "target": "controller_stocksapi_controller_getcotations" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_memory_types.py", - "source_location": "L25", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L234", "weight": 1.0, - "source": "models_types_vectortype", - "target": "tests_test_memory_types_testvectortype_test_wrong_dims_raises" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_234", + "target": "controller_stocksapi_controller_getcotations" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_memory_types.py", - "source_location": "L31", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L238", "weight": 1.0, - "source": "models_types_vectortype", - "target": "tests_test_memory_types_testvectortype_test_preserves_negative_values" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_238", + "target": "controller_stocksapi_controller_getcotations" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_memory_types.py", - "source_location": "L39", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L250", "weight": 1.0, - "source": "models_types_vectortype", - "target": "tests_test_memory_types_testvectortype_test_large_random_vector" - }, - { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/models/memory.py", - "source_location": "L4", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_types_vectortype", - "target": "models_memory_usermemory" + "source": "controller_stocksapi_controller_getcotations", + "target": "stocks_api_compressor_compressresponse" }, { - "relation": "inherits", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/memory_types.py", - "source_location": "L5", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L209", "weight": 1.0, "confidence_score": 1.0, - "source": "typedecorator", - "target": "models_memory_types_vectortype" + "source": "controller_stocksapi_controller_rationale_209", + "target": "controller_stocksapi_controller_getcotations" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/user.py", - "source_location": "L5", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L185", "weight": 1.0, "confidence_score": 1.0, - "source": "main_models_user_py", - "target": "models_user_user" - }, - { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/models/user_session.py", - "source_location": "L4", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_user_session_usersession", - "target": "models_user_user" - }, - { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/models/memory.py", - "source_location": "L5", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_memory_prometheusmemory", - "target": "models_user_user" + "source": "controller_stocksapi_controller_getcotations", + "target": "controller_stocksapi_controller_rationale_185" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/models/prometheus.py", - "source_location": "L4", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_prometheus_prometheussession", - "target": "models_user_user" + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L184", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_getcotations", + "target": "controller_stocksapi_controller_rationale_184" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_models.py", - "source_location": "L2", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_user_user", - "target": "tests_test_models_testusermodel" + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L307", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_307", + "target": "controller_stocksapi_controller_getlivecotation" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_models.py", - "source_location": "L2", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_user_user", - "target": "tests_test_models_teststocksapikeymodel" + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L289", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_289", + "target": "controller_stocksapi_controller_getlivecotation" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_models.py", - "source_location": "L2", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_user_user", - "target": "tests_test_models_testprometheussessionmodel" + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L290", + "weight": 1.0, + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_290", + "target": "controller_stocksapi_controller_getlivecotation" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L9", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L282", "weight": 1.0, - "source": "models_user_user", - "target": "tests_test_models_testusermodel_test_create_user" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_282", + "target": "controller_stocksapi_controller_getlivecotation" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L19", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L279", "weight": 1.0, - "source": "models_user_user", - "target": "tests_test_models_testusermodel_test_get_roles_list_default" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_279", + "target": "controller_stocksapi_controller_getlivecotation" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L24", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L283", "weight": 1.0, - "source": "models_user_user", - "target": "tests_test_models_testusermodel_test_get_roles_list_single_role" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_283", + "target": "controller_stocksapi_controller_getlivecotation" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L29", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L291", "weight": 1.0, - "source": "models_user_user", - "target": "tests_test_models_testusermodel_test_get_roles_list_multiple_roles" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_291", + "target": "controller_stocksapi_controller_getlivecotation" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L37", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L288", "weight": 1.0, - "source": "models_user_user", - "target": "tests_test_models_testusermodel_test_add_role_new" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_288", + "target": "controller_stocksapi_controller_getlivecotation" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L43", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L296", "weight": 1.0, - "source": "models_user_user", - "target": "tests_test_models_testusermodel_test_add_role_existing" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_296", + "target": "controller_stocksapi_controller_getlivecotation" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L63", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L286", "weight": 1.0, - "source": "models_user_user", - "target": "tests_test_models_testusermodel_test_has_role_true" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_286", + "target": "controller_stocksapi_controller_getlivecotation" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L68", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L293", "weight": 1.0, - "source": "models_user_user", - "target": "tests_test_models_testusermodel_test_has_role_false" + "source": "controller_stocksapi_controller_getlivecotation", + "target": "stocks_api_compressor_compressresponse" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L75", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L261", "weight": 1.0, - "source": "models_user_user", - "target": "tests_test_models_testusermodel_test_has_role_with_enum" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_rationale_261", + "target": "controller_stocksapi_controller_getlivecotation" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L80", + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L233", "weight": 1.0, - "source": "models_user_user", - "target": "tests_test_models_testusermodel_test_toDict" + "confidence_score": 1.0, + "source": "controller_stocksapi_controller_getlivecotation", + "target": "controller_stocksapi_controller_rationale_233" }, { - "relation": "method", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/models/user.py", - "source_location": "L22", + "source_file": "main/controller/stocksapi_controller.py", + "source_location": "L232", "weight": 1.0, "confidence_score": 1.0, - "source": "models_user_user", - "target": "models_user_user_getroleslist" + "source": "controller_stocksapi_controller_getlivecotation", + "target": "controller_stocksapi_controller_rationale_232" }, { - "relation": "method", + "relation": "imports_from", + "context": "import", "confidence": "EXTRACTED", - "source_file": "main/models/user.py", - "source_location": "L27", + "source_file": "main/controller/user_controller.py", + "source_location": "L7", "weight": 1.0, "confidence_score": 1.0, - "source": "models_user_user", - "target": "models_user_user_addrole" + "source": "main_controller_user_controller_py", + "target": "fastapi" }, { - "relation": "method", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/user.py", - "source_location": "L43", + "source_file": "main/controller/user_controller.py", + "source_location": "L16", "weight": 1.0, "confidence_score": 1.0, - "source": "models_user_user", - "target": "models_user_user_hasrole" + "source": "main_controller_user_controller_py", + "target": "controller_user_controller_sessiontodict" }, { - "relation": "method", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/user.py", - "source_location": "L48", + "source_file": "main/controller/user_controller.py", + "source_location": "L15", "weight": 1.0, "confidence_score": 1.0, - "source": "models_user_user", - "target": "models_user_user_todict" + "source": "main_controller_user_controller_py", + "target": "controller_user_controller_health" }, { - "relation": "method", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/user.py", + "source_file": "main/controller/user_controller.py", "source_location": "L19", "weight": 1.0, "confidence_score": 1.0, - "source": "models_user_user", - "target": "models_user_user_repr" + "source": "main_controller_user_controller_py", + "target": "controller_user_controller_getme" }, { - "relation": "method", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/user.py", - "source_location": "L35", + "source_file": "main/controller/user_controller.py", + "source_location": "L45", "weight": 1.0, "confidence_score": 1.0, - "source": "models_user_user", - "target": "models_user_user_removerole" + "source": "main_controller_user_controller_py", + "target": "controller_user_controller_testadminaccess" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L50", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/user_controller.py", + "source_location": "L52", "weight": 1.0, - "source": "models_user_user", - "target": "tests_test_models_testusermodel_test_remove_role_existing" + "confidence_score": 1.0, + "source": "main_controller_user_controller_py", + "target": "controller_user_controller_getsessions" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_models.py", - "source_location": "L57", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/user_controller.py", + "source_location": "L94", "weight": 1.0, - "source": "models_user_user", - "target": "tests_test_models_testusermodel_test_remove_role_last_role" + "confidence_score": 1.0, + "source": "main_controller_user_controller_py", + "target": "controller_user_controller_getcurrentsession" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/user_session.py", - "source_location": "L5", + "source_file": "main/controller/user_controller.py", + "source_location": "L115", "weight": 1.0, "confidence_score": 1.0, - "source": "main_models_user_session_py", - "target": "models_user_session_usersession" - }, - { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/service/user_service.py", - "source_location": "L8", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_user_session_usersession", - "target": "service_user_service_userservice" - }, - { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_sessions.py", - "source_location": "L7", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testusersessionmodel" - }, - { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_sessions.py", - "source_location": "L8", - "weight": 0.8, - "confidence_score": 0.5, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testsessionexpiration" + "source": "main_controller_user_controller_py", + "target": "controller_user_controller_revokesession" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L56", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/user_controller.py", + "source_location": "L135", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testusersessionmodel_test_getdevicename_with_browser_and_os" + "confidence_score": 1.0, + "source": "main_controller_user_controller_py", + "target": "controller_user_controller_revokeallsessions" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L69", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/user_controller.py", + "source_location": "L23", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testusersessionmodel_test_getdevicename_with_fingerprint_only" + "confidence_score": 1.0, + "source": "main_controller_user_controller_py", + "target": "controller_user_controller_upgradetodeveloperstarter" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L81", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/user_controller.py", + "source_location": "L34", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testusersessionmodel_test_getdevicename_fallback" + "confidence_score": 1.0, + "source": "main_controller_user_controller_py", + "target": "controller_user_controller_upgradetodeveloperenterprise" }, { "relation": "calls", "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L94", + "confidence": "EXTRACTED", + "source_file": "main/controller/user_controller.py", + "source_location": "L67", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testusersessionmodel_test_getdevicename_empty_strings" + "confidence_score": 1.0, + "source": "controller_user_controller_getsessions", + "target": "controller_user_controller_sessiontodict" }, { "relation": "calls", "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L108", + "confidence": "EXTRACTED", + "source_file": "main/controller/user_controller.py", + "source_location": "L87", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testusersessionmodel_test_isactive_default" + "confidence_score": 1.0, + "source": "controller_user_controller_getcurrentsession", + "target": "controller_user_controller_sessiontodict" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L112", + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L3", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testusersessionmodel_test_isactive_can_be_false" + "confidence_score": 1.0, + "source": "main_controller_wallet_controller_py", + "target": "fastapi" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L156", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L17", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testsessionexpiration_test_session_can_expire" + "confidence_score": 1.0, + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_walletcreate" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L175", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L22", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testsessionexpiration_test_session_still_valid_within_expiry" + "confidence_score": 1.0, + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_create_wallet_route" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L193", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L32", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testsessionexpiration_test_session_exactly_at_boundary" + "confidence_score": 1.0, + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_list_wallets_route" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L210", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L42", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testsessionexpiration_test_created_at_future_date" + "confidence_score": 1.0, + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_serialize_holding" }, { - "relation": "method", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/user_session.py", - "source_location": "L38", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L48", "weight": 1.0, "confidence_score": 1.0, - "source": "models_user_session_usersession", - "target": "models_user_session_usersession_getdevicename" + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_serialize_entry" }, { - "relation": "method", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/user_session.py", - "source_location": "L22", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L63", "weight": 1.0, "confidence_score": 1.0, - "source": "models_user_session_usersession", - "target": "models_user_session_usersession_repr" + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_create_entry_route" }, { - "relation": "method", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/models/user_session.py", - "source_location": "L25", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L73", "weight": 1.0, "confidence_score": 1.0, - "source": "models_user_session_usersession", - "target": "models_user_session_usersession_todict" + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_list_entries_route" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L12", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L86", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testusersessionmodel_test_repr" + "confidence_score": 1.0, + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_update_entry_route" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L17", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L97", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testusersessionmodel_test_toDict_basic" + "confidence_score": 1.0, + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_delete_entry_route" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L34", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L107", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testusersessionmodel_test_toDict_with_sensitive" + "confidence_score": 1.0, + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_list_positions_route" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L45", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L119", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testusersessionmodel_test_toDict_hides_useragent" + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_get_rebalance_route", + "confidence_score": 1.0 }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L118", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L117", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testusersessionmodel_test_todict_with_timestamps" + "confidence_score": 1.0, + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_get_summary_route" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_sessions.py", - "source_location": "L132", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L126", "weight": 1.0, - "source": "models_user_session_usersession", - "target": "tests_test_sessions_testusersessionmodel_test_todict_without_timestamps" + "confidence_score": 1.0, + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_get_allocation_route" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/service/authentication_service.py", - "source_location": "L9", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L136", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_authentication_service_py", - "target": "service_authentication_service_authenticationservice" + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_upsert_target_route" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/service/authentication_service.py", - "source_location": "L11", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L151", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_authentication_service_py", - "target": "service_authentication_service_initialize" + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_set_rating_route" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/service/authentication_service.py", - "source_location": "L6", - "weight": 0.8, - "confidence_score": 0.5, - "source": "service_authentication_service_authenticationservice", - "target": "utils_service_manager_servicemanager" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L160", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_earningssync" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/service/authentication_service.py", - "source_location": "L12", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L164", "weight": 1.0, - "source": "service_authentication_service_initialize", - "target": "utils_service_manager_getapp" + "confidence_score": 1.0, + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_serialize_earning" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/service/orunmila_service.py", - "source_location": "L23", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L175", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_orunmila_service_py", - "target": "service_orunmila_service_memorymaintenance" + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_list_earnings_route" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/service/orunmila_service.py", - "source_location": "L65", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L189", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_orunmila_service_py", - "target": "service_orunmila_service_orunmilaservice" + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_sync_earnings_route" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/service/orunmila_service.py", - "source_location": "L67", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L199", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_orunmila_service_py", - "target": "service_orunmila_service_initialize" + "source": "main_controller_wallet_controller_py", + "target": "controller_wallet_controller_get_performance_route" }, { "relation": "calls", "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/service/orunmila_service.py", - "source_location": "L68", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L69", "weight": 1.0, - "source": "service_orunmila_service_initialize", - "target": "utils_service_manager_getapp" + "confidence_score": 1.0, + "source": "controller_wallet_controller_create_entry_route", + "target": "controller_wallet_controller_serialize_holding" }, { "relation": "calls", "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/service/orunmila_service.py", - "source_location": "L71", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L93", "weight": 1.0, - "source": "service_orunmila_service_initialize", - "target": "models_loader_getembeddingmodel" + "confidence_score": 1.0, + "source": "controller_wallet_controller_update_entry_route", + "target": "controller_wallet_controller_serialize_holding" }, { "relation": "calls", "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/service/orunmila_service.py", - "source_location": "L73", + "confidence": "EXTRACTED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L103", "weight": 1.0, - "source": "service_orunmila_service_initialize", - "target": "utils_scheduler_registerjob" + "confidence_score": 1.0, + "source": "controller_wallet_controller_delete_entry_route", + "target": "controller_wallet_controller_serialize_holding" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/service/scraper_service.py", - "source_location": "L14", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L82", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_scraper_service_py", - "target": "service_scraper_service_runscraper" + "source": "controller_wallet_controller_list_entries_route", + "target": "controller_wallet_controller_serialize_entry" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "main/service/scraper_service.py", - "source_location": "L22", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L183", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_scraper_service_py", - "target": "service_scraper_service_registerscraperjobs" + "source": "controller_wallet_controller_list_earnings_route", + "target": "controller_wallet_controller_serialize_earning" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/service/scraper_service.py", - "source_location": "L25", + "source_file": "main/models/memory.py", + "source_location": "L8", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_scraper_service_py", - "target": "service_scraper_service_scraperservice" + "source": "main_models_memory_py", + "target": "models_memory_orunmilamemory" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/service/scraper_service.py", - "source_location": "L27", + "source_file": "main/models/memory.py", + "source_location": "L7", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_scraper_service_py", - "target": "service_scraper_service_initialize" + "source": "main_models_memory_py", + "target": "models_memory_prometheusmemory" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/service/scraper_service.py", - "source_location": "L60", + "source_file": "main/models/memory.py", + "source_location": "L7", "weight": 1.0, "confidence_score": 1.0, - "source": "service_scraper_service_initialize", - "target": "service_scraper_service_registerscraperjobs" + "source": "main_models_memory_py", + "target": "models_memory_usermemory" }, { - "relation": "calls", - "context": "call", + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/models/memory.py", + "source_location": "L8", + "weight": 1.0, + "confidence_score": 1.0, + "source": "models_memory_orunmilamemory", + "target": "base" + }, + { + "relation": "uses", "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/service/scraper_service.py", - "source_location": "L42", + "source_file": "main/models/memory.py", + "source_location": "L4", + "weight": 0.8, + "confidence_score": 0.5, + "source": "models_memory_orunmilamemory", + "target": "models_types_vectortype" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/models/memory.py", + "source_location": "L5", + "weight": 0.8, + "confidence_score": 0.5, + "source": "models_memory_orunmilamemory", + "target": "models_user_user" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/service/orunmila_service.py", + "source_location": "L9", + "weight": 0.8, + "confidence_score": 0.5, + "source": "service_orunmila_service_orunmilaservice", + "target": "models_memory_orunmilamemory" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/models/orunmila.py", + "source_location": "L7", "weight": 1.0, - "source": "service_scraper_service_registerscraperjobs", - "target": "utils_scheduler_registerjob" + "confidence_score": 1.0, + "source": "models_orunmila_orunmilasession", + "target": "base" }, { - "relation": "rationale_for", + "relation": "inherits", "confidence": "EXTRACTED", - "source_file": "main/service/scraper_service.py", - "source_location": "L23", + "source_file": "main/models/sandbox.py", + "source_location": "L5", "weight": 1.0, "confidence_score": 1.0, - "source": "service_scraper_service_rationale_23", - "target": "service_scraper_service_registerscraperjobs" + "source": "models_sandbox_orunmilasandbox", + "target": "base" }, { - "relation": "contains", + "relation": "inherits", "confidence": "EXTRACTED", - "source_file": "main/service/stocksapi_service.py", - "source_location": "L10", + "source_file": "main/models/stocksapi_key.py", + "source_location": "L7", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_stocksapi_service_py", - "target": "service_stocksapi_service_mcpdetectmiddleware" + "source": "base", + "target": "models_stocksapi_key_stocksapikey" }, { - "relation": "contains", + "relation": "inherits", "confidence": "EXTRACTED", - "source_file": "main/service/stocksapi_service.py", - "source_location": "L6", + "source_file": "main/models/user.py", + "source_location": "L5", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_stocksapi_service_py", - "target": "service_stocksapi_service_stocksapiservice" + "source": "base", + "target": "models_user_user" }, { - "relation": "contains", + "relation": "inherits", "confidence": "EXTRACTED", - "source_file": "main/service/stocksapi_service.py", - "source_location": "L8", + "source_file": "main/models/user_session.py", + "source_location": "L5", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_stocksapi_service_py", - "target": "service_stocksapi_service_initialize" + "source": "base", + "target": "models_user_session_usersession" }, { - "relation": "method", + "relation": "inherits", "confidence": "EXTRACTED", - "source_file": "main/service/stocksapi_service.py", - "source_location": "L11", + "source_file": "main/models/wallet.py", + "source_location": "L18", "weight": 1.0, "confidence_score": 1.0, - "source": "service_stocksapi_service_mcpdetectmiddleware", - "target": "service_stocksapi_service_mcpdetectmiddleware_init" + "source": "models_wallet_wallet", + "target": "base" }, { - "relation": "method", + "relation": "inherits", "confidence": "EXTRACTED", - "source_file": "main/service/stocksapi_service.py", - "source_location": "L14", + "source_file": "main/models/wallet.py", + "source_location": "L28", "weight": 1.0, "confidence_score": 1.0, - "source": "service_stocksapi_service_mcpdetectmiddleware", - "target": "service_stocksapi_service_mcpdetectmiddleware_call" + "source": "models_wallet_holding", + "target": "base" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/service/stocksapi_service.py", - "source_location": "L4", - "weight": 0.8, - "confidence_score": 0.5, - "source": "service_stocksapi_service_mcpdetectmiddleware", - "target": "utils_service_manager_servicemanager" + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/models/wallet.py", + "source_location": "L45", + "weight": 1.0, + "confidence_score": 1.0, + "source": "models_wallet_transaction", + "target": "base" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/service/stocksapi_service.py", - "source_location": "L1", - "weight": 0.8, - "confidence_score": 0.5, - "source": "service_stocksapi_service_stocksapiservice", - "target": "utils_service_manager_servicemanager" + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/models/wallet.py", + "source_location": "L60", + "weight": 1.0, + "confidence_score": 1.0, + "source": "models_wallet_target", + "target": "base" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/service/stocksapi_service.py", - "source_location": "L29", + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/models/wallet.py", + "source_location": "L72", "weight": 1.0, - "source": "service_stocksapi_service_initialize", - "target": "utils_service_manager_getapp" + "confidence_score": 1.0, + "source": "models_wallet_snapshot", + "target": "base" }, { - "relation": "contains", + "relation": "inherits", "confidence": "EXTRACTED", - "source_file": "main/service/user_service.py", - "source_location": "L16", + "source_file": "main/models/wallet.py", + "source_location": "L89", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_user_service_py", - "target": "service_user_service_removeinactivesessions" + "source": "models_wallet_earning", + "target": "base" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/models/memory.py", + "source_location": "L7", + "weight": 1.0, + "confidence_score": 1.0, + "source": "models_memory_prometheusmemory", + "target": "base" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/models/prometheus.py", + "source_location": "L5", + "weight": 1.0, + "confidence_score": 1.0, + "source": "base", + "target": "models_prometheus_prometheussession" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/models/sandbox.py", + "source_location": "L5", + "weight": 1.0, + "confidence_score": 1.0, + "source": "base", + "target": "models_sandbox_prometheussandbox" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/models/memory.py", + "source_location": "L7", + "weight": 1.0, + "confidence_score": 1.0, + "source": "base", + "target": "models_memory_usermemory" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/models/harness.py", + "source_location": "L7", + "weight": 1.0, + "confidence_score": 1.0, + "source": "base", + "target": "models_harness_loopevent" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/service/user_service.py", - "source_location": "L4", + "source_file": "main/models/orunmila.py", + "source_location": "L7", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_user_service_py", - "target": "service_user_service_userservice" + "source": "main_models_orunmila_py", + "target": "models_orunmila_orunmilasession" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/models/orunmila.py", + "source_location": "L4", + "weight": 0.8, + "confidence_score": 0.5, + "source": "models_orunmila_orunmilasession", + "target": "models_user_user" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/service/user_service.py", - "source_location": "L6", + "source_file": "main/models/sandbox.py", + "source_location": "L5", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_user_service_py", - "target": "service_user_service_initialize" + "source": "main_models_sandbox_py", + "target": "models_sandbox_orunmilasandbox" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/service/user_service.py", - "source_location": "L46", + "source_file": "main/models/sandbox.py", + "source_location": "L5", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_user_service_py", - "target": "service_user_service_registersessioncleanupjobs" + "source": "main_models_sandbox_py", + "target": "models_sandbox_prometheussandbox" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/service/user_service.py", - "source_location": "L33", + "source_file": "main/models/stocksapi_key.py", + "source_location": "L7", "weight": 1.0, "confidence_score": 1.0, - "source": "main_service_user_service_py", - "target": "service_user_service_inactivesessionsscheduler" + "source": "main_models_stocksapi_key_py", + "target": "models_stocksapi_key_stocksapikey" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "main/service/user_service.py", - "source_location": "L1", + "source_file": "main/models/stocksapi_key.py", + "source_location": "L4", "weight": 0.8, "confidence_score": 0.5, - "source": "service_user_service_userservice", - "target": "utils_service_manager_servicemanager" + "source": "models_stocksapi_key_stocksapikey", + "target": "models_user_user" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "main/service/user_service.py", - "source_location": "L42", + "source_file": "main/app/stocks_api/key.py", + "source_location": "L58", "weight": 1.0, - "source": "service_user_service_initialize", - "target": "utils_service_manager_getapp" + "source": "stocks_api_key_createkey", + "target": "models_stocksapi_key_stocksapikey" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_api_key_quota_atomic.py", + "source_location": "L15", + "weight": 0.8, + "confidence_score": 0.5, + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_api_key_quota_atomic.py", + "source_location": "L15", + "weight": 0.8, + "confidence_score": 0.5, + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_api_key_quota_atomic_testverifyapikeyintegration" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_models.py", + "source_location": "L3", + "weight": 0.8, + "confidence_score": 0.5, + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_testusermodel" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_models.py", + "source_location": "L3", + "weight": 0.8, + "confidence_score": 0.5, + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_teststocksapikeymodel" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_models.py", + "source_location": "L3", + "weight": 0.8, + "confidence_score": 0.5, + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_testprometheussessionmodel" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "main/service/user_service.py", - "source_location": "L48", + "source_file": "tests/test_api_key_quota_atomic.py", + "source_location": "L43", "weight": 1.0, - "source": "service_user_service_initialize", - "target": "utils_scheduler_registerjob" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_normal_quota_check_works" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/service/user_service.py", - "source_location": "L72", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_api_key_quota_atomic.py", + "source_location": "L70", "weight": 1.0, - "confidence_score": 1.0, - "source": "service_user_service_initialize", - "target": "service_user_service_registersessioncleanupjobs" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_atomic_increment_prevents_overuse" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/connectivity.py", - "source_location": "L13", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_api_key_quota_atomic.py", + "source_location": "L111", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_connectivity_py", - "target": "utils_connectivity_checkdatabaseconnection" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_concurrent_requests_serialized_at_db_level" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/connectivity.py", - "source_location": "L51", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_api_key_quota_atomic.py", + "source_location": "L145", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_connectivity_py", - "target": "utils_connectivity_checkserviceconnection" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_request_at_exact_quota_limit" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/connectivity.py", - "source_location": "L13", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_api_key_quota_atomic.py", + "source_location": "L181", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_connectivity_py", - "target": "utils_connectivity_checkmysqlconnection" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_multiple_keys_independent_quotas" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/connectivity.py", - "source_location": "L13", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_api_key_quota_atomic.py", + "source_location": "L216", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_connectivity_py", - "target": "utils_connectivity_checksingledb" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_increment_from_zero" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_connectivity_coverage.py", - "source_location": "L112", + "source_file": "tests/test_api_key_quota_atomic.py", + "source_location": "L240", "weight": 1.0, - "source": "utils_connectivity_checkserviceconnection", - "target": "tests_test_connectivity_coverage_test_service_not_found" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_api_key_quota_atomic_testverifyapikeyintegration_test_verify_api_key_success" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_connectivity_coverage.py", - "source_location": "L124", + "source_file": "tests/test_api_key_quota_atomic.py", + "source_location": "L255", "weight": 1.0, - "source": "utils_connectivity_checkserviceconnection", - "target": "tests_test_connectivity_coverage_test_stocks_api_health_ok" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_api_key_quota_atomic_testverifyapikeyintegration_test_verify_api_key_quota_exceeded" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_connectivity_coverage.py", - "source_location": "L139", + "source_file": "tests/test_models.py", + "source_location": "L92", "weight": 1.0, - "source": "utils_connectivity_checkserviceconnection", - "target": "tests_test_connectivity_coverage_test_non_stocks_prefix" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_teststocksapikeymodel_test_create_api_key" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_connectivity_coverage.py", - "source_location": "L154", + "source_file": "tests/test_models.py", + "source_location": "L101", "weight": 1.0, - "source": "utils_connectivity_checkserviceconnection", - "target": "tests_test_connectivity_coverage_test_non_200_status" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_teststocksapikeymodel_test_is_quota_exceeded_true" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_connectivity_coverage.py", - "source_location": "L164", + "source_file": "tests/test_models.py", + "source_location": "L107", "weight": 1.0, - "source": "utils_connectivity_checkserviceconnection", - "target": "tests_test_connectivity_coverage_test_connection_error" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_teststocksapikeymodel_test_is_quota_exceeded_false" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_connectivity_coverage.py", - "source_location": "L174", + "source_file": "tests/test_models.py", + "source_location": "L113", "weight": 1.0, - "source": "utils_connectivity_checkserviceconnection", - "target": "tests_test_connectivity_coverage_test_timeout" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_teststocksapikeymodel_test_needs_reset_true_no_last_reset" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_connectivity_coverage.py", - "source_location": "L184", + "source_file": "tests/test_models.py", + "source_location": "L118", "weight": 1.0, - "source": "utils_connectivity_checkserviceconnection", - "target": "tests_test_connectivity_coverage_test_request_exception" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_teststocksapikeymodel_test_needs_reset_true_expired" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_connectivity_coverage.py", - "source_location": "L194", + "source_file": "tests/test_models.py", + "source_location": "L124", "weight": 1.0, - "source": "utils_connectivity_checkserviceconnection", - "target": "tests_test_connectivity_coverage_test_generic_exception" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_teststocksapikeymodel_test_needs_reset_false_recent" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "main/utils/connectivity.py", - "source_location": "L66", + "source_file": "tests/test_models.py", + "source_location": "L130", "weight": 1.0, - "source": "utils_connectivity_checkserviceconnection", - "target": "utils_http_session_get_session" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_teststocksapikeymodel_test_reset_quota" }, { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L5", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_models.py", + "source_location": "L138", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_errors_py", - "target": "fastapi" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_teststocksapikeymodel_test_increment_usage" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L13", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_models.py", + "source_location": "L144", "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_errors_py", - "target": "utils_errors_errorresponse" + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_teststocksapikeymodel_test_get_remaining_quota" }, { - "relation": "contains", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_models.py", + "source_location": "L150", + "weight": 1.0, + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_teststocksapikeymodel_test_get_remaining_quota_exceeded" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_models.py", + "source_location": "L156", + "weight": 1.0, + "source": "models_stocksapi_key_stocksapikey", + "target": "tests_test_models_teststocksapikeymodel_test_toDict" + }, + { + "relation": "method", "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", + "source_file": "main/models/stocksapi_key.py", "source_location": "L21", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_errors_py", - "target": "utils_errors_requestcontextfilter" + "source": "models_stocksapi_key_stocksapikey", + "target": "models_stocksapi_key_stocksapikey_isquotaexceeded" }, { - "relation": "contains", + "relation": "method", "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L27", + "source_file": "main/models/stocksapi_key.py", + "source_location": "L24", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_errors_py", - "target": "utils_errors_builderrorresponse" + "source": "models_stocksapi_key_stocksapikey", + "target": "models_stocksapi_key_stocksapikey_needsreset" }, { - "relation": "contains", + "relation": "method", "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L37", + "source_file": "main/models/stocksapi_key.py", + "source_location": "L32", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_errors_py", - "target": "utils_errors_httpexceptionhandler" + "source": "models_stocksapi_key_stocksapikey", + "target": "models_stocksapi_key_stocksapikey_resetquota" }, { - "relation": "contains", + "relation": "method", "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L44", + "source_file": "main/models/stocksapi_key.py", + "source_location": "L36", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_errors_py", - "target": "utils_errors_validationexceptionhandler" + "source": "models_stocksapi_key_stocksapikey", + "target": "models_stocksapi_key_stocksapikey_incrementusage" }, { - "relation": "contains", + "relation": "method", "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L56", + "source_file": "main/models/stocksapi_key.py", + "source_location": "L39", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_errors_py", - "target": "utils_errors_genericexceptionhandler" + "source": "models_stocksapi_key_stocksapikey", + "target": "models_stocksapi_key_stocksapikey_getremainingquota" }, { - "relation": "contains", + "relation": "method", "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L65", + "source_file": "main/models/stocksapi_key.py", + "source_location": "L42", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_errors_py", - "target": "utils_errors_registererrorhandlers" + "source": "models_stocksapi_key_stocksapikey", + "target": "models_stocksapi_key_stocksapikey_todict" }, { - "relation": "contains", + "relation": "method", "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L29", + "source_file": "main/models/stocksapi_key.py", + "source_location": "L18", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_errors_py", - "target": "utils_errors_build_error_response" + "source": "models_stocksapi_key_stocksapikey", + "target": "models_stocksapi_key_stocksapikey_repr" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L38", + "source_file": "main/models/types.py", + "source_location": "L5", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_errors_py", - "target": "utils_errors_http_exception_handler" + "source": "main_models_types_py", + "target": "models_types_vectortype" }, { - "relation": "contains", + "relation": "inherits", "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L45", + "source_file": "main/models/types.py", + "source_location": "L5", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_errors_py", - "target": "utils_errors_validation_exception_handler" + "source": "models_types_vectortype", + "target": "typedecorator" }, { - "relation": "contains", + "relation": "method", "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L57", + "source_file": "main/models/types.py", + "source_location": "L9", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_errors_py", - "target": "utils_errors_generic_exception_handler" + "source": "models_types_vectortype", + "target": "models_types_vectortype_init" }, { - "relation": "contains", + "relation": "method", "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L66", + "source_file": "main/models/types.py", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_errors_py", - "target": "utils_errors_register_error_handlers" + "source": "models_types_vectortype", + "target": "models_types_vectortype_process_bind_param" }, { - "relation": "calls", - "context": "call", + "relation": "method", "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L28", + "source_file": "main/models/types.py", + "source_location": "L21", "weight": 1.0, "confidence_score": 1.0, - "source": "utils_errors_errorresponse", - "target": "utils_errors_builderrorresponse" - }, - { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_errors_errorresponse", - "target": "tests_test_error_handlers_samplebody" - }, - { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_errors_errorresponse", - "target": "tests_test_error_handlers_testerrorresponsemodel" - }, - { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_errors_errorresponse", - "target": "tests_test_error_handlers_testrequestcontextfilter" - }, - { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_errors_errorresponse", - "target": "tests_test_error_handlers_testhttpexceptionhandler" + "source": "models_types_vectortype", + "target": "models_types_vectortype_process_result_value" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", + "source_file": "main/models/memory.py", + "source_location": "L4", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_errors_errorresponse", - "target": "tests_test_error_handlers_testvalidationexceptionhandler" + "source": "models_memory_prometheusmemory", + "target": "models_types_vectortype" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", + "source_file": "tests/test_memory_types.py", + "source_location": "L3", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_errors_errorresponse", - "target": "tests_test_error_handlers_testgenericexceptionhandler" + "source": "models_types_vectortype", + "target": "tests_test_memory_types_testvectortype" }, { - "relation": "uses", + "relation": "calls", + "context": "call", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_errors_errorresponse", - "target": "tests_test_error_handlers_testsuccesspassthrough" + "confidence_score": 0.8, + "source_file": "tests/test_memory_types.py", + "source_location": "L9", + "weight": 1.0, + "source": "models_types_vectortype", + "target": "tests_test_memory_types_testvectortype_test_roundtrip" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_error_handlers.py", - "source_location": "L56", + "source_file": "tests/test_memory_types.py", + "source_location": "L19", "weight": 1.0, - "source": "utils_errors_errorresponse", - "target": "tests_test_error_handlers_testerrorresponsemodel_test_error_response_structure" + "source": "models_types_vectortype", + "target": "tests_test_memory_types_testvectortype_test_none_roundtrip" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_error_handlers.py", - "source_location": "L65", + "source_file": "tests/test_memory_types.py", + "source_location": "L25", "weight": 1.0, - "source": "utils_errors_errorresponse", - "target": "tests_test_error_handlers_testerrorresponsemodel_test_error_response_with_detail_and_request_id" + "source": "models_types_vectortype", + "target": "tests_test_memory_types_testvectortype_test_wrong_dims_raises" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L30", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_memory_types.py", + "source_location": "L31", "weight": 1.0, - "confidence_score": 1.0, - "source": "utils_errors_errorresponse", - "target": "utils_errors_build_error_response" + "source": "models_types_vectortype", + "target": "tests_test_memory_types_testvectortype_test_preserves_negative_values" }, { - "relation": "method", - "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L24", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_memory_types.py", + "source_location": "L39", "weight": 1.0, - "confidence_score": 1.0, - "source": "utils_errors_requestcontextfilter", - "target": "utils_errors_requestcontextfilter_filter" + "source": "models_types_vectortype", + "target": "tests_test_memory_types_testvectortype_test_large_random_vector" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "main/utils/logging_config.py", - "source_location": "L9", + "source_file": "main/models/memory.py", + "source_location": "L4", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_errors_requestcontextfilter", - "target": "utils_logging_config_discordhandler" + "source": "models_types_vectortype", + "target": "models_memory_usermemory" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/utils/logging_config.py", - "source_location": "L20", + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/models/memory_types.py", + "source_location": "L5", "weight": 1.0, - "source": "utils_errors_requestcontextfilter", - "target": "utils_logging_config_setuplogging" + "confidence_score": 1.0, + "source": "typedecorator", + "target": "models_memory_types_vectortype" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_errors_requestcontextfilter", - "target": "tests_test_error_handlers_samplebody" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/models/user.py", + "source_location": "L5", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_models_user_py", + "target": "models_user_user" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", + "source_file": "main/models/user_session.py", + "source_location": "L4", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_errors_requestcontextfilter", - "target": "tests_test_error_handlers_testerrorresponsemodel" + "source": "models_user_session_usersession", + "target": "models_user_user" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", + "source_file": "main/models/memory.py", + "source_location": "L5", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_errors_requestcontextfilter", - "target": "tests_test_error_handlers_testrequestcontextfilter" + "source": "models_memory_prometheusmemory", + "target": "models_user_user" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", + "source_file": "main/models/prometheus.py", + "source_location": "L4", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_errors_requestcontextfilter", - "target": "tests_test_error_handlers_testhttpexceptionhandler" + "source": "models_prometheus_prometheussession", + "target": "models_user_user" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", + "source_file": "tests/test_models.py", + "source_location": "L2", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_errors_requestcontextfilter", - "target": "tests_test_error_handlers_testvalidationexceptionhandler" + "source": "models_user_user", + "target": "tests_test_models_testusermodel" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", + "source_file": "tests/test_models.py", + "source_location": "L2", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_errors_requestcontextfilter", - "target": "tests_test_error_handlers_testgenericexceptionhandler" + "source": "models_user_user", + "target": "tests_test_models_teststocksapikeymodel" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L12", + "source_file": "tests/test_models.py", + "source_location": "L2", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_errors_requestcontextfilter", - "target": "tests_test_error_handlers_testsuccesspassthrough" + "source": "models_user_user", + "target": "tests_test_models_testprometheussessionmodel" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_error_handlers.py", - "source_location": "L78", + "source_file": "tests/test_models.py", + "source_location": "L9", "weight": 1.0, - "source": "utils_errors_requestcontextfilter", - "target": "tests_test_error_handlers_testrequestcontextfilter_test_injects_request_id_from_contextvar" + "source": "models_user_user", + "target": "tests_test_models_testusermodel_test_create_user" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_error_handlers.py", - "source_location": "L87", - "weight": 1.0, - "source": "utils_errors_requestcontextfilter", - "target": "tests_test_error_handlers_testrequestcontextfilter_test_empty_request_id_default" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L22", - "weight": 1.0, - "confidence_score": 1.0, - "source": "utils_errors_requestcontextfilter", - "target": "utils_errors_rationale_22" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L40", - "weight": 1.0, - "confidence_score": 1.0, - "source": "utils_errors_builderrorresponse", - "target": "utils_errors_httpexceptionhandler" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L52", + "source_file": "tests/test_models.py", + "source_location": "L19", "weight": 1.0, - "confidence_score": 1.0, - "source": "utils_errors_builderrorresponse", - "target": "utils_errors_validationexceptionhandler" + "source": "models_user_user", + "target": "tests_test_models_testusermodel_test_get_roles_list_default" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/utils/errors.py", - "source_location": "L61", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_models.py", + "source_location": "L24", "weight": 1.0, - "confidence_score": 1.0, - "source": "utils_errors_builderrorresponse", - "target": "utils_errors_genericexceptionhandler" + "source": "models_user_user", + "target": "tests_test_models_testusermodel_test_get_roles_list_single_role" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/conftest.py", - "source_location": "L84", + "source_file": "tests/test_models.py", + "source_location": "L29", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_conftest_stocks_http_client" + "source": "models_user_user", + "target": "tests_test_models_testusermodel_test_get_roles_list_multiple_roles" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/conftest.py", - "source_location": "L93", + "source_file": "tests/test_models.py", + "source_location": "L37", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_conftest_client" + "source": "models_user_user", + "target": "tests_test_models_testusermodel_test_add_role_new" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L31", + "source_file": "tests/test_models.py", + "source_location": "L43", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_make_auth_client" + "source": "models_user_user", + "target": "tests_test_models_testusermodel_test_add_role_existing" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L46", + "source_file": "tests/test_models.py", + "source_location": "L63", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_make_user_client" + "source": "models_user_user", + "target": "tests_test_models_testusermodel_test_has_role_true" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L66", + "source_file": "tests/test_models.py", + "source_location": "L68", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_make_prometheus_client" + "source": "models_user_user", + "target": "tests_test_models_testusermodel_test_has_role_false" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L87", + "source_file": "tests/test_models.py", + "source_location": "L75", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_make_stocksapi_client" + "source": "models_user_user", + "target": "tests_test_models_testusermodel_test_has_role_with_enum" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L685", + "source_file": "tests/test_models.py", + "source_location": "L80", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testgetsessions_test_get_sessions" + "source": "models_user_user", + "target": "tests_test_models_testusermodel_test_toDict" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L731", + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/models/user.py", + "source_location": "L22", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testgetcurrentsession_test_get_current_session_found" + "confidence_score": 1.0, + "source": "models_user_user", + "target": "models_user_user_getroleslist" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L754", + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/models/user.py", + "source_location": "L27", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testgetcurrentsession_test_get_current_session_not_found" + "confidence_score": 1.0, + "source": "models_user_user", + "target": "models_user_user_addrole" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L784", + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/models/user.py", + "source_location": "L43", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testrevokesession_test_revoke_session_success" + "confidence_score": 1.0, + "source": "models_user_user", + "target": "models_user_user_hasrole" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L807", + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/models/user.py", + "source_location": "L48", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testrevokesession_test_revoke_session_not_found" + "confidence_score": 1.0, + "source": "models_user_user", + "target": "models_user_user_todict" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L832", + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/models/user.py", + "source_location": "L19", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testrevokesession_test_revoke_session_failure" + "confidence_score": 1.0, + "source": "models_user_user", + "target": "models_user_user_repr" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L858", + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/models/user.py", + "source_location": "L35", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testrevokeallsessions_test_revoke_all_sessions" + "confidence_score": 1.0, + "source": "models_user_user", + "target": "models_user_user_removerole" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L975", + "source_file": "tests/test_models.py", + "source_location": "L50", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testprometheusgethistory_test_get_history_found" + "source": "models_user_user", + "target": "tests_test_models_testusermodel_test_remove_role_existing" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L1011", + "source_file": "tests/test_models.py", + "source_location": "L57", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testprometheusgethistory_test_get_history_not_found" + "source": "models_user_user", + "target": "tests_test_models_testusermodel_test_remove_role_last_role" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/models/user_session.py", + "source_location": "L5", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_models_user_session_py", + "target": "models_user_session_usersession" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/service/user_service.py", + "source_location": "L8", + "weight": 0.8, + "confidence_score": 0.5, + "source": "models_user_session_usersession", + "target": "service_user_service_userservice" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_sessions.py", + "source_location": "L7", + "weight": 0.8, + "confidence_score": 0.5, + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testusersessionmodel" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_sessions.py", + "source_location": "L8", + "weight": 0.8, + "confidence_score": 0.5, + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testsessionexpiration" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L1090", + "source_file": "tests/test_sessions.py", + "source_location": "L56", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testprometheuschat_test_chat_existing_session_verified" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testusersessionmodel_test_getdevicename_with_browser_and_os" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L1132", + "source_file": "tests/test_sessions.py", + "source_location": "L69", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testprometheuschat_test_chat_existing_session_not_owner" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testusersessionmodel_test_getdevicename_with_fingerprint_only" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_error_handlers.py", - "source_location": "L28", + "source_file": "tests/test_sessions.py", + "source_location": "L81", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_error_handlers_app" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testusersessionmodel_test_getdevicename_fallback" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_oauth_cookie_security.py", - "source_location": "L28", + "source_file": "tests/test_sessions.py", + "source_location": "L94", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_oauth_cookie_security_make_callback_client" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testusersessionmodel_test_getdevicename_empty_strings" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_sso_state_cookie.py", - "source_location": "L32", + "source_file": "tests/test_sessions.py", + "source_location": "L108", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_sso_state_cookie_build_app" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testusersessionmodel_test_isactive_default" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_memory_controller.py", - "source_location": "L38", + "source_file": "tests/test_sessions.py", + "source_location": "L112", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_memory_controller_testmemorycontrollerroutes_test_get_memories_rejects_unauthenticated" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testusersessionmodel_test_isactive_can_be_false" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_memory_controller.py", - "source_location": "L57", + "source_file": "tests/test_sessions.py", + "source_location": "L156", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_memory_controller_testmemorycontrollerroutes_test_get_memories_rejects_basic_user" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testsessionexpiration_test_session_can_expire" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_stocks_api_coverage.py", - "source_location": "L1165", + "source_file": "tests/test_sessions.py", + "source_location": "L175", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_stocks_api_coverage_testquerycotations_test_cotations_http_route" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testsessionexpiration_test_session_still_valid_within_expiry" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_stocks_api_coverage.py", - "source_location": "L1353", + "source_file": "tests/test_sessions.py", + "source_location": "L193", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_stocks_api_coverage_testquerylivecotation_test_http_route_returns_200" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testsessionexpiration_test_session_exactly_at_boundary" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_stocks_api_coverage.py", - "source_location": "L1377", + "source_file": "tests/test_sessions.py", + "source_location": "L210", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_stocks_api_coverage_testquerylivecotation_test_http_route_search_required" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testsessionexpiration_test_created_at_future_date" + }, + { + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/models/user_session.py", + "source_location": "L38", + "weight": 1.0, + "confidence_score": 1.0, + "source": "models_user_session_usersession", + "target": "models_user_session_usersession_getdevicename" + }, + { + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/models/user_session.py", + "source_location": "L22", + "weight": 1.0, + "confidence_score": 1.0, + "source": "models_user_session_usersession", + "target": "models_user_session_usersession_repr" + }, + { + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/models/user_session.py", + "source_location": "L25", + "weight": 1.0, + "confidence_score": 1.0, + "source": "models_user_session_usersession", + "target": "models_user_session_usersession_todict" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_stocks_api_coverage.py", - "source_location": "L1466", + "source_file": "tests/test_sessions.py", + "source_location": "L12", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_stocks_api_coverage_testquerylivecotation_test_cotations_search_required" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testusersessionmodel_test_repr" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_stocks_api_coverage.py", - "source_location": "L1298", + "source_file": "tests/test_sessions.py", + "source_location": "L17", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_stocks_api_coverage_testquerycotations_test_cotations_search_required" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testusersessionmodel_test_toDict_basic" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L156", + "source_file": "tests/test_sessions.py", + "source_location": "L34", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testregisterendpoint_make_register_client" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testusersessionmodel_test_toDict_with_sensitive" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L236", + "source_file": "tests/test_sessions.py", + "source_location": "L45", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testloginendpoint_make_login_client" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testusersessionmodel_test_toDict_hides_useragent" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L289", + "source_file": "tests/test_sessions.py", + "source_location": "L118", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testlogoutendpoint_make_logout_client" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testusersessionmodel_test_todict_with_timestamps" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L433", + "source_file": "tests/test_sessions.py", + "source_location": "L132", "weight": 1.0, - "source": "utils_errors_registererrorhandlers", - "target": "tests_test_controllers_coverage_testgooglecallback_make_callback_client" + "source": "models_user_session_usersession", + "target": "tests_test_sessions_testusersessionmodel_test_todict_without_timestamps" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/http_session.py", - "source_location": "L9", + "source_file": "main/models/wallet.py", + "source_location": "L18", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_http_session_py", - "target": "utils_http_session_getsession" + "source": "main_models_wallet_py", + "target": "models_wallet_wallet" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/http_session.py", - "source_location": "L22", + "source_file": "main/models/wallet.py", + "source_location": "L28", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_http_session_py", - "target": "utils_http_session_cleanup" + "source": "main_models_wallet_py", + "target": "models_wallet_holding" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/http_session.py", - "source_location": "L8", + "source_file": "main/models/wallet.py", + "source_location": "L45", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_http_session_py", - "target": "utils_http_session_get_session" + "source": "main_models_wallet_py", + "target": "models_wallet_transaction" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/logging_config.py", - "source_location": "L12", + "source_file": "main/models/wallet.py", + "source_location": "L60", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_logging_config_py", - "target": "utils_logging_config_setuplogging" + "source": "main_models_wallet_py", + "target": "models_wallet_target" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/logging_config.py", - "source_location": "L24", + "source_file": "main/models/wallet.py", + "source_location": "L72", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_logging_config_py", - "target": "utils_logging_config_discordhandler" + "source": "main_models_wallet_py", + "target": "models_wallet_snapshot" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/logging_config.py", - "source_location": "L49", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_logging_config_py", - "target": "utils_logging_config_setupdiscordhandler" - }, - { - "relation": "method", - "confidence": "EXTRACTED", - "source_file": "main/utils/logging_config.py", - "source_location": "L37", - "weight": 1.0, - "confidence_score": 1.0, - "source": "utils_logging_config_discordhandler", - "target": "utils_logging_config_discordhandler_init" - }, - { - "relation": "method", - "confidence": "EXTRACTED", - "source_file": "main/utils/logging_config.py", - "source_location": "L25", + "source_file": "main/models/wallet.py", + "source_location": "L89", "weight": 1.0, "confidence_score": 1.0, - "source": "utils_logging_config_discordhandler", - "target": "utils_logging_config_discordhandler_emit" + "source": "main_models_wallet_py", + "target": "models_wallet_earning" }, { "relation": "calls", "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/utils/logging_config.py", - "source_location": "L51", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L33", "weight": 1.0, - "confidence_score": 1.0, - "source": "utils_logging_config_discordhandler", - "target": "utils_logging_config_setupdiscordhandler" + "source": "wallet_wallet_service_createwallet", + "target": "models_wallet_wallet" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_logging_config_coverage.py", - "source_location": "L9", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_logging_config_discordhandler", - "target": "tests_test_logging_config_coverage_testdiscordhandleremit" + "source": "wallet_wallet_service_entrycreate", + "target": "models_wallet_wallet" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_logging_config_coverage.py", - "source_location": "L9", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_logging_config_discordhandler", - "target": "tests_test_logging_config_coverage_testsetuplogging" + "source": "wallet_wallet_service_entryupdate", + "target": "models_wallet_wallet" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_thread_safety.py", - "source_location": "L138", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_logging_config_discordhandler", - "target": "tests_test_thread_safety_testgetsession" + "source": "wallet_wallet_service_targetupsert", + "target": "models_wallet_wallet" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_thread_safety.py", - "source_location": "L138", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_logging_config_discordhandler", - "target": "tests_test_thread_safety_testdiscordhandlerthreadpool" + "source": "wallet_wallet_service_ratingupsert", + "target": "models_wallet_wallet" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_thread_safety.py", - "source_location": "L138", + "source_file": "main/service/wallet_service.py", + "source_location": "L9", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_logging_config_discordhandler", - "target": "tests_test_thread_safety_testconcurrentgetsession" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_logging_config_coverage.py", - "source_location": "L10", - "weight": 1.0, - "source": "utils_logging_config_discordhandler", - "target": "tests_test_logging_config_coverage_testdiscordhandleremit_make_handler" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_thread_safety.py", - "source_location": "L110", - "weight": 1.0, - "source": "utils_logging_config_discordhandler", - "target": "tests_test_thread_safety_testdiscordhandlerthreadpool_test_emit_submits_to_executor" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_thread_safety.py", - "source_location": "L140", - "weight": 1.0, - "source": "utils_logging_config_discordhandler", - "target": "tests_test_thread_safety_testdiscordhandlerthreadpool_test_concurrent_emits_do_not_spawn_unbounded_threads" + "source": "service_wallet_service_entrycreate", + "target": "models_wallet_wallet" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_thread_safety.py", - "source_location": "L138", + "source_file": "main/service/wallet_service.py", + "source_location": "L9", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_logging_config_discordhandler", - "target": "tests_test_thread_safety_testconcurrenthttpproxy" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_logging_config_coverage.py", - "source_location": "L107", - "weight": 1.0, - "source": "utils_logging_config_setupdiscordhandler", - "target": "tests_test_logging_config_coverage_test_setup_discord_handler_enabled" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "tests/test_logging_config_coverage.py", - "source_location": "L113", - "weight": 1.0, - "source": "utils_logging_config_setupdiscordhandler", - "target": "tests_test_logging_config_coverage_test_setup_discord_handler_disabled" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/migrator.py", - "source_location": "L8", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_migrator_py", - "target": "utils_migrator_runmigrations" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/request_id.py", - "source_location": "L13", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_request_id_py", - "target": "utils_request_id_requestidmiddleware" - }, - { - "relation": "inherits", - "confidence": "EXTRACTED", - "source_file": "main/utils/request_id.py", - "source_location": "L13", - "weight": 1.0, - "confidence_score": 1.0, - "source": "utils_request_id_requestidmiddleware", - "target": "basehttpmiddleware" - }, - { - "relation": "method", - "confidence": "EXTRACTED", - "source_file": "main/utils/request_id.py", - "source_location": "L14", - "weight": 1.0, - "confidence_score": 1.0, - "source": "utils_request_id_requestidmiddleware", - "target": "utils_request_id_requestidmiddleware_dispatch" + "source": "service_wallet_service_entryupdate", + "target": "models_wallet_wallet" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L17", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_request_id_requestidmiddleware", - "target": "tests_test_error_handlers_samplebody" + "source": "service_wallet_service_targetupsert", + "target": "models_wallet_wallet" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L17", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_request_id_requestidmiddleware", - "target": "tests_test_error_handlers_testerrorresponsemodel" + "source": "service_wallet_service_ratingupsert", + "target": "models_wallet_wallet" }, { - "relation": "uses", + "relation": "calls", + "context": "call", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L17", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_request_id_requestidmiddleware", - "target": "tests_test_error_handlers_testrequestcontextfilter" + "confidence_score": 0.8, + "source_file": "main/service/wallet_service.py", + "source_location": "L11", + "weight": 1.0, + "source": "service_wallet_service_create_wallet", + "target": "models_wallet_wallet" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L17", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_request_id_requestidmiddleware", - "target": "tests_test_error_handlers_testhttpexceptionhandler" + "source": "wallet_wallet_service_entrycreate", + "target": "models_wallet_holding" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L17", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_request_id_requestidmiddleware", - "target": "tests_test_error_handlers_testvalidationexceptionhandler" + "source": "wallet_wallet_service_entryupdate", + "target": "models_wallet_holding" }, { - "relation": "uses", + "relation": "calls", + "context": "call", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L17", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_request_id_requestidmiddleware", - "target": "tests_test_error_handlers_testgenericexceptionhandler" + "confidence_score": 0.8, + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L102", + "weight": 1.0, + "source": "wallet_wallet_service_recalcholding", + "target": "models_wallet_holding" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_error_handlers.py", - "source_location": "L17", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_request_id_requestidmiddleware", - "target": "tests_test_error_handlers_testsuccesspassthrough" + "source": "wallet_wallet_service_targetupsert", + "target": "models_wallet_holding" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_request_id.py", - "source_location": "L10", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_request_id_requestidmiddleware", - "target": "tests_test_request_id_testrequestidmiddleware" - }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "main/utils/roles.py", - "source_location": "L2", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_roles_py", - "target": "fastapi" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/roles.py", - "source_location": "L4", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_roles_py", - "target": "utils_roles_permission" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/roles.py", - "source_location": "L28", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_roles_py", - "target": "utils_roles_all" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/roles.py", - "source_location": "L32", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_roles_py", - "target": "utils_roles_roles" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/roles.py", - "source_location": "L51", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_roles_py", - "target": "utils_roles_checkaccess" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/roles.py", - "source_location": "L64", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_roles_py", - "target": "utils_roles_requirepermission" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/roles.py", - "source_location": "L63", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_roles_py", - "target": "utils_roles_servicetoken" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/roles.py", - "source_location": "L69", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_roles_py", - "target": "utils_roles_introspecturl" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/roles.py", - "source_location": "L75", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_roles_py", - "target": "utils_roles_extractcredential" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/utils/roles.py", - "source_location": "L92", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_utils_roles_py", - "target": "utils_roles_introspectuser" - }, - { - "relation": "inherits", - "confidence": "EXTRACTED", - "source_file": "main/utils/roles.py", - "source_location": "L4", - "weight": 1.0, - "confidence_score": 1.0, - "source": "utils_roles_permission", - "target": "intflag" + "source": "wallet_wallet_service_ratingupsert", + "target": "models_wallet_holding" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "main/app/prometheus/memory.py", - "source_location": "L23", + "source_file": "main/service/wallet_service.py", + "source_location": "L9", "weight": 0.8, "confidence_score": 0.5, - "source": "prometheus_memory_memorycandidate", - "target": "utils_roles_permission" + "source": "service_wallet_service_entrycreate", + "target": "models_wallet_holding" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "main/app/prometheus/memory.py", + "source_file": "main/service/wallet_service.py", "source_location": "L9", "weight": 0.8, "confidence_score": 0.5, - "source": "prometheus_memory_prometheusmemory", - "target": "utils_roles_permission" + "source": "service_wallet_service_entryupdate", + "target": "models_wallet_holding" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_roles.py", - "source_location": "L7", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_roles_testpermission" + "source": "service_wallet_service_targetupsert", + "target": "models_wallet_holding" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_roles.py", - "source_location": "L7", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_roles_testroles" + "source": "service_wallet_service_ratingupsert", + "target": "models_wallet_holding" }, { - "relation": "uses", + "relation": "calls", + "context": "call", "confidence": "INFERRED", - "source_file": "tests/test_roles_coverage.py", - "source_location": "L5", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_roles_coverage_testcheckaccess" + "confidence_score": 0.8, + "source_file": "main/service/wallet_service.py", + "source_location": "L84", + "weight": 1.0, + "source": "service_wallet_service_recalc_holding", + "target": "models_wallet_holding" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_roles_coverage.py", - "source_location": "L5", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_roles_coverage_testrequirepermission" + "source": "wallet_wallet_service_entrycreate", + "target": "models_wallet_transaction" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_roles_coverage.py", - "source_location": "L5", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_roles_coverage_testpermissionall" + "source": "wallet_wallet_service_entryupdate", + "target": "models_wallet_transaction" }, { - "relation": "uses", + "relation": "calls", + "context": "call", "confidence": "INFERRED", - "source_file": "tests/test_roles_coverage.py", - "source_location": "L5", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_roles_coverage_testroleshierarchy" + "confidence_score": 0.8, + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L118", + "weight": 1.0, + "source": "wallet_wallet_service_addentry", + "target": "models_wallet_transaction" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "main/app/prometheus/memory.py", - "source_location": "L7", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "prometheus_memory_memorymanager" + "source": "wallet_wallet_service_targetupsert", + "target": "models_wallet_transaction" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_memory_manager.py", - "source_location": "L6", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_memory_manager_testgetmemorylimit" + "source": "wallet_wallet_service_ratingupsert", + "target": "models_wallet_transaction" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_memory_manager.py", - "source_location": "L6", + "source_file": "main/service/wallet_service.py", + "source_location": "L9", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_memory_manager_testupsertmemory" + "source": "service_wallet_service_entrycreate", + "target": "models_wallet_transaction" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_memory_manager.py", - "source_location": "L6", + "source_file": "main/service/wallet_service.py", + "source_location": "L9", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_memory_manager_testcountmemories" + "source": "service_wallet_service_entryupdate", + "target": "models_wallet_transaction" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_memory_manager.py", - "source_location": "L6", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_memory_manager_testgetusermemories" + "source": "service_wallet_service_targetupsert", + "target": "models_wallet_transaction" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_memory_manager.py", - "source_location": "L6", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_memory_manager_testdeletememory" + "source": "service_wallet_service_ratingupsert", + "target": "models_wallet_transaction" }, { - "relation": "uses", + "relation": "calls", + "context": "call", "confidence": "INFERRED", - "source_file": "tests/test_memory_manager.py", - "source_location": "L6", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_memory_manager_testsearchfulltext" + "confidence_score": 0.8, + "source_file": "main/service/wallet_service.py", + "source_location": "L100", + "weight": 1.0, + "source": "service_wallet_service_add_entry", + "target": "models_wallet_transaction" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testissecurescheme" + "source": "wallet_wallet_service_entrycreate", + "target": "models_wallet_target" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testhealthendpoint" + "source": "wallet_wallet_service_entryupdate", + "target": "models_wallet_target" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testregisterendpoint" + "source": "wallet_wallet_service_targetupsert", + "target": "models_wallet_target" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testloginendpoint" + "source": "wallet_wallet_service_ratingupsert", + "target": "models_wallet_target" }, { - "relation": "uses", + "relation": "calls", + "context": "call", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testlogoutendpoint" + "confidence_score": 0.8, + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L408", + "weight": 1.0, + "source": "wallet_wallet_service_upserttarget", + "target": "models_wallet_target" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testgooglelogin" + "source": "service_wallet_service_entrycreate", + "target": "models_wallet_target" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testgooglecallback" + "source": "service_wallet_service_entryupdate", + "target": "models_wallet_target" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testuserhealth" + "source": "service_wallet_service_targetupsert", + "target": "models_wallet_target" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testgetme" + "source": "service_wallet_service_ratingupsert", + "target": "models_wallet_target" }, { - "relation": "uses", + "relation": "calls", + "context": "call", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testupgradeendpoints" + "confidence_score": 0.8, + "source_file": "main/service/wallet_service.py", + "source_location": "L395", + "weight": 1.0, + "source": "service_wallet_service_upsert_target", + "target": "models_wallet_target" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testadminaccess" + "source": "wallet_wallet_service_entrycreate", + "target": "models_wallet_snapshot" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testgetsessions" + "source": "wallet_wallet_service_entryupdate", + "target": "models_wallet_snapshot" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testgetcurrentsession" + "source": "wallet_wallet_service_targetupsert", + "target": "models_wallet_snapshot" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testrevokesession" + "source": "wallet_wallet_service_ratingupsert", + "target": "models_wallet_snapshot" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testrevokeallsessions" + "source": "service_wallet_service_entrycreate", + "target": "models_wallet_snapshot" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testprometheushealth" + "source": "service_wallet_service_entryupdate", + "target": "models_wallet_snapshot" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testprometheusgetsessions" + "source": "service_wallet_service_targetupsert", + "target": "models_wallet_snapshot" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testprometheuscreatesession" + "source": "service_wallet_service_ratingupsert", + "target": "models_wallet_snapshot" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testprometheusupdatesessiontitle" + "source": "wallet_wallet_service_entrycreate", + "target": "models_wallet_earning" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testprometheusgethistory" + "source": "wallet_wallet_service_entryupdate", + "target": "models_wallet_earning" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testprometheusdeletesession" + "source": "wallet_wallet_service_targetupsert", + "target": "models_wallet_earning" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L18", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testprometheuschat" + "source": "wallet_wallet_service_ratingupsert", + "target": "models_wallet_earning" }, { - "relation": "uses", + "relation": "calls", + "context": "call", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_teststocksapihealth" + "confidence_score": 0.8, + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L503", + "weight": 1.0, + "source": "wallet_wallet_service_syncearnings", + "target": "models_wallet_earning" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_teststocksapikeytest" + "source": "service_wallet_service_entrycreate", + "target": "models_wallet_earning" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_teststocksapihistorical" + "source": "service_wallet_service_entryupdate", + "target": "models_wallet_earning" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_teststocksapifundamental" + "source": "service_wallet_service_targetupsert", + "target": "models_wallet_earning" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/service/wallet_service.py", + "source_location": "L14", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_teststocksapigeneratekey" + "source": "service_wallet_service_ratingupsert", + "target": "models_wallet_earning" }, { - "relation": "uses", + "relation": "calls", + "context": "call", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testaddroletouser" + "confidence_score": 0.8, + "source_file": "main/service/wallet_service.py", + "source_location": "L499", + "weight": 1.0, + "source": "service_wallet_service_sync_earnings", + "target": "models_wallet_earning" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testgetcurrentuser" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/authentication_service.py", + "source_location": "L9", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_authentication_service_py", + "target": "service_authentication_service_authenticationservice" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testhashpasswordempty" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/authentication_service.py", + "source_location": "L11", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_authentication_service_py", + "target": "service_authentication_service_initialize" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/service/authentication_service.py", + "source_location": "L6", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testverifyaccesstoken" + "source": "service_authentication_service_authenticationservice", + "target": "utils_service_manager_servicemanager" }, { - "relation": "uses", + "relation": "calls", + "context": "call", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testextracttokenpayloadreraise" + "confidence_score": 0.8, + "source_file": "main/service/authentication_service.py", + "source_location": "L12", + "weight": 1.0, + "source": "service_authentication_service_initialize", + "target": "utils_service_manager_getapp" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_permission", - "target": "tests_test_controllers_coverage_testmanagerinit" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/orunmila_service.py", + "source_location": "L23", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_orunmila_service_py", + "target": "service_orunmila_service_memorymaintenance" }, { - "relation": "inherits", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/roles.py", - "source_location": "L32", + "source_file": "main/service/orunmila_service.py", + "source_location": "L65", "weight": 1.0, "confidence_score": 1.0, - "source": "intflag", - "target": "utils_roles_roles" + "source": "main_service_orunmila_service_py", + "target": "service_orunmila_service_orunmilaservice" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/orunmila_service.py", + "source_location": "L67", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_orunmila_service_py", + "target": "service_orunmila_service_initialize" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "main/app/stocks_api/compress.py", - "source_location": "L84", + "source_file": "main/service/orunmila_service.py", + "source_location": "L68", "weight": 1.0, - "source": "stocks_api_compress_tocolumnar", - "target": "utils_roles_all" + "source": "service_orunmila_service_initialize", + "target": "utils_service_manager_getapp" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "main/app/stocks_api/compressor.py", - "source_location": "L91", + "source_file": "main/service/orunmila_service.py", + "source_location": "L71", "weight": 1.0, - "source": "stocks_api_compressor_tocolumnar", - "target": "utils_roles_all" + "source": "service_orunmila_service_initialize", + "target": "models_loader_getembeddingmodel" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "tests/test_vector_utils.py", - "source_location": "L112", + "source_file": "main/service/orunmila_service.py", + "source_location": "L73", "weight": 1.0, - "source": "utils_roles_all", - "target": "tests_test_vector_utils_testcontenthash_test_hex_format" + "source": "service_orunmila_service_initialize", + "target": "utils_scheduler_registerjob" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/app/prometheus/memory.py", - "source_location": "L23", - "weight": 0.8, - "confidence_score": 0.5, - "source": "prometheus_memory_memorycandidate", - "target": "utils_roles_roles" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/scraper_service.py", + "source_location": "L14", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_scraper_service_py", + "target": "service_scraper_service_runscraper" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "main/app/prometheus/memory.py", - "source_location": "L9", - "weight": 0.8, - "confidence_score": 0.5, - "source": "prometheus_memory_prometheusmemory", - "target": "utils_roles_roles" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/scraper_service.py", + "source_location": "L22", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_scraper_service_py", + "target": "service_scraper_service_registerscraperjobs" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_roles.py", - "source_location": "L7", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_roles_testpermission" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/scraper_service.py", + "source_location": "L25", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_scraper_service_py", + "target": "service_scraper_service_scraperservice" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_roles.py", - "source_location": "L7", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_roles_testroles" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/scraper_service.py", + "source_location": "L27", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_scraper_service_py", + "target": "service_scraper_service_initialize" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/service/scraper_service.py", + "source_location": "L60", + "weight": 1.0, + "confidence_score": 1.0, + "source": "service_scraper_service_initialize", + "target": "service_scraper_service_registerscraperjobs" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/service/scraper_service.py", + "source_location": "L42", + "weight": 1.0, + "source": "service_scraper_service_registerscraperjobs", + "target": "utils_scheduler_registerjob" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/service/scraper_service.py", + "source_location": "L23", + "weight": 1.0, + "confidence_score": 1.0, + "source": "service_scraper_service_rationale_23", + "target": "service_scraper_service_registerscraperjobs" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/stocksapi_service.py", + "source_location": "L10", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_stocksapi_service_py", + "target": "service_stocksapi_service_mcpdetectmiddleware" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/stocksapi_service.py", + "source_location": "L6", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_stocksapi_service_py", + "target": "service_stocksapi_service_stocksapiservice" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/stocksapi_service.py", + "source_location": "L8", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_stocksapi_service_py", + "target": "service_stocksapi_service_initialize" + }, + { + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/service/stocksapi_service.py", + "source_location": "L11", + "weight": 1.0, + "confidence_score": 1.0, + "source": "service_stocksapi_service_mcpdetectmiddleware", + "target": "service_stocksapi_service_mcpdetectmiddleware_init" + }, + { + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/service/stocksapi_service.py", + "source_location": "L14", + "weight": 1.0, + "confidence_score": 1.0, + "source": "service_stocksapi_service_mcpdetectmiddleware", + "target": "service_stocksapi_service_mcpdetectmiddleware_call" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_roles_coverage.py", - "source_location": "L65", + "source_file": "main/service/stocksapi_service.py", + "source_location": "L4", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_roles_coverage_testcheckaccess" + "source": "service_stocksapi_service_mcpdetectmiddleware", + "target": "utils_service_manager_servicemanager" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_roles_coverage.py", - "source_location": "L65", + "source_file": "main/service/stocksapi_service.py", + "source_location": "L1", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_roles_coverage_testrequirepermission" + "source": "service_stocksapi_service_stocksapiservice", + "target": "utils_service_manager_servicemanager" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/service/stocksapi_service.py", + "source_location": "L29", + "weight": 1.0, + "source": "service_stocksapi_service_initialize", + "target": "utils_service_manager_getapp" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/user_service.py", + "source_location": "L16", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_user_service_py", + "target": "service_user_service_removeinactivesessions" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/user_service.py", + "source_location": "L4", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_user_service_py", + "target": "service_user_service_userservice" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/user_service.py", + "source_location": "L6", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_user_service_py", + "target": "service_user_service_initialize" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/user_service.py", + "source_location": "L46", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_user_service_py", + "target": "service_user_service_registersessioncleanupjobs" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/user_service.py", + "source_location": "L33", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_user_service_py", + "target": "service_user_service_inactivesessionsscheduler" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_roles_coverage.py", + "source_file": "main/service/user_service.py", + "source_location": "L1", + "weight": 0.8, + "confidence_score": 0.5, + "source": "service_user_service_userservice", + "target": "utils_service_manager_servicemanager" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/service/user_service.py", + "source_location": "L42", + "weight": 1.0, + "source": "service_user_service_initialize", + "target": "utils_service_manager_getapp" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/service/user_service.py", + "source_location": "L48", + "weight": 1.0, + "source": "service_user_service_initialize", + "target": "utils_scheduler_registerjob" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/service/user_service.py", + "source_location": "L72", + "weight": 1.0, + "confidence_score": 1.0, + "source": "service_user_service_initialize", + "target": "service_user_service_registersessioncleanupjobs" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L9", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_walletservice" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L11", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_initialize" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L5", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "fastapi" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L10", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_create_wallet" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L18", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_list_wallets" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L26", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_entrycreate" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L37", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_entryupdate" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L44", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_get_owned_wallet" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L54", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_apply_entries" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L70", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_recalc_holding" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L94", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_add_entry" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L120", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_list_entries" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L132", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_update_entry" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L154", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_delete_entry" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L180", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_stocksapibase" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L184", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_stocksapiheaders" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L189", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_fetchliveprices" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L214", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_fetchcachedclose" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L234", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_get_positions" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L293", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_targetupsert" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L300", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_ratingupsert" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L306", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_get_summary" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L357", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_get_allocation" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L383", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_upsert_target" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L409", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_set_rating" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L429", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_position_at_date" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L436", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_fetchmarketdividends" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L454", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_sync_earnings" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L521", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_list_earnings" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L536", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_fetchpadraocloses" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L559", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_cachedperformance" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/service/wallet_service.py", + "source_location": "L662", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_service_wallet_service_py", + "target": "service_wallet_service_get_performance" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/service/wallet_service.py", + "source_location": "L12", + "weight": 1.0, + "source": "service_wallet_service_initialize", + "target": "utils_service_manager_getapp" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/connectivity.py", + "source_location": "L13", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_connectivity_py", + "target": "utils_connectivity_checkdatabaseconnection" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/connectivity.py", + "source_location": "L51", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_connectivity_py", + "target": "utils_connectivity_checkserviceconnection" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/connectivity.py", + "source_location": "L13", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_connectivity_py", + "target": "utils_connectivity_checkmysqlconnection" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/connectivity.py", + "source_location": "L13", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_connectivity_py", + "target": "utils_connectivity_checksingledb" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_connectivity_coverage.py", + "source_location": "L112", + "weight": 1.0, + "source": "utils_connectivity_checkserviceconnection", + "target": "tests_test_connectivity_coverage_test_service_not_found" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_connectivity_coverage.py", + "source_location": "L124", + "weight": 1.0, + "source": "utils_connectivity_checkserviceconnection", + "target": "tests_test_connectivity_coverage_test_stocks_api_health_ok" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_connectivity_coverage.py", + "source_location": "L139", + "weight": 1.0, + "source": "utils_connectivity_checkserviceconnection", + "target": "tests_test_connectivity_coverage_test_non_stocks_prefix" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_connectivity_coverage.py", + "source_location": "L154", + "weight": 1.0, + "source": "utils_connectivity_checkserviceconnection", + "target": "tests_test_connectivity_coverage_test_non_200_status" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_connectivity_coverage.py", + "source_location": "L164", + "weight": 1.0, + "source": "utils_connectivity_checkserviceconnection", + "target": "tests_test_connectivity_coverage_test_connection_error" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_connectivity_coverage.py", + "source_location": "L174", + "weight": 1.0, + "source": "utils_connectivity_checkserviceconnection", + "target": "tests_test_connectivity_coverage_test_timeout" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_connectivity_coverage.py", + "source_location": "L184", + "weight": 1.0, + "source": "utils_connectivity_checkserviceconnection", + "target": "tests_test_connectivity_coverage_test_request_exception" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_connectivity_coverage.py", + "source_location": "L194", + "weight": 1.0, + "source": "utils_connectivity_checkserviceconnection", + "target": "tests_test_connectivity_coverage_test_generic_exception" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/utils/connectivity.py", + "source_location": "L66", + "weight": 1.0, + "source": "utils_connectivity_checkserviceconnection", + "target": "utils_http_session_get_session" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L5", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_errors_py", + "target": "fastapi" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L13", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_errors_py", + "target": "utils_errors_errorresponse" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L21", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_errors_py", + "target": "utils_errors_requestcontextfilter" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L27", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_errors_py", + "target": "utils_errors_builderrorresponse" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L37", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_errors_py", + "target": "utils_errors_httpexceptionhandler" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L44", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_errors_py", + "target": "utils_errors_validationexceptionhandler" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L56", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_errors_py", + "target": "utils_errors_genericexceptionhandler" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", "source_location": "L65", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_errors_py", + "target": "utils_errors_registererrorhandlers" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L29", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_errors_py", + "target": "utils_errors_build_error_response" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L38", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_errors_py", + "target": "utils_errors_http_exception_handler" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L45", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_errors_py", + "target": "utils_errors_validation_exception_handler" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L57", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_errors_py", + "target": "utils_errors_generic_exception_handler" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L66", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_errors_py", + "target": "utils_errors_register_error_handlers" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L28", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_errors_errorresponse", + "target": "utils_errors_builderrorresponse" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_roles_coverage_testpermissionall" + "source": "utils_errors_errorresponse", + "target": "tests_test_error_handlers_samplebody" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_roles_coverage.py", - "source_location": "L65", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_roles_coverage_testroleshierarchy" + "source": "utils_errors_errorresponse", + "target": "tests_test_error_handlers_testerrorresponsemodel" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "main/app/prometheus/memory.py", - "source_location": "L7", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "prometheus_memory_memorymanager" + "source": "utils_errors_errorresponse", + "target": "tests_test_error_handlers_testrequestcontextfilter" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testissecurescheme" + "source": "utils_errors_errorresponse", + "target": "tests_test_error_handlers_testhttpexceptionhandler" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testhealthendpoint" + "source": "utils_errors_errorresponse", + "target": "tests_test_error_handlers_testvalidationexceptionhandler" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testregisterendpoint" + "source": "utils_errors_errorresponse", + "target": "tests_test_error_handlers_testgenericexceptionhandler" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testloginendpoint" + "source": "utils_errors_errorresponse", + "target": "tests_test_error_handlers_testsuccesspassthrough" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_error_handlers.py", + "source_location": "L56", + "weight": 1.0, + "source": "utils_errors_errorresponse", + "target": "tests_test_error_handlers_testerrorresponsemodel_test_error_response_structure" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_error_handlers.py", + "source_location": "L65", + "weight": 1.0, + "source": "utils_errors_errorresponse", + "target": "tests_test_error_handlers_testerrorresponsemodel_test_error_response_with_detail_and_request_id" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L30", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_errors_errorresponse", + "target": "utils_errors_build_error_response" + }, + { + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L24", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_errors_requestcontextfilter", + "target": "utils_errors_requestcontextfilter_filter" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "main/utils/logging_config.py", + "source_location": "L9", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testlogoutendpoint" + "source": "utils_errors_requestcontextfilter", + "target": "utils_logging_config_discordhandler" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/utils/logging_config.py", + "source_location": "L20", + "weight": 1.0, + "source": "utils_errors_requestcontextfilter", + "target": "utils_logging_config_setuplogging" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testgooglelogin" + "source": "utils_errors_requestcontextfilter", + "target": "tests_test_error_handlers_samplebody" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testgooglecallback" + "source": "utils_errors_requestcontextfilter", + "target": "tests_test_error_handlers_testerrorresponsemodel" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testuserhealth" + "source": "utils_errors_requestcontextfilter", + "target": "tests_test_error_handlers_testrequestcontextfilter" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testgetme" + "source": "utils_errors_requestcontextfilter", + "target": "tests_test_error_handlers_testhttpexceptionhandler" }, { "relation": "uses", "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", "weight": 0.8, "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testupgradeendpoints" + "source": "utils_errors_requestcontextfilter", + "target": "tests_test_error_handlers_testvalidationexceptionhandler" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_errors_requestcontextfilter", + "target": "tests_test_error_handlers_testgenericexceptionhandler" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_error_handlers.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_errors_requestcontextfilter", + "target": "tests_test_error_handlers_testsuccesspassthrough" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_error_handlers.py", + "source_location": "L78", + "weight": 1.0, + "source": "utils_errors_requestcontextfilter", + "target": "tests_test_error_handlers_testrequestcontextfilter_test_injects_request_id_from_contextvar" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_error_handlers.py", + "source_location": "L87", + "weight": 1.0, + "source": "utils_errors_requestcontextfilter", + "target": "tests_test_error_handlers_testrequestcontextfilter_test_empty_request_id_default" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L22", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_errors_requestcontextfilter", + "target": "utils_errors_rationale_22" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L40", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_errors_builderrorresponse", + "target": "utils_errors_httpexceptionhandler" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L52", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_errors_builderrorresponse", + "target": "utils_errors_validationexceptionhandler" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/utils/errors.py", + "source_location": "L61", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_errors_builderrorresponse", + "target": "utils_errors_genericexceptionhandler" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/conftest.py", + "source_location": "L84", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_conftest_stocks_http_client" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/conftest.py", + "source_location": "L93", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_conftest_client" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L31", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_make_auth_client" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L46", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_make_user_client" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L66", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_make_prometheus_client" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L87", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_make_stocksapi_client" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L685", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testgetsessions_test_get_sessions" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L731", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testgetcurrentsession_test_get_current_session_found" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L754", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testgetcurrentsession_test_get_current_session_not_found" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L784", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testrevokesession_test_revoke_session_success" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L807", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testrevokesession_test_revoke_session_not_found" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L832", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testrevokesession_test_revoke_session_failure" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L858", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testrevokeallsessions_test_revoke_all_sessions" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L975", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testprometheusgethistory_test_get_history_found" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L1011", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testprometheusgethistory_test_get_history_not_found" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L1090", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testprometheuschat_test_chat_existing_session_verified" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L1132", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testprometheuschat_test_chat_existing_session_not_owner" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_error_handlers.py", + "source_location": "L28", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_error_handlers_app" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_oauth_cookie_security.py", + "source_location": "L28", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_oauth_cookie_security_make_callback_client" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_sso_state_cookie.py", + "source_location": "L32", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_sso_state_cookie_build_app" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_memory_controller.py", + "source_location": "L38", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_memory_controller_testmemorycontrollerroutes_test_get_memories_rejects_unauthenticated" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_memory_controller.py", + "source_location": "L57", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_memory_controller_testmemorycontrollerroutes_test_get_memories_rejects_basic_user" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_stocks_api_coverage.py", + "source_location": "L1165", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_stocks_api_coverage_testquerycotations_test_cotations_http_route" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_stocks_api_coverage.py", + "source_location": "L1353", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_stocks_api_coverage_testquerylivecotation_test_http_route_returns_200" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_stocks_api_coverage.py", + "source_location": "L1377", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_stocks_api_coverage_testquerylivecotation_test_http_route_search_required" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_stocks_api_coverage.py", + "source_location": "L1466", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_stocks_api_coverage_testquerylivecotation_test_cotations_search_required" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_stocks_api_coverage.py", + "source_location": "L1298", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_stocks_api_coverage_testquerycotations_test_cotations_search_required" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L156", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testregisterendpoint_make_register_client" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L236", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testloginendpoint_make_login_client" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L289", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testlogoutendpoint_make_logout_client" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L433", + "weight": 1.0, + "source": "utils_errors_registererrorhandlers", + "target": "tests_test_controllers_coverage_testgooglecallback_make_callback_client" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/http_session.py", + "source_location": "L9", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_http_session_py", + "target": "utils_http_session_getsession" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/http_session.py", + "source_location": "L22", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_http_session_py", + "target": "utils_http_session_cleanup" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/http_session.py", + "source_location": "L8", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_http_session_py", + "target": "utils_http_session_get_session" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/logging_config.py", + "source_location": "L12", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_logging_config_py", + "target": "utils_logging_config_setuplogging" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/logging_config.py", + "source_location": "L24", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_logging_config_py", + "target": "utils_logging_config_discordhandler" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/logging_config.py", + "source_location": "L49", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_logging_config_py", + "target": "utils_logging_config_setupdiscordhandler" + }, + { + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/utils/logging_config.py", + "source_location": "L37", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_logging_config_discordhandler", + "target": "utils_logging_config_discordhandler_init" + }, + { + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/utils/logging_config.py", + "source_location": "L25", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_logging_config_discordhandler", + "target": "utils_logging_config_discordhandler_emit" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/utils/logging_config.py", + "source_location": "L51", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_logging_config_discordhandler", + "target": "utils_logging_config_setupdiscordhandler" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_logging_config_coverage.py", + "source_location": "L9", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_logging_config_discordhandler", + "target": "tests_test_logging_config_coverage_testdiscordhandleremit" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_logging_config_coverage.py", + "source_location": "L9", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_logging_config_discordhandler", + "target": "tests_test_logging_config_coverage_testsetuplogging" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_thread_safety.py", + "source_location": "L138", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_logging_config_discordhandler", + "target": "tests_test_thread_safety_testgetsession" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_thread_safety.py", + "source_location": "L138", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_logging_config_discordhandler", + "target": "tests_test_thread_safety_testdiscordhandlerthreadpool" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_thread_safety.py", + "source_location": "L138", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_logging_config_discordhandler", + "target": "tests_test_thread_safety_testconcurrentgetsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_logging_config_coverage.py", + "source_location": "L10", + "weight": 1.0, + "source": "utils_logging_config_discordhandler", + "target": "tests_test_logging_config_coverage_testdiscordhandleremit_make_handler" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_thread_safety.py", + "source_location": "L110", + "weight": 1.0, + "source": "utils_logging_config_discordhandler", + "target": "tests_test_thread_safety_testdiscordhandlerthreadpool_test_emit_submits_to_executor" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_thread_safety.py", + "source_location": "L140", + "weight": 1.0, + "source": "utils_logging_config_discordhandler", + "target": "tests_test_thread_safety_testdiscordhandlerthreadpool_test_concurrent_emits_do_not_spawn_unbounded_threads" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_thread_safety.py", + "source_location": "L138", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_logging_config_discordhandler", + "target": "tests_test_thread_safety_testconcurrenthttpproxy" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_logging_config_coverage.py", + "source_location": "L107", + "weight": 1.0, + "source": "utils_logging_config_setupdiscordhandler", + "target": "tests_test_logging_config_coverage_test_setup_discord_handler_enabled" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_logging_config_coverage.py", + "source_location": "L113", + "weight": 1.0, + "source": "utils_logging_config_setupdiscordhandler", + "target": "tests_test_logging_config_coverage_test_setup_discord_handler_disabled" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/migrator.py", + "source_location": "L8", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_migrator_py", + "target": "utils_migrator_runmigrations" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/request_id.py", + "source_location": "L13", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_request_id_py", + "target": "utils_request_id_requestidmiddleware" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/utils/request_id.py", + "source_location": "L13", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_request_id_requestidmiddleware", + "target": "basehttpmiddleware" + }, + { + "relation": "method", + "confidence": "EXTRACTED", + "source_file": "main/utils/request_id.py", + "source_location": "L14", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_request_id_requestidmiddleware", + "target": "utils_request_id_requestidmiddleware_dispatch" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_error_handlers.py", + "source_location": "L17", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_request_id_requestidmiddleware", + "target": "tests_test_error_handlers_samplebody" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_error_handlers.py", + "source_location": "L17", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_request_id_requestidmiddleware", + "target": "tests_test_error_handlers_testerrorresponsemodel" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_error_handlers.py", + "source_location": "L17", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_request_id_requestidmiddleware", + "target": "tests_test_error_handlers_testrequestcontextfilter" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_error_handlers.py", + "source_location": "L17", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_request_id_requestidmiddleware", + "target": "tests_test_error_handlers_testhttpexceptionhandler" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_error_handlers.py", + "source_location": "L17", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_request_id_requestidmiddleware", + "target": "tests_test_error_handlers_testvalidationexceptionhandler" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_error_handlers.py", + "source_location": "L17", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_request_id_requestidmiddleware", + "target": "tests_test_error_handlers_testgenericexceptionhandler" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_error_handlers.py", + "source_location": "L17", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_request_id_requestidmiddleware", + "target": "tests_test_error_handlers_testsuccesspassthrough" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_request_id.py", + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_request_id_requestidmiddleware", + "target": "tests_test_request_id_testrequestidmiddleware" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "main/utils/roles.py", + "source_location": "L2", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_roles_py", + "target": "fastapi" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/roles.py", + "source_location": "L4", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_roles_py", + "target": "utils_roles_permission" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/roles.py", + "source_location": "L28", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_roles_py", + "target": "utils_roles_all" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/roles.py", + "source_location": "L32", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_roles_py", + "target": "utils_roles_roles" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/roles.py", + "source_location": "L51", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_roles_py", + "target": "utils_roles_checkaccess" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/roles.py", + "source_location": "L64", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_roles_py", + "target": "utils_roles_requirepermission" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/roles.py", + "source_location": "L63", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_roles_py", + "target": "utils_roles_servicetoken" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/roles.py", + "source_location": "L69", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_roles_py", + "target": "utils_roles_introspecturl" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/roles.py", + "source_location": "L75", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_roles_py", + "target": "utils_roles_extractcredential" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/roles.py", + "source_location": "L92", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_roles_py", + "target": "utils_roles_introspectuser" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/utils/roles.py", + "source_location": "L4", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_roles_permission", + "target": "intflag" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/prometheus/memory.py", + "source_location": "L23", + "weight": 0.8, + "confidence_score": 0.5, + "source": "prometheus_memory_memorycandidate", + "target": "utils_roles_permission" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/prometheus/memory.py", + "source_location": "L9", + "weight": 0.8, + "confidence_score": 0.5, + "source": "prometheus_memory_prometheusmemory", + "target": "utils_roles_permission" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_roles.py", + "source_location": "L7", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_roles_testpermission" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_roles.py", + "source_location": "L7", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_roles_testroles" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_roles_coverage.py", + "source_location": "L5", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_roles_coverage_testcheckaccess" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_roles_coverage.py", + "source_location": "L5", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_roles_coverage_testrequirepermission" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_roles_coverage.py", + "source_location": "L5", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_roles_coverage_testpermissionall" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_roles_coverage.py", + "source_location": "L5", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_roles_coverage_testroleshierarchy" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/prometheus/memory.py", + "source_location": "L7", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "prometheus_memory_memorymanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_memory_manager.py", + "source_location": "L6", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_memory_manager_testgetmemorylimit" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_memory_manager.py", + "source_location": "L6", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_memory_manager_testupsertmemory" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_memory_manager.py", + "source_location": "L6", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_memory_manager_testcountmemories" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_memory_manager.py", + "source_location": "L6", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_memory_manager_testgetusermemories" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_memory_manager.py", + "source_location": "L6", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_memory_manager_testdeletememory" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_memory_manager.py", + "source_location": "L6", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_memory_manager_testsearchfulltext" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testissecurescheme" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testhealthendpoint" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testregisterendpoint" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testloginendpoint" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testlogoutendpoint" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testgooglelogin" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testgooglecallback" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testuserhealth" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testgetme" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testupgradeendpoints" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testadminaccess" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testgetsessions" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testgetcurrentsession" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testrevokesession" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testrevokeallsessions" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testprometheushealth" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testprometheusgetsessions" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testprometheuscreatesession" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testprometheusupdatesessiontitle" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testprometheusgethistory" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testprometheusdeletesession" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testprometheuschat" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_teststocksapihealth" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_teststocksapikeytest" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_teststocksapihistorical" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_teststocksapifundamental" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_teststocksapigeneratekey" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testaddroletouser" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testgetcurrentuser" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testhashpasswordempty" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testverifyaccesstoken" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testextracttokenpayloadreraise" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_permission", + "target": "tests_test_controllers_coverage_testmanagerinit" + }, + { + "relation": "inherits", + "confidence": "EXTRACTED", + "source_file": "main/utils/roles.py", + "source_location": "L32", + "weight": 1.0, + "confidence_score": 1.0, + "source": "intflag", + "target": "utils_roles_roles" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/stocks_api/compress.py", + "source_location": "L84", + "weight": 1.0, + "source": "stocks_api_compress_tocolumnar", + "target": "utils_roles_all" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/stocks_api/compressor.py", + "source_location": "L91", + "weight": 1.0, + "source": "stocks_api_compressor_tocolumnar", + "target": "utils_roles_all" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "tests/test_vector_utils.py", + "source_location": "L112", + "weight": 1.0, + "source": "utils_roles_all", + "target": "tests_test_vector_utils_testcontenthash_test_hex_format" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/prometheus/memory.py", + "source_location": "L23", + "weight": 0.8, + "confidence_score": 0.5, + "source": "prometheus_memory_memorycandidate", + "target": "utils_roles_roles" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/prometheus/memory.py", + "source_location": "L9", + "weight": 0.8, + "confidence_score": 0.5, + "source": "prometheus_memory_prometheusmemory", + "target": "utils_roles_roles" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_roles.py", + "source_location": "L7", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_roles_testpermission" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_roles.py", + "source_location": "L7", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_roles_testroles" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_roles_coverage.py", + "source_location": "L65", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_roles_coverage_testcheckaccess" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_roles_coverage.py", + "source_location": "L65", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_roles_coverage_testrequirepermission" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_roles_coverage.py", + "source_location": "L65", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_roles_coverage_testpermissionall" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_roles_coverage.py", + "source_location": "L65", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_roles_coverage_testroleshierarchy" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/prometheus/memory.py", + "source_location": "L7", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "prometheus_memory_memorymanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testissecurescheme" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testhealthendpoint" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testregisterendpoint" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testloginendpoint" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testlogoutendpoint" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testgooglelogin" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testgooglecallback" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testuserhealth" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testgetme" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testupgradeendpoints" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testadminaccess" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testgetsessions" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testgetcurrentsession" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testrevokesession" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testrevokeallsessions" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testprometheushealth" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testprometheusgetsessions" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testprometheuscreatesession" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testprometheusupdatesessiontitle" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testprometheusgethistory" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testprometheusdeletesession" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testprometheuschat" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_teststocksapihealth" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_teststocksapikeytest" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_teststocksapihistorical" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_teststocksapifundamental" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_teststocksapigeneratekey" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testaddroletouser" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testgetcurrentuser" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testhashpasswordempty" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testverifyaccesstoken" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testextracttokenpayloadreraise" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "tests/test_controllers_coverage.py", + "source_location": "L61", + "weight": 0.8, + "confidence_score": 0.5, + "source": "utils_roles_roles", + "target": "tests_test_controllers_coverage_testmanagerinit" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/scheduler.py", + "source_location": "L32", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_scheduler_py", + "target": "utils_scheduler_getsharedscheduler" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/scheduler.py", + "source_location": "L42", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_scheduler_py", + "target": "utils_scheduler_registerjob" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/utils/scheduler.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_scheduler_rationale_1", + "target": "main_utils_scheduler_py" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/utils/scheduler.py", + "source_location": "L50", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_scheduler_registerjob", + "target": "utils_scheduler_getsharedscheduler" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/utils/scheduler.py", + "source_location": "L33", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_scheduler_rationale_33", + "target": "utils_scheduler_getsharedscheduler" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/service/prometheus_service.py", + "source_location": "L70", + "weight": 1.0, + "source": "service_prometheus_service_initialize", + "target": "utils_scheduler_registerjob" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/service/user_service.py", + "source_location": "L55", + "weight": 1.0, + "source": "service_user_service_registersessioncleanupjobs", + "target": "utils_scheduler_registerjob" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/service/prometheus_service.py", + "source_location": "L69", + "weight": 1.0, + "source": "service_prometheus_service_registermemorymaintenancejob", + "target": "utils_scheduler_registerjob" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/utils/scheduler.py", + "source_location": "L43", + "weight": 1.0, + "confidence_score": 1.0, + "source": "utils_scheduler_rationale_43", + "target": "utils_scheduler_registerjob" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "main/utils/service_manager.py", + "source_location": "L8", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_service_manager_py", + "target": "fastapi" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/service_manager.py", + "source_location": "L21", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_service_manager_py", + "target": "utils_service_manager_getapp" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/service_manager.py", + "source_location": "L48", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_service_manager_py", + "target": "utils_service_manager_runall" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/service_manager.py", + "source_location": "L16", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_service_manager_py", + "target": "utils_service_manager_servicemanager" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/service/prometheus_service.py", + "source_location": "L64", + "weight": 1.0, + "source": "service_prometheus_service_initialize", + "target": "utils_service_manager_getapp" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/models/loader.py", + "source_location": "L12", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_models_loader_py", + "target": "models_loader_getembeddingmodel" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/models/loader.py", + "source_location": "L21", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_models_loader_py", + "target": "models_loader_embed" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/utils/models/loader.py", + "source_location": "L11", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_utils_models_loader_py", + "target": "models_loader_downloadmodel" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/prometheus/vector.py", + "source_location": "L11", + "weight": 1.0, + "source": "prometheus_vector_embed", + "target": "models_loader_getembeddingmodel" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/service/prometheus_service.py", + "source_location": "L12", + "weight": 1.0, + "source": "service_prometheus_service_initialize", + "target": "models_loader_getembeddingmodel" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/utils/models/loader.py", + "source_location": "L22", + "weight": 1.0, + "confidence_score": 1.0, + "source": "models_loader_getembeddingmodel", + "target": "models_loader_embed" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/utils/models/loader.py", + "source_location": "L21", + "weight": 1.0, + "confidence_score": 1.0, + "source": "models_loader_getembeddingmodel", + "target": "models_loader_downloadmodel" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/env.py", + "source_location": "L25", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_env_py", + "target": "migrations_env_getdatabaseurl" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/env.py", + "source_location": "L28", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_env_py", + "target": "migrations_env_runmigrationsoffline" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/env.py", + "source_location": "L39", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_env_py", + "target": "migrations_env_runmigrationsonline" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "migrations/env.py", + "source_location": "L30", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_env_getdatabaseurl", + "target": "migrations_env_runmigrationsoffline" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "migrations/env.py", + "source_location": "L41", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_env_getdatabaseurl", + "target": "migrations_env_runmigrationsonline" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/25af7ad931e7_initial_migration.py", + "source_location": "L21", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_25af7ad931e7_initial_migration_py", + "target": "versions_25af7ad931e7_initial_migration_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/25af7ad931e7_initial_migration.py", + "source_location": "L61", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_25af7ad931e7_initial_migration_py", + "target": "versions_25af7ad931e7_initial_migration_downgrade" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/25af7ad931e7_initial_migration.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_25af7ad931e7_initial_migration_py", + "target": "versions_25af7ad931e7_initial_migration_rationale_1" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/4a2f1c9e3b5d_user_sessions.py", + "source_location": "L20", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_4a2f1c9e3b5d_user_sessions_py", + "target": "versions_4a2f1c9e3b5d_user_sessions_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/4a2f1c9e3b5d_user_sessions.py", + "source_location": "L47", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_4a2f1c9e3b5d_user_sessions_py", + "target": "versions_4a2f1c9e3b5d_user_sessions_downgrade" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/4a2f1c9e3b5d_user_sessions.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_4a2f1c9e3b5d_user_sessions_py", + "target": "versions_4a2f1c9e3b5d_user_sessions_rationale_1" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/73211a401c34_wallet_tables.py", + "source_location": "L22", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_73211a401c34_wallet_tables_py", + "target": "versions_73211a401c34_wallet_tables_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/73211a401c34_wallet_tables.py", + "source_location": "L104", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_73211a401c34_wallet_tables_py", + "target": "versions_73211a401c34_wallet_tables_downgrade" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/73211a401c34_wallet_tables.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "versions_73211a401c34_wallet_tables_rationale_1", + "target": "migrations_versions_73211a401c34_wallet_tables_py" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/9f3b339dde20_drop_unused_user_sessions_columns.py", + "source_location": "L43", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_9f3b339dde20_drop_unused_user_sessions_columns_py", + "target": "versions_9f3b339dde20_drop_unused_user_sessions_columns_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/9f3b339dde20_drop_unused_user_sessions_columns.py", + "source_location": "L50", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_9f3b339dde20_drop_unused_user_sessions_columns_py", + "target": "versions_9f3b339dde20_drop_unused_user_sessions_columns_downgrade" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/9f3b339dde20_drop_unused_user_sessions_columns.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_9f3b339dde20_drop_unused_user_sessions_columns_py", + "target": "versions_9f3b339dde20_drop_unused_user_sessions_columns_rationale_1" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/9f3b339dde20_drop_unused_user_sessions_columns.py", + "source_location": "L44", + "weight": 1.0, + "confidence_score": 1.0, + "source": "versions_9f3b339dde20_drop_unused_user_sessions_columns_upgrade", + "target": "versions_9f3b339dde20_drop_unused_user_sessions_columns_rationale_44" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/9f3b339dde20_drop_unused_user_sessions_columns.py", + "source_location": "L51", + "weight": 1.0, + "confidence_score": 1.0, + "source": "versions_9f3b339dde20_drop_unused_user_sessions_columns_downgrade", + "target": "versions_9f3b339dde20_drop_unused_user_sessions_columns_rationale_51" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/add_access_token_hash.py", + "source_location": "L21", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_add_access_token_hash_py", + "target": "versions_add_access_token_hash_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/add_access_token_hash.py", + "source_location": "L54", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_add_access_token_hash_py", + "target": "versions_add_access_token_hash_downgrade" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/add_access_token_hash.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_add_access_token_hash_py", + "target": "versions_add_access_token_hash_rationale_1" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/add_access_token_hash.py", + "source_location": "L22", + "weight": 1.0, + "confidence_score": 1.0, + "source": "versions_add_access_token_hash_upgrade", + "target": "versions_add_access_token_hash_rationale_22" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/add_access_token_hash.py", + "source_location": "L55", + "weight": 1.0, + "confidence_score": 1.0, + "source": "versions_add_access_token_hash_downgrade", + "target": "versions_add_access_token_hash_rationale_55" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/b1c2d3e4f5a6_create_prometheus_memories.py", + "source_location": "L22", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_b1c2d3e4f5a6_create_prometheus_memories_py", + "target": "versions_b1c2d3e4f5a6_create_prometheus_memories_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/b1c2d3e4f5a6_create_prometheus_memories.py", + "source_location": "L50", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_b1c2d3e4f5a6_create_prometheus_memories_py", + "target": "versions_b1c2d3e4f5a6_create_prometheus_memories_downgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/b1c2d3e4f5a6_create_prometheus_memories.py", + "source_location": "L60", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_b1c2d3e4f5a6_create_prometheus_memories_py", + "target": "versions_b1c2d3e4f5a6_create_prometheus_memories_fix_partial" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/b1c2d3e4f5a6_create_prometheus_memories.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_b1c2d3e4f5a6_create_prometheus_memories_py", + "target": "versions_b1c2d3e4f5a6_create_prometheus_memories_rationale_1" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/c2e4f6a8b0c1_drop_embedding_model_version.py", + "source_location": "L22", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_c2e4f6a8b0c1_drop_embedding_model_version_py", + "target": "versions_c2e4f6a8b0c1_drop_embedding_model_version_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/c2e4f6a8b0c1_drop_embedding_model_version.py", + "source_location": "L27", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_c2e4f6a8b0c1_drop_embedding_model_version_py", + "target": "versions_c2e4f6a8b0c1_drop_embedding_model_version_downgrade" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/c2e4f6a8b0c1_drop_embedding_model_version.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_c2e4f6a8b0c1_drop_embedding_model_version_py", + "target": "versions_c2e4f6a8b0c1_drop_embedding_model_version_rationale_1" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/c4d1e8f2a917_wallet_earnings.py", + "source_location": "L27", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_c4d1e8f2a917_wallet_earnings_py", + "target": "versions_c4d1e8f2a917_wallet_earnings_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/c4d1e8f2a917_wallet_earnings.py", + "source_location": "L51", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_c4d1e8f2a917_wallet_earnings_py", + "target": "versions_c4d1e8f2a917_wallet_earnings_downgrade" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/c4d1e8f2a917_wallet_earnings.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "versions_c4d1e8f2a917_wallet_earnings_rationale_1", + "target": "migrations_versions_c4d1e8f2a917_wallet_earnings_py" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/d3df3fc5ca72_rename_memory_base_score.py", + "source_location": "L17", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_d3df3fc5ca72_rename_memory_base_score_py", + "target": "versions_d3df3fc5ca72_rename_memory_base_score_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/d3df3fc5ca72_rename_memory_base_score.py", + "source_location": "L21", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_d3df3fc5ca72_rename_memory_base_score_py", + "target": "versions_d3df3fc5ca72_rename_memory_base_score_downgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/d3e4f5a6b7c8_add_prometheus_sandboxes.py", + "source_location": "L22", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_d3e4f5a6b7c8_add_prometheus_sandboxes_py", + "target": "versions_d3e4f5a6b7c8_add_prometheus_sandboxes_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/d3e4f5a6b7c8_add_prometheus_sandboxes.py", + "source_location": "L36", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_d3e4f5a6b7c8_add_prometheus_sandboxes_py", + "target": "versions_d3e4f5a6b7c8_add_prometheus_sandboxes_downgrade" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/d3e4f5a6b7c8_add_prometheus_sandboxes.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_d3e4f5a6b7c8_add_prometheus_sandboxes_py", + "target": "versions_d3e4f5a6b7c8_add_prometheus_sandboxes_rationale_1" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories.py", + "source_location": "L21", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories_py", + "target": "versions_e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories.py", + "source_location": "L45", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories_py", + "target": "versions_e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories_downgrade" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "versions_e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories_rationale_1", + "target": "migrations_versions_e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories_py" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes.py", + "source_location": "L22", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes_py", + "target": "versions_e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes.py", + "source_location": "L26", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes_py", + "target": "versions_e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes_downgrade" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "versions_e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes_rationale_1", + "target": "migrations_versions_e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes_py" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/f1a2b3c4d5e6_session_gc_index.py", + "source_location": "L26", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_f1a2b3c4d5e6_session_gc_index_py", + "target": "versions_f1a2b3c4d5e6_session_gc_index_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/f1a2b3c4d5e6_session_gc_index.py", + "source_location": "L34", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_f1a2b3c4d5e6_session_gc_index_py", + "target": "versions_f1a2b3c4d5e6_session_gc_index_downgrade" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/f1a2b3c4d5e6_session_gc_index.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "versions_f1a2b3c4d5e6_session_gc_index_rationale_1", + "target": "migrations_versions_f1a2b3c4d5e6_session_gc_index_py" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/f7a8b9c0d1e2_rename_prometheus_to_orunmila.py", + "source_location": "L25", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_f7a8b9c0d1e2_rename_prometheus_to_orunmila_py", + "target": "versions_f7a8b9c0d1e2_rename_prometheus_to_orunmila_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/f7a8b9c0d1e2_rename_prometheus_to_orunmila.py", + "source_location": "L43", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_f7a8b9c0d1e2_rename_prometheus_to_orunmila_py", + "target": "versions_f7a8b9c0d1e2_rename_prometheus_to_orunmila_downgrade" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/f7a8b9c0d1e2_rename_prometheus_to_orunmila.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "versions_f7a8b9c0d1e2_rename_prometheus_to_orunmila_rationale_1", + "target": "migrations_versions_f7a8b9c0d1e2_rename_prometheus_to_orunmila_py" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "agents_md", + "target": "server_agents_project_overview" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L4", + "weight": 1.0, + "confidence_score": 1.0, + "source": "agents_md", + "target": "server_agents_dev_commands" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L23", + "weight": 1.0, + "confidence_score": 1.0, + "source": "agents_md", + "target": "server_agents_architecture" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L47", + "weight": 1.0, + "confidence_score": 1.0, + "source": "agents_md", + "target": "server_agents_code_style" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L34", + "weight": 1.0, + "confidence_score": 1.0, + "source": "agents_md", + "target": "server_agents_testing" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L38", + "weight": 1.0, + "confidence_score": 1.0, + "source": "agents_md", + "target": "server_agents_graphify" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L60", + "weight": 1.0, + "confidence_score": 1.0, + "source": "agents_md", + "target": "server_agents_swarm_delegation_default" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L47", + "weight": 1.0, + "confidence_score": 1.0, + "source": "agents_md", + "target": "server_agents_stocks_api_pandas_first_pattern" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L54", + "weight": 1.0, + "confidence_score": 1.0, + "source": "agents_md", + "target": "server_agents_scraper_b3_xango_batch_data_pipeline" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L60", + "weight": 1.0, + "confidence_score": 1.0, + "source": "agents_md", + "target": "server_agents_auth_users_dual_layer_session_security" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L28", + "weight": 1.0, + "confidence_score": 1.0, + "source": "agents_md", + "target": "server_agents_key_quirks" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L57", + "weight": 1.0, + "confidence_score": 1.0, + "source": "agents_md", + "target": "server_agents_prometheus_ai_chat_strengths_gaps" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L5", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_agents_dev_commands", + "target": "server_agents_codeblock_1" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "AGENTS.md", + "source_location": "L31", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_agents_dev_commands", + "target": "server_agents_ci_pipeline_order" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "README.md", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "readme_md", + "target": "server_readme_mansa_server" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "README.md", + "source_location": "L7", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_readme_mansa_server", + "target": "server_readme_run_with_docker" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "README.md", + "source_location": "L20", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_readme_mansa_server", + "target": "server_readme_environment_setup" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "README.md", + "source_location": "L85", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_readme_mansa_server", + "target": "server_readme_health_check" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "README.md", + "source_location": "L91", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_readme_mansa_server", + "target": "server_readme_license" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "README.md", + "source_location": "L9", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_readme_run_with_docker", + "target": "server_readme_codeblock_1" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "README.md", + "source_location": "L24", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_readme_environment_setup", + "target": "server_readme_codeblock_2" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "README.md", + "source_location": "L87", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_readme_health_check", + "target": "server_readme_codeblock_3" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "TODO.md", + "source_location": "L25", + "weight": 1.0, + "confidence_score": 1.0, + "source": "todo_md", + "target": "server_todo_user_structure_defined_by_string_roles" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "TODO.md", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "todo_md", + "target": "server_todo_priorities_active_order_2026_09_29" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "TODO.md", + "source_location": "L34", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_todo_user_structure_defined_by_string_roles", + "target": "server_todo_user" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "TODO.md", + "source_location": "L37", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_todo_user_structure_defined_by_string_roles", + "target": "server_todo_premium" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "TODO.md", + "source_location": "L40", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_todo_user_structure_defined_by_string_roles", + "target": "server_todo_developer" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "TODO.md", + "source_location": "L67", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_todo_user_structure_defined_by_string_roles", + "target": "server_todo_stocks_api" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "TODO.md", + "source_location": "L70", + "weight": 1.0, + "confidence_score": 1.0, + "source": "server_todo_user_structure_defined_by_string_roles", + "target": "server_todo_prometheus" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_md", + "target": "docs_authentication_authentication_management" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L5", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_token_session_lifetime" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L11", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_token_extraction_order" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L21", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_cookie_handling_conditional_secure" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L30", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_session_data_model_family_only" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L39", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_roles_and_permissions" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L61", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_rate_limits" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L49", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_api_endpoints" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L117", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_security_features" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L138", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_not_implemented" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L154", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_workflow" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L187", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_license" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L9", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_usage" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L130", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_device_detection" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L144", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_authentication_management", + "target": "docs_authentication_session_management" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L51", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_api_endpoints", + "target": "docs_authentication_health_check" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L57", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_api_endpoints", + "target": "docs_authentication_user_registration" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L65", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_api_endpoints", + "target": "docs_authentication_user_login" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L84", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_api_endpoints", + "target": "docs_authentication_logout" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L94", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_api_endpoints", + "target": "docs_authentication_google_oauth2_login" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L120", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_api_endpoints", + "target": "docs_authentication_google_callback_cookie_only" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L77", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_api_endpoints", + "target": "docs_authentication_profile_me" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L108", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_api_endpoints", + "target": "docs_authentication_google_callback" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L76", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_health_check", + "target": "docs_authentication_codeblock_1" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L52", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_health_check", + "target": "docs_authentication_codeblock_2" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L11", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_usage", + "target": "docs_authentication_codeblock_1" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L84", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_user_registration", + "target": "docs_authentication_codeblock_2" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L59", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_user_registration", + "target": "docs_authentication_codeblock_3" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L94", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_user_login", + "target": "docs_authentication_codeblock_3" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L67", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_user_login", + "target": "docs_authentication_codeblock_4" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L104", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_logout", + "target": "docs_authentication_codeblock_4" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L86", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_logout", + "target": "docs_authentication_codeblock_6" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L113", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_google_oauth2_login", + "target": "docs_authentication_codeblock_5" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L98", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_google_oauth2_login", + "target": "docs_authentication_codeblock_7" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L104", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_google_oauth2_login", + "target": "docs_authentication_codeblock_8" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L79", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_profile_me", + "target": "docs_authentication_codeblock_5" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L144", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_workflow", + "target": "docs_authentication_codeblock_6" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/authentication.md", + "source_location": "L156", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_authentication_workflow", + "target": "docs_authentication_codeblock_9" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/orunmila.md", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_orunmila_md", + "target": "docs_orunmila_orunmila" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/orunmila.md", + "source_location": "L7", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_orunmila_orunmila", + "target": "docs_orunmila_usage" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/orunmila.md", + "source_location": "L53", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_orunmila_orunmila", + "target": "docs_orunmila_workflow" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/orunmila.md", + "source_location": "L65", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_orunmila_orunmila", + "target": "docs_orunmila_api_endpoints" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/orunmila.md", + "source_location": "L72", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_orunmila_orunmila", + "target": "docs_orunmila_license" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/orunmila.md", + "source_location": "L9", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_orunmila_usage", + "target": "docs_orunmila_codeblock_1" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/orunmila.md", + "source_location": "L49", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_orunmila_usage", + "target": "docs_orunmila_codeblock_2" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/orunmila.md", + "source_location": "L55", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_orunmila_workflow", + "target": "docs_orunmila_codeblock_3" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/scraper_b3.md", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_scraper_b3_md", + "target": "docs_scraper_b3_b3_market_scraper" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/scraper_b3.md", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_scraper_b3_md", + "target": "docs_scraper_b3_brazilian_stocks_market_scraper" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/scraper_b3.md", + "source_location": "L5", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_scraper_b3_b3_market_scraper", + "target": "docs_scraper_b3_sources_6" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/scraper_b3.md", + "source_location": "L19", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_scraper_b3_b3_market_scraper", + "target": "docs_scraper_b3_scheduling_config_config_py_77_81_scraper_service_py_23_36" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/scraper_b3.md", + "source_location": "L31", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_scraper_b3_b3_market_scraper", + "target": "docs_scraper_b3_xango_score_main_app_scraper_b3_xango_py" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/scraper_b3.md", + "source_location": "L41", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_scraper_b3_b3_market_scraper", + "target": "docs_scraper_b3_outputs" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/scraper_b3.md", + "source_location": "L21", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_scraper_b3_scheduling_config_config_py_77_81_scraper_service_py_23_36", + "target": "docs_scraper_b3_codeblock_1" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/scraper_b3.md", + "source_location": "L8", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_scraper_b3_usage", + "target": "docs_scraper_b3_codeblock_1" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_md", + "target": "docs_stocks_api_brazilian_stocks_market_api" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L7", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_brazilian_stocks_market_api", + "target": "docs_stocks_api_usage" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L22", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_brazilian_stocks_market_api", + "target": "docs_stocks_api_auth" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L32", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_brazilian_stocks_market_api", + "target": "docs_stocks_api_api_endpoints" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L90", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_brazilian_stocks_market_api", + "target": "docs_stocks_api_response_format" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L119", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_brazilian_stocks_market_api", + "target": "docs_stocks_api_architecture" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L113", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_brazilian_stocks_market_api", + "target": "docs_stocks_api_license" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L9", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_usage", + "target": "docs_stocks_api_codeblock_1" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L34", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_api_endpoints", + "target": "docs_stocks_api_health_check" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L40", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_api_endpoints", + "target": "docs_stocks_api_field_discovery" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L53", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_api_endpoints", + "target": "docs_stocks_api_historical_data" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L72", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_api_endpoints", + "target": "docs_stocks_api_fundamental_data" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L74", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_api_endpoints", + "target": "docs_stocks_api_cotations_10_year_daily_history" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L87", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_api_endpoints", + "target": "docs_stocks_api_live_price" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L98", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_api_endpoints", + "target": "docs_stocks_api_mcp_ai_agent_tools" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L40", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_api_endpoints", + "target": "docs_stocks_api_api_key_verification" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L45", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_api_endpoints", + "target": "docs_stocks_api_key_management" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L35", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_health_check", + "target": "docs_stocks_api_codeblock_2" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L42", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_field_discovery", + "target": "docs_stocks_api_codeblock_3" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L41", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_api_key_verification", + "target": "docs_stocks_api_codeblock_3" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L50", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_historical_data", + "target": "docs_stocks_api_codeblock_4" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L55", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_historical_data", + "target": "docs_stocks_api_codeblock_5" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L68", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_historical_data", + "target": "docs_stocks_api_codeblock_6" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L47", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_key_management", + "target": "docs_stocks_api_codeblock_4" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L63", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_fundamental_data", + "target": "docs_stocks_api_codeblock_5" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L74", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_fundamental_data", + "target": "docs_stocks_api_codeblock_7" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L86", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_fundamental_data", + "target": "docs_stocks_api_codeblock_8" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L76", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_cotations_10_year_daily_history", + "target": "docs_stocks_api_codeblock_6" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testadminaccess" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L89", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_live_price", + "target": "docs_stocks_api_codeblock_7" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testgetsessions" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L106", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_response_format", + "target": "docs_stocks_api_codeblock_8" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testgetcurrentsession" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/stocks_api.md", + "source_location": "L94", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_stocks_api_response_format", + "target": "docs_stocks_api_codeblock_9" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testrevokesession" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_md", + "target": "docs_user_user_management" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testrevokeallsessions" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L5", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_user_management", + "target": "docs_user_roles_and_permissions" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testprometheushealth" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L17", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_user_management", + "target": "docs_user_api_endpoints" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testprometheusgetsessions" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L59", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_user_management", + "target": "docs_user_session_management" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testprometheuscreatesession" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L112", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_user_management", + "target": "docs_user_api_keys_stocks_api" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testprometheusupdatesessiontitle" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L123", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_user_management", + "target": "docs_user_rate_limits_related_services" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testprometheusgethistory" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L135", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_user_management", + "target": "docs_user_not_implemented" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testprometheusdeletesession" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L156", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_user_management", + "target": "docs_user_workflow" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testprometheuschat" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L177", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_user_management", + "target": "docs_user_license" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_teststocksapihealth" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L140", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_user_management", + "target": "docs_user_permission_system" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_teststocksapikeytest" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L19", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_api_endpoints", + "target": "docs_user_health_check" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_teststocksapihistorical" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L25", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_api_endpoints", + "target": "docs_user_get_profile" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_teststocksapifundamental" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L53", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_api_endpoints", + "target": "docs_user_admin_access" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_teststocksapigeneratekey" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L41", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_api_endpoints", + "target": "docs_user_upgrade_to_developer_starter" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testaddroletouser" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L47", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_api_endpoints", + "target": "docs_user_upgrade_to_developer_enterprise" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testgetcurrentuser" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L20", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_health_check", + "target": "docs_user_codeblock_1" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testhashpasswordempty" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L27", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_get_profile", + "target": "docs_user_codeblock_2" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testverifyaccesstoken" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L31", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_get_profile", + "target": "docs_user_codeblock_3" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testextracttokenpayloadreraise" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L39", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_admin_access", + "target": "docs_user_codeblock_3" }, { - "relation": "uses", - "confidence": "INFERRED", - "source_file": "tests/test_controllers_coverage.py", - "source_location": "L61", - "weight": 0.8, - "confidence_score": 0.5, - "source": "utils_roles_roles", - "target": "tests_test_controllers_coverage_testmanagerinit" + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L55", + "weight": 1.0, + "confidence_score": 1.0, + "source": "docs_user_admin_access", + "target": "docs_user_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/scheduler.py", - "source_location": "L32", + "source_file": "docs/user.md", + "source_location": "L63", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_scheduler_py", - "target": "utils_scheduler_getsharedscheduler" + "source": "docs_user_session_management", + "target": "docs_user_list_all_sessions" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/scheduler.py", - "source_location": "L42", + "source_file": "docs/user.md", + "source_location": "L92", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_scheduler_py", - "target": "utils_scheduler_registerjob" + "source": "docs_user_session_management", + "target": "docs_user_get_current_session" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/scheduler.py", - "source_location": "L1", + "source_file": "docs/user.md", + "source_location": "L114", "weight": 1.0, "confidence_score": 1.0, - "source": "utils_scheduler_rationale_1", - "target": "main_utils_scheduler_py" + "source": "docs_user_session_management", + "target": "docs_user_revoke_a_session" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/scheduler.py", - "source_location": "L50", + "source_file": "docs/user.md", + "source_location": "L127", "weight": 1.0, "confidence_score": 1.0, - "source": "utils_scheduler_registerjob", - "target": "utils_scheduler_getsharedscheduler" + "source": "docs_user_session_management", + "target": "docs_user_revoke_all_sessions" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/scheduler.py", - "source_location": "L33", + "source_file": "docs/user.md", + "source_location": "L55", "weight": 1.0, "confidence_score": 1.0, - "source": "utils_scheduler_rationale_33", - "target": "utils_scheduler_getsharedscheduler" + "source": "docs_user_list_all_sessions", + "target": "docs_user_codeblock_4" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/service/prometheus_service.py", - "source_location": "L70", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L59", "weight": 1.0, - "source": "service_prometheus_service_initialize", - "target": "utils_scheduler_registerjob" + "confidence_score": 1.0, + "source": "docs_user_list_all_sessions", + "target": "docs_user_codeblock_5" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/service/user_service.py", - "source_location": "L55", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L65", "weight": 1.0, - "source": "service_user_service_registersessioncleanupjobs", - "target": "utils_scheduler_registerjob" + "confidence_score": 1.0, + "source": "docs_user_list_all_sessions", + "target": "docs_user_codeblock_7" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/service/prometheus_service.py", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", "source_location": "L69", "weight": 1.0, - "source": "service_prometheus_service_registermemorymaintenancejob", - "target": "utils_scheduler_registerjob" + "confidence_score": 1.0, + "source": "docs_user_list_all_sessions", + "target": "docs_user_codeblock_8" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/scheduler.py", + "source_file": "docs/user.md", "source_location": "L43", "weight": 1.0, "confidence_score": 1.0, - "source": "utils_scheduler_rationale_43", - "target": "utils_scheduler_registerjob" + "source": "docs_user_upgrade_to_developer_starter", + "target": "docs_user_codeblock_4" }, { - "relation": "imports_from", - "context": "import", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/service_manager.py", - "source_location": "L8", + "source_file": "docs/user.md", + "source_location": "L49", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_service_manager_py", - "target": "fastapi" + "source": "docs_user_upgrade_to_developer_enterprise", + "target": "docs_user_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/service_manager.py", - "source_location": "L21", + "source_file": "docs/user.md", + "source_location": "L83", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_service_manager_py", - "target": "utils_service_manager_getapp" + "source": "docs_user_get_current_session", + "target": "docs_user_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/service_manager.py", - "source_location": "L48", + "source_file": "docs/user.md", + "source_location": "L94", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_service_manager_py", - "target": "utils_service_manager_runall" + "source": "docs_user_get_current_session", + "target": "docs_user_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/service_manager.py", - "source_location": "L16", + "source_file": "docs/user.md", + "source_location": "L98", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_service_manager_py", - "target": "utils_service_manager_servicemanager" + "source": "docs_user_get_current_session", + "target": "docs_user_codeblock_10" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/service/prometheus_service.py", - "source_location": "L64", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L91", "weight": 1.0, - "source": "service_prometheus_service_initialize", - "target": "utils_service_manager_getapp" + "confidence_score": 1.0, + "source": "docs_user_revoke_a_session", + "target": "docs_user_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/models/loader.py", - "source_location": "L12", + "source_file": "docs/user.md", + "source_location": "L116", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_models_loader_py", - "target": "models_loader_getembeddingmodel" + "source": "docs_user_revoke_a_session", + "target": "docs_user_codeblock_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/models/loader.py", - "source_location": "L21", + "source_file": "docs/user.md", + "source_location": "L120", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_models_loader_py", - "target": "models_loader_embed" + "source": "docs_user_revoke_a_session", + "target": "docs_user_codeblock_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/models/loader.py", - "source_location": "L11", + "source_file": "docs/user.md", + "source_location": "L101", "weight": 1.0, "confidence_score": 1.0, - "source": "main_utils_models_loader_py", - "target": "models_loader_downloadmodel" + "source": "docs_user_revoke_all_sessions", + "target": "docs_user_codeblock_8" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/prometheus/vector.py", - "source_location": "L11", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L105", "weight": 1.0, - "source": "prometheus_vector_embed", - "target": "models_loader_getembeddingmodel" + "confidence_score": 1.0, + "source": "docs_user_revoke_all_sessions", + "target": "docs_user_codeblock_9" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/service/prometheus_service.py", - "source_location": "L12", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "docs/user.md", + "source_location": "L129", "weight": 1.0, - "source": "service_prometheus_service_initialize", - "target": "models_loader_getembeddingmodel" + "confidence_score": 1.0, + "source": "docs_user_revoke_all_sessions", + "target": "docs_user_codeblock_13" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/models/loader.py", - "source_location": "L22", + "source_file": "docs/user.md", + "source_location": "L133", "weight": 1.0, "confidence_score": 1.0, - "source": "models_loader_getembeddingmodel", - "target": "models_loader_embed" + "source": "docs_user_revoke_all_sessions", + "target": "docs_user_codeblock_14" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/utils/models/loader.py", - "source_location": "L21", + "source_file": "docs/user.md", + "source_location": "L141", "weight": 1.0, "confidence_score": 1.0, - "source": "models_loader_getembeddingmodel", - "target": "models_loader_downloadmodel" + "source": "docs_user_workflow", + "target": "docs_user_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/env.py", - "source_location": "L25", + "source_file": "docs/user.md", + "source_location": "L158", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_env_py", - "target": "migrations_env_getdatabaseurl" + "source": "docs_user_workflow", + "target": "docs_user_codeblock_16" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/env.py", - "source_location": "L28", + "source_file": "docs/superpowers/investidor10-wallet-research.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_env_py", - "target": "migrations_env_runmigrationsoffline" + "source": "docs_superpowers_investidor10_wallet_research_md", + "target": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/env.py", - "source_location": "L39", + "source_file": "docs/superpowers/investidor10-wallet-research.md", + "source_location": "L10", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_env_py", - "target": "migrations_env_runmigrationsonline" + "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", + "target": "superpowers_investidor10_wallet_research_1_feature_inventory_nav_structure" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/env.py", + "source_file": "docs/superpowers/investidor10-wallet-research.md", "source_location": "L30", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_env_getdatabaseurl", - "target": "migrations_env_runmigrationsoffline" + "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", + "target": "superpowers_investidor10_wallet_research_2_user_lifecycle_end_to_end" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/env.py", - "source_location": "L41", + "source_file": "docs/superpowers/investidor10-wallet-research.md", + "source_location": "L40", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_env_getdatabaseurl", - "target": "migrations_env_runmigrationsonline" + "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", + "target": "superpowers_investidor10_wallet_research_3_wallet_api_reference" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/25af7ad931e7_initial_migration.py", - "source_location": "L21", + "source_file": "docs/superpowers/investidor10-wallet-research.md", + "source_location": "L65", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_25af7ad931e7_initial_migration_py", - "target": "versions_25af7ad931e7_initial_migration_upgrade" + "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", + "target": "superpowers_investidor10_wallet_research_4_data_model_inference_from_payloads_no_db_access" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/25af7ad931e7_initial_migration.py", - "source_location": "L61", + "source_file": "docs/superpowers/investidor10-wallet-research.md", + "source_location": "L74", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_25af7ad931e7_initial_migration_py", - "target": "versions_25af7ad931e7_initial_migration_downgrade" + "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", + "target": "superpowers_investidor10_wallet_research_5_product_logic" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/25af7ad931e7_initial_migration.py", - "source_location": "L1", + "source_file": "docs/superpowers/investidor10-wallet-research.md", + "source_location": "L82", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_25af7ad931e7_initial_migration_py", - "target": "versions_25af7ad931e7_initial_migration_rationale_1" + "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", + "target": "superpowers_investidor10_wallet_research_5b_gaps_unverified_do_not_treat_as_fact" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/4a2f1c9e3b5d_user_sessions.py", - "source_location": "L20", + "source_file": "docs/superpowers/investidor10-wallet-research.md", + "source_location": "L86", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_4a2f1c9e3b5d_user_sessions_py", - "target": "versions_4a2f1c9e3b5d_user_sessions_upgrade" + "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", + "target": "superpowers_investidor10_wallet_research_6_concrete_mansa_proposal_build_first_later_minimal_sketches" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/4a2f1c9e3b5d_user_sessions.py", - "source_location": "L47", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_4a2f1c9e3b5d_user_sessions_py", - "target": "versions_4a2f1c9e3b5d_user_sessions_downgrade" + "source": "docs_superpowers_investidor10_wallet_spec_md", + "target": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/4a2f1c9e3b5d_user_sessions.py", - "source_location": "L1", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L12", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_4a2f1c9e3b5d_user_sessions_py", - "target": "versions_4a2f1c9e3b5d_user_sessions_rationale_1" + "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", + "target": "superpowers_investidor10_wallet_spec_1_requirements" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/9f3b339dde20_drop_unused_user_sessions_columns.py", - "source_location": "L43", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L38", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_9f3b339dde20_drop_unused_user_sessions_columns_py", - "target": "versions_9f3b339dde20_drop_unused_user_sessions_columns_upgrade" + "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", + "target": "superpowers_investidor10_wallet_spec_2_domain_model" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/9f3b339dde20_drop_unused_user_sessions_columns.py", - "source_location": "L50", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L58", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_9f3b339dde20_drop_unused_user_sessions_columns_py", - "target": "versions_9f3b339dde20_drop_unused_user_sessions_columns_downgrade" + "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", + "target": "superpowers_investidor10_wallet_spec_3_api_contracts_all_under_wallet_chain_main_controller_wallet_controller_py_main_service_wallet_service_py_fn_main_models_wallet_py_model_auth_wallet_local_dependency_on_the_introspect_contract_user_directive_2026_09_30_resolve_the_raw_token_x_access_token_authorization_bearer_mansa_token_cookie_order_per_main_app_authentication_util_py_54_66_introspecttoken_db_raw_main_app_authentication_introspect_py_14_userid_username_roles_roles_checkaccess_roles_permission_wallet_main_utils_roles_py_29_39_403_if_absent_depends_getsession_for_the_db_session" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/9f3b339dde20_drop_unused_user_sessions_columns.py", - "source_location": "L1", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L66", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_9f3b339dde20_drop_unused_user_sessions_columns_py", - "target": "versions_9f3b339dde20_drop_unused_user_sessions_columns_rationale_1" + "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", + "target": "superpowers_investidor10_wallet_spec_4_phased_build_plan_writing_plans_each_phase_independently_reviewable_reviewer_pass_per_phase" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/9f3b339dde20_drop_unused_user_sessions_columns.py", - "source_location": "L44", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L72", "weight": 1.0, "confidence_score": 1.0, - "source": "versions_9f3b339dde20_drop_unused_user_sessions_columns_upgrade", - "target": "versions_9f3b339dde20_drop_unused_user_sessions_columns_rationale_44" + "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", + "target": "superpowers_investidor10_wallet_spec_5_risks_assumptions_honest_flags_carried_over_do_not_treat_as_fact" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/9f3b339dde20_drop_unused_user_sessions_columns.py", - "source_location": "L51", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L81", "weight": 1.0, "confidence_score": 1.0, - "source": "versions_9f3b339dde20_drop_unused_user_sessions_columns_downgrade", - "target": "versions_9f3b339dde20_drop_unused_user_sessions_columns_rationale_51" + "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", + "target": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/add_access_token_hash.py", - "source_location": "L21", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L121", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_add_access_token_hash_py", - "target": "versions_add_access_token_hash_upgrade" + "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", + "target": "superpowers_investidor10_wallet_spec_7_independent_re_verification_swarm_s4_2026_09_29_corrections_to_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/add_access_token_hash.py", - "source_location": "L54", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L49", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_add_access_token_hash_py", - "target": "versions_add_access_token_hash_downgrade" + "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", + "target": "superpowers_investidor10_wallet_spec_3_api_contracts_all_under_wallet_chain_main_controller_wallet_controller_py_main_service_wallet_service_py_fn_main_models_wallet_py_model_auth_depends_usermanager_getcurrentuser_depends_getsession_throughout" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/add_access_token_hash.py", - "source_location": "L1", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L49", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_add_access_token_hash_py", - "target": "versions_add_access_token_hash_rationale_1" + "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", + "target": "superpowers_investidor10_wallet_spec_3_api_contracts_all_under_api_wallet_chain_main_controller_wallet_controller_py_main_service_wallet_service_py_fn_main_models_wallet_py_model_auth_depends_usermanager_getcurrentuser_depends_getsession_throughout" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/add_access_token_hash.py", - "source_location": "L22", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L14", "weight": 1.0, "confidence_score": 1.0, - "source": "versions_add_access_token_hash_upgrade", - "target": "versions_add_access_token_hash_rationale_22" + "source": "superpowers_investidor10_wallet_spec_1_requirements", + "target": "superpowers_investidor10_wallet_spec_1_1_functional_per_surface_tags_exists_build_on_it_partial_half_reusable_missing_greenfield" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/add_access_token_hash.py", - "source_location": "L55", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L28", "weight": 1.0, "confidence_score": 1.0, - "source": "versions_add_access_token_hash_downgrade", - "target": "versions_add_access_token_hash_rationale_55" + "source": "superpowers_investidor10_wallet_spec_1_requirements", + "target": "superpowers_investidor10_wallet_spec_1_2_non_functional" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/b1c2d3e4f5a6_create_prometheus_memories.py", - "source_location": "L22", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L87", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_b1c2d3e4f5a6_create_prometheus_memories_py", - "target": "versions_b1c2d3e4f5a6_create_prometheus_memories_upgrade" + "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", + "target": "superpowers_investidor10_wallet_spec_6_1_db_migrations_user_db_contested_7_1_3_actions_incl_one_destructive_autogenerate_risk" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/b1c2d3e4f5a6_create_prometheus_memories.py", - "source_location": "L50", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L94", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_b1c2d3e4f5a6_create_prometheus_memories_py", - "target": "versions_b1c2d3e4f5a6_create_prometheus_memories_downgrade" + "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", + "target": "superpowers_investidor10_wallet_spec_6_2_stocks_price_access_confirmed_extended_7_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/b1c2d3e4f5a6_create_prometheus_memories.py", - "source_location": "L60", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L100", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_b1c2d3e4f5a6_create_prometheus_memories_py", - "target": "versions_b1c2d3e4f5a6_create_prometheus_memories_fix_partial" + "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", + "target": "superpowers_investidor10_wallet_spec_6_3_wiring_auth_tests_contested_7_3_mounting_true_gating_test_seams_missing" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/b1c2d3e4f5a6_create_prometheus_memories.py", - "source_location": "L1", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L115", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_b1c2d3e4f5a6_create_prometheus_memories_py", - "target": "versions_b1c2d3e4f5a6_create_prometheus_memories_rationale_1" + "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", + "target": "superpowers_investidor10_wallet_spec_6_4_scraper_pipeline_p2_dividends_contested_7_4_data_present_source_staleness_gaps" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/c2e4f6a8b0c1_drop_embedding_model_version.py", - "source_location": "L22", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L110", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_c2e4f6a8b0c1_drop_embedding_model_version_py", - "target": "versions_c2e4f6a8b0c1_drop_embedding_model_version_upgrade" + "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", + "target": "superpowers_investidor10_wallet_spec_6_5_ordered_actions_before_p1_code" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/c2e4f6a8b0c1_drop_embedding_model_version.py", - "source_location": "L27", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L106", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_c2e4f6a8b0c1_drop_embedding_model_version_py", - "target": "versions_c2e4f6a8b0c1_drop_embedding_model_version_downgrade" + "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", + "target": "superpowers_investidor10_wallet_spec_6_4_scraper_pipeline_p2_dividends_has_b3_contested_7_4_data_present_source_staleness_gaps" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/c2e4f6a8b0c1_drop_embedding_model_version.py", - "source_location": "L1", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L85", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_c2e4f6a8b0c1_drop_embedding_model_version_py", - "target": "versions_c2e4f6a8b0c1_drop_embedding_model_version_rationale_1" + "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", + "target": "superpowers_investidor10_wallet_spec_6_1_db_migrations_user_db_ready_2_actions" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/d3df3fc5ca72_rename_memory_base_score.py", - "source_location": "L17", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L92", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_d3df3fc5ca72_rename_memory_base_score_py", - "target": "versions_d3df3fc5ca72_rename_memory_base_score_upgrade" + "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", + "target": "superpowers_investidor10_wallet_spec_6_2_stocks_price_access_ready_for_full_series_one_new_helper_needed" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/d3df3fc5ca72_rename_memory_base_score.py", - "source_location": "L21", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L98", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_d3df3fc5ca72_rename_memory_base_score_py", - "target": "versions_d3df3fc5ca72_rename_memory_base_score_downgrade" + "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", + "target": "superpowers_investidor10_wallet_spec_6_3_wiring_auth_tests_ready" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/d3e4f5a6b7c8_add_prometheus_sandboxes.py", - "source_location": "L22", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L104", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_d3e4f5a6b7c8_add_prometheus_sandboxes_py", - "target": "versions_d3e4f5a6b7c8_add_prometheus_sandboxes_upgrade" + "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", + "target": "superpowers_investidor10_wallet_spec_6_4_scraper_pipeline_p2_dividends_has_b3_ready_public_sources_only" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/d3e4f5a6b7c8_add_prometheus_sandboxes.py", - "source_location": "L36", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L125", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_d3e4f5a6b7c8_add_prometheus_sandboxes_py", - "target": "versions_d3e4f5a6b7c8_add_prometheus_sandboxes_downgrade" + "source": "superpowers_investidor10_wallet_spec_7_independent_re_verification_swarm_s4_2026_09_29_corrections_to_6", + "target": "superpowers_investidor10_wallet_spec_7_1_db_migrations_6_1_contested_3_actions_one_destructive_risk" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/d3e4f5a6b7c8_add_prometheus_sandboxes.py", - "source_location": "L1", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L133", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_d3e4f5a6b7c8_add_prometheus_sandboxes_py", - "target": "versions_d3e4f5a6b7c8_add_prometheus_sandboxes_rationale_1" + "source": "superpowers_investidor10_wallet_spec_7_independent_re_verification_swarm_s4_2026_09_29_corrections_to_6", + "target": "superpowers_investidor10_wallet_spec_7_2_stocks_price_access_6_2_confirmed_incomplete" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories.py", - "source_location": "L21", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L143", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories_py", - "target": "versions_e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories_upgrade" + "source": "superpowers_investidor10_wallet_spec_7_independent_re_verification_swarm_s4_2026_09_29_corrections_to_6", + "target": "superpowers_investidor10_wallet_spec_7_3_wiring_auth_tests_6_3_contested_mounting_true" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories.py", - "source_location": "L45", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L150", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories_py", - "target": "versions_e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories_downgrade" + "source": "superpowers_investidor10_wallet_spec_7_independent_re_verification_swarm_s4_2026_09_29_corrections_to_6", + "target": "superpowers_investidor10_wallet_spec_7_4_scraper_pipeline_6_4_contested" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories.py", - "source_location": "L1", + "source_file": "docs/superpowers/investidor10-wallet-spec.md", + "source_location": "L159", "weight": 1.0, "confidence_score": 1.0, - "source": "versions_e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories_rationale_1", - "target": "migrations_versions_e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories_py" + "source": "superpowers_investidor10_wallet_spec_7_independent_re_verification_swarm_s4_2026_09_29_corrections_to_6", + "target": "superpowers_investidor10_wallet_spec_7_5_revised_pre_p1_actions_supersedes_6_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes.py", - "source_location": "L22", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes_py", - "target": "versions_e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes_upgrade" + "source": "docs_superpowers_nginx_scaling_plan_md", + "target": "superpowers_nginx_scaling_plan_nginx_scaling_plan_reverse_proxy_response_cache_for_stocks_and_the_multi_server_evolution" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes.py", - "source_location": "L26", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L64", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes_py", - "target": "versions_e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes_downgrade" + "source": "docs_superpowers_nginx_scaling_plan_md", + "target": "superpowers_nginx_scaling_plan_part_1_implementation_plan" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes.py", - "source_location": "L1", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L347", "weight": 1.0, "confidence_score": 1.0, - "source": "versions_e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes_rationale_1", - "target": "migrations_versions_e5f6a7b8c9d0_drop_workspace_path_prometheus_sandboxes_py" + "source": "docs_superpowers_nginx_scaling_plan_md", + "target": "superpowers_nginx_scaling_plan_part_2_benchmark_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/f1a2b3c4d5e6_session_gc_index.py", - "source_location": "L26", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L510", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_f1a2b3c4d5e6_session_gc_index_py", - "target": "versions_f1a2b3c4d5e6_session_gc_index_upgrade" + "source": "docs_superpowers_nginx_scaling_plan_md", + "target": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/f1a2b3c4d5e6_session_gc_index.py", - "source_location": "L34", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L661", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_f1a2b3c4d5e6_session_gc_index_py", - "target": "versions_f1a2b3c4d5e6_session_gc_index_downgrade" + "source": "docs_superpowers_nginx_scaling_plan_md", + "target": "superpowers_nginx_scaling_plan_open_decisions_blocking_or_product_owned" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/f1a2b3c4d5e6_session_gc_index.py", - "source_location": "L1", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L669", "weight": 1.0, "confidence_score": 1.0, - "source": "versions_f1a2b3c4d5e6_session_gc_index_rationale_1", - "target": "migrations_versions_f1a2b3c4d5e6_session_gc_index_py" + "source": "docs_superpowers_nginx_scaling_plan_md", + "target": "superpowers_nginx_scaling_plan_next_actions_not_in_scope_here" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/f7a8b9c0d1e2_rename_prometheus_to_orunmila.py", - "source_location": "L25", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L17", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_f7a8b9c0d1e2_rename_prometheus_to_orunmila_py", - "target": "versions_f7a8b9c0d1e2_rename_prometheus_to_orunmila_upgrade" + "source": "superpowers_nginx_scaling_plan_nginx_scaling_plan_reverse_proxy_response_cache_for_stocks_and_the_multi_server_evolution", + "target": "superpowers_nginx_scaling_plan_0_purpose_and_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/f7a8b9c0d1e2_rename_prometheus_to_orunmila.py", - "source_location": "L43", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L35", "weight": 1.0, "confidence_score": 1.0, - "source": "migrations_versions_f7a8b9c0d1e2_rename_prometheus_to_orunmila_py", - "target": "versions_f7a8b9c0d1e2_rename_prometheus_to_orunmila_downgrade" + "source": "superpowers_nginx_scaling_plan_nginx_scaling_plan_reverse_proxy_response_cache_for_stocks_and_the_multi_server_evolution", + "target": "superpowers_nginx_scaling_plan_0_1_rev_2_do_first_app_cache_ttl_increase_fields_cache_no_nginx_no_redis" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "migrations/versions/f7a8b9c0d1e2_rename_prometheus_to_orunmila.py", - "source_location": "L1", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L66", "weight": 1.0, "confidence_score": 1.0, - "source": "versions_f7a8b9c0d1e2_rename_prometheus_to_orunmila_rationale_1", - "target": "migrations_versions_f7a8b9c0d1e2_rename_prometheus_to_orunmila_py" + "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", + "target": "superpowers_nginx_scaling_plan_1_1_architecture_decision" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L1", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L79", "weight": 1.0, "confidence_score": 1.0, - "source": "agents_md", - "target": "server_agents_project_overview" + "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", + "target": "superpowers_nginx_scaling_plan_1_2_file_layout" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L4", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L96", "weight": 1.0, "confidence_score": 1.0, - "source": "agents_md", - "target": "server_agents_dev_commands" + "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", + "target": "superpowers_nginx_scaling_plan_1_3_phase_p0_nginx_service_config_skeleton" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L23", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L152", "weight": 1.0, "confidence_score": 1.0, - "source": "agents_md", - "target": "server_agents_architecture" + "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", + "target": "superpowers_nginx_scaling_plan_1_4_phase_p1_cache_locations_ttl_table_directives" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L47", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L251", "weight": 1.0, "confidence_score": 1.0, - "source": "agents_md", - "target": "server_agents_code_style" + "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", + "target": "superpowers_nginx_scaling_plan_1_5_phase_p2_port_scheme_worker_containers_keepalive" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L34", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L277", "weight": 1.0, "confidence_score": 1.0, - "source": "agents_md", - "target": "server_agents_testing" + "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", + "target": "superpowers_nginx_scaling_plan_1_6_phase_p3_remote_vps_upstreams_health_strategy" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L38", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L309", "weight": 1.0, "confidence_score": 1.0, - "source": "agents_md", - "target": "server_agents_graphify" + "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", + "target": "superpowers_nginx_scaling_plan_1_7_phase_p4_handoff_design_no_code_in_this_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L60", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L320", "weight": 1.0, "confidence_score": 1.0, - "source": "agents_md", - "target": "server_agents_swarm_delegation_default" + "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", + "target": "superpowers_nginx_scaling_plan_1_8_quota_rate_limit_semantics_after_caching" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L47", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L332", "weight": 1.0, "confidence_score": 1.0, - "source": "agents_md", - "target": "server_agents_stocks_api_pandas_first_pattern" + "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", + "target": "superpowers_nginx_scaling_plan_1_9_anti_scraping_note_todo_17" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L54", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L336", "weight": 1.0, "confidence_score": 1.0, - "source": "agents_md", - "target": "server_agents_scraper_b3_xango_batch_data_pipeline" + "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", + "target": "superpowers_nginx_scaling_plan_1_10_edge_cases_risks_implementation" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L60", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L82", "weight": 1.0, "confidence_score": 1.0, - "source": "agents_md", - "target": "server_agents_auth_users_dual_layer_session_security" + "source": "superpowers_nginx_scaling_plan_1_2_file_layout", + "target": "superpowers_nginx_scaling_plan_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L28", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L98", "weight": 1.0, "confidence_score": 1.0, - "source": "agents_md", - "target": "server_agents_key_quirks" + "source": "superpowers_nginx_scaling_plan_1_3_phase_p0_nginx_service_config_skeleton", + "target": "superpowers_nginx_scaling_plan_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L57", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L118", "weight": 1.0, "confidence_score": 1.0, - "source": "agents_md", - "target": "server_agents_prometheus_ai_chat_strengths_gaps" + "source": "superpowers_nginx_scaling_plan_1_3_phase_p0_nginx_service_config_skeleton", + "target": "superpowers_nginx_scaling_plan_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L5", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L139", "weight": 1.0, "confidence_score": 1.0, - "source": "server_agents_dev_commands", - "target": "server_agents_codeblock_1" + "source": "superpowers_nginx_scaling_plan_1_3_phase_p0_nginx_service_config_skeleton", + "target": "superpowers_nginx_scaling_plan_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "AGENTS.md", - "source_location": "L31", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L155", "weight": 1.0, "confidence_score": 1.0, - "source": "server_agents_dev_commands", - "target": "server_agents_ci_pipeline_order" + "source": "superpowers_nginx_scaling_plan_1_4_phase_p1_cache_locations_ttl_table_directives", + "target": "superpowers_nginx_scaling_plan_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "README.md", - "source_location": "L1", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L186", "weight": 1.0, "confidence_score": 1.0, - "source": "readme_md", - "target": "server_readme_mansa_server" + "source": "superpowers_nginx_scaling_plan_1_4_phase_p1_cache_locations_ttl_table_directives", + "target": "superpowers_nginx_scaling_plan_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "README.md", - "source_location": "L7", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L242", "weight": 1.0, "confidence_score": 1.0, - "source": "server_readme_mansa_server", - "target": "server_readme_run_with_docker" + "source": "superpowers_nginx_scaling_plan_1_4_phase_p1_cache_locations_ttl_table_directives", + "target": "superpowers_nginx_scaling_plan_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "README.md", - "source_location": "L20", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L257", "weight": 1.0, "confidence_score": 1.0, - "source": "server_readme_mansa_server", - "target": "server_readme_environment_setup" + "source": "superpowers_nginx_scaling_plan_1_5_phase_p2_port_scheme_worker_containers_keepalive", + "target": "superpowers_nginx_scaling_plan_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "README.md", - "source_location": "L85", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L279", "weight": 1.0, "confidence_score": 1.0, - "source": "server_readme_mansa_server", - "target": "server_readme_health_check" + "source": "superpowers_nginx_scaling_plan_1_6_phase_p3_remote_vps_upstreams_health_strategy", + "target": "superpowers_nginx_scaling_plan_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "README.md", - "source_location": "L91", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L291", "weight": 1.0, "confidence_score": 1.0, - "source": "server_readme_mansa_server", - "target": "server_readme_license" + "source": "superpowers_nginx_scaling_plan_1_6_phase_p3_remote_vps_upstreams_health_strategy", + "target": "superpowers_nginx_scaling_plan_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "README.md", - "source_location": "L9", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L349", "weight": 1.0, "confidence_score": 1.0, - "source": "server_readme_run_with_docker", - "target": "server_readme_codeblock_1" + "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", + "target": "superpowers_nginx_scaling_plan_2_0_grounding_what_the_code_actually_does" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "README.md", - "source_location": "L24", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L381", "weight": 1.0, "confidence_score": 1.0, - "source": "server_readme_environment_setup", - "target": "server_readme_codeblock_2" + "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", + "target": "superpowers_nginx_scaling_plan_2_1_hypotheses" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "README.md", - "source_location": "L87", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L390", "weight": 1.0, "confidence_score": 1.0, - "source": "server_readme_health_check", - "target": "server_readme_codeblock_3" + "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", + "target": "superpowers_nginx_scaling_plan_2_2_tooling" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "TODO.md", - "source_location": "L25", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L440", "weight": 1.0, "confidence_score": 1.0, - "source": "todo_md", - "target": "server_todo_user_structure_defined_by_string_roles" + "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", + "target": "superpowers_nginx_scaling_plan_2_3_scenarios" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "TODO.md", - "source_location": "L1", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L452", "weight": 1.0, "confidence_score": 1.0, - "source": "todo_md", - "target": "server_todo_priorities_active_order_2026_09_29" + "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", + "target": "superpowers_nginx_scaling_plan_2_4_protocol" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "TODO.md", - "source_location": "L34", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L463", "weight": 1.0, "confidence_score": 1.0, - "source": "server_todo_user_structure_defined_by_string_roles", - "target": "server_todo_user" + "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", + "target": "superpowers_nginx_scaling_plan_2_5_metrics" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "TODO.md", - "source_location": "L37", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L467", "weight": 1.0, "confidence_score": 1.0, - "source": "server_todo_user_structure_defined_by_string_roles", - "target": "server_todo_premium" + "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", + "target": "superpowers_nginx_scaling_plan_2_6_acceptance_thresholds_all_proposed_freeze_after_first_real_run" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "TODO.md", - "source_location": "L40", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L484", "weight": 1.0, "confidence_score": 1.0, - "source": "server_todo_user_structure_defined_by_string_roles", - "target": "server_todo_developer" + "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", + "target": "superpowers_nginx_scaling_plan_2_7_results_doc_layout" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "TODO.md", - "source_location": "L67", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L493", "weight": 1.0, "confidence_score": 1.0, - "source": "server_todo_user_structure_defined_by_string_roles", - "target": "server_todo_stocks_api" + "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", + "target": "superpowers_nginx_scaling_plan_2_8_feeding_status_todo_14" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "TODO.md", - "source_location": "L70", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L499", "weight": 1.0, "confidence_score": 1.0, - "source": "server_todo_user_structure_defined_by_string_roles", - "target": "server_todo_prometheus" + "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", + "target": "superpowers_nginx_scaling_plan_2_9_benchmark_risks" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L1", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L393", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_md", - "target": "docs_authentication_authentication_management" + "source": "superpowers_nginx_scaling_plan_2_2_tooling", + "target": "superpowers_nginx_scaling_plan_codeblock_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L5", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L406", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_token_session_lifetime" + "source": "superpowers_nginx_scaling_plan_2_2_tooling", + "target": "superpowers_nginx_scaling_plan_codeblock_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L11", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L414", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_token_extraction_order" + "source": "superpowers_nginx_scaling_plan_2_2_tooling", + "target": "superpowers_nginx_scaling_plan_codeblock_13" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L21", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L420", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_cookie_handling_conditional_secure" + "source": "superpowers_nginx_scaling_plan_2_2_tooling", + "target": "superpowers_nginx_scaling_plan_codeblock_14" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L30", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L431", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_session_data_model_family_only" + "source": "superpowers_nginx_scaling_plan_2_2_tooling", + "target": "superpowers_nginx_scaling_plan_codeblock_15" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L39", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L486", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_roles_and_permissions" + "source": "superpowers_nginx_scaling_plan_2_7_results_doc_layout", + "target": "superpowers_nginx_scaling_plan_codeblock_16" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L61", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L512", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_rate_limits" + "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", + "target": "superpowers_nginx_scaling_plan_3_0_verified_ground_truth" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L49", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L529", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_api_endpoints" + "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", + "target": "superpowers_nginx_scaling_plan_3_1_target_topology" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L117", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L546", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_security_features" + "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", + "target": "superpowers_nginx_scaling_plan_3_2_worker_container_extraction" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L138", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L563", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_not_implemented" + "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", + "target": "superpowers_nginx_scaling_plan_3_3_nginx_upstream_evolution_validated_against_the_user_s_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L154", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L584", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_workflow" + "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", + "target": "superpowers_nginx_scaling_plan_3_4_todo_13_migration_drop_service_host_service_port" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L187", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L591", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_license" + "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", + "target": "superpowers_nginx_scaling_plan_3_5_redis_exactly_two_jobs" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L9", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L607", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_usage" + "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", + "target": "superpowers_nginx_scaling_plan_3_6_cache_strategy_across_boxes" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L130", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L613", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_device_detection" + "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", + "target": "superpowers_nginx_scaling_plan_3_7_autoscaling_story_todo_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L144", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L618", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_authentication_management", - "target": "docs_authentication_session_management" + "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", + "target": "superpowers_nginx_scaling_plan_3_8_forgevm_interplay_todo_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L51", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L622", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_api_endpoints", - "target": "docs_authentication_health_check" + "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", + "target": "superpowers_nginx_scaling_plan_3_9_risk_register" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L57", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L642", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_api_endpoints", - "target": "docs_authentication_user_registration" + "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", + "target": "superpowers_nginx_scaling_plan_3_10_migration_sequence_verification" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L65", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L534", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_api_endpoints", - "target": "docs_authentication_user_login" + "source": "superpowers_nginx_scaling_plan_3_1_target_topology", + "target": "superpowers_nginx_scaling_plan_codeblock_17" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L84", + "source_file": "docs/superpowers/nginx-scaling-plan.md", + "source_location": "L567", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_api_endpoints", - "target": "docs_authentication_logout" + "source": "superpowers_nginx_scaling_plan_3_3_nginx_upstream_evolution_validated_against_the_user_s_plan", + "target": "superpowers_nginx_scaling_plan_codeblock_18" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L94", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_api_endpoints", - "target": "docs_authentication_google_oauth2_login" + "source": "docs_superpowers_orunmila_harness_gaps_md", + "target": "superpowers_orunmila_harness_gaps_orunmila_harness_loop_gap_analysis" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L120", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L5", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_api_endpoints", - "target": "docs_authentication_google_callback_cookie_only" + "source": "superpowers_orunmila_harness_gaps_orunmila_harness_loop_gap_analysis", + "target": "superpowers_orunmila_harness_gaps_1_orunmila_s_loop_today" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L77", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L9", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_api_endpoints", - "target": "docs_authentication_profile_me" + "source": "superpowers_orunmila_harness_gaps_orunmila_harness_loop_gap_analysis", + "target": "superpowers_orunmila_harness_gaps_2_where_orunmila_is_already_ahead_do_not_rebuild" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L108", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L16", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_api_endpoints", - "target": "docs_authentication_google_callback" + "source": "superpowers_orunmila_harness_gaps_orunmila_harness_loop_gap_analysis", + "target": "superpowers_orunmila_harness_gaps_3_the_12_modern_patterns_vs_orunmila" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L76", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L33", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_health_check", - "target": "docs_authentication_codeblock_1" + "source": "superpowers_orunmila_harness_gaps_orunmila_harness_loop_gap_analysis", + "target": "superpowers_orunmila_harness_gaps_4_p0_reliability_do_first_each_one_pr" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L52", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L39", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_health_check", - "target": "docs_authentication_codeblock_2" + "source": "superpowers_orunmila_harness_gaps_orunmila_harness_loop_gap_analysis", + "target": "superpowers_orunmila_harness_gaps_5_p1_context_quality_biggest_behavior_delta_per_line" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L11", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L47", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_usage", - "target": "docs_authentication_codeblock_1" + "source": "superpowers_orunmila_harness_gaps_orunmila_harness_loop_gap_analysis", + "target": "superpowers_orunmila_harness_gaps_6_p2_structural_larger_sequenced_after_p0_p1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L84", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L54", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_user_registration", - "target": "docs_authentication_codeblock_2" + "source": "superpowers_orunmila_harness_gaps_orunmila_harness_loop_gap_analysis", + "target": "superpowers_orunmila_harness_gaps_7_p3_later_deliberate_scope_not_accidents" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L59", + "source_file": "docs/superpowers/orunmila-harness-gaps.md", + "source_location": "L60", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_user_registration", - "target": "docs_authentication_codeblock_3" + "source": "superpowers_orunmila_harness_gaps_orunmila_harness_loop_gap_analysis", + "target": "superpowers_orunmila_harness_gaps_8_sources" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L94", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_user_login", - "target": "docs_authentication_codeblock_3" + "source": "docs_superpowers_uvicorn_worker_scaling_plan_md", + "target": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L67", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_user_login", - "target": "docs_authentication_codeblock_4" + "source": "docs_superpowers_uvicorn_worker_scaling_plan_md", + "target": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_scaling_verified_state_and_evaluated_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L104", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_logout", - "target": "docs_authentication_codeblock_4" + "source": "docs_superpowers_uvicorn_worker_scaling_plan_md", + "target": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_scaling_verified_state_evaluated_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L86", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L17", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_logout", - "target": "docs_authentication_codeblock_6" + "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", + "target": "superpowers_uvicorn_worker_scaling_plan_0_the_blockers_ranked" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L113", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L32", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_google_oauth2_login", - "target": "docs_authentication_codeblock_5" + "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", + "target": "superpowers_uvicorn_worker_scaling_plan_1_verified_state_compact" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L98", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L52", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_google_oauth2_login", - "target": "docs_authentication_codeblock_7" + "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", + "target": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L104", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L135", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_google_oauth2_login", - "target": "docs_authentication_codeblock_8" + "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", + "target": "superpowers_uvicorn_worker_scaling_plan_3_rulings_conflicts_i_adjudicated" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L79", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L147", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_profile_me", - "target": "docs_authentication_codeblock_5" + "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", + "target": "superpowers_uvicorn_worker_scaling_plan_4_design_spec_alignment_2026_09_29_nginx_scaling_design_md" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L144", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L162", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_workflow", - "target": "docs_authentication_codeblock_6" + "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", + "target": "superpowers_uvicorn_worker_scaling_plan_5_sequencing_verification_and_bans" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/authentication.md", - "source_location": "L156", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L174", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_authentication_workflow", - "target": "docs_authentication_codeblock_9" + "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", + "target": "superpowers_uvicorn_worker_scaling_plan_6_options_demoted" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/orunmila.md", - "source_location": "L1", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L186", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_orunmila_md", - "target": "docs_orunmila_orunmila" + "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", + "target": "superpowers_uvicorn_worker_scaling_plan_7_risks" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/orunmila.md", - "source_location": "L7", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L200", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_orunmila_orunmila", - "target": "docs_orunmila_usage" + "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", + "target": "superpowers_uvicorn_worker_scaling_plan_8_evidence_index" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/orunmila.md", - "source_location": "L53", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L54", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_orunmila_orunmila", - "target": "docs_orunmila_workflow" + "source": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine", + "target": "superpowers_uvicorn_worker_scaling_plan_b1_\u00e2_startup_and_process_model_must_fix" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/orunmila.md", - "source_location": "L65", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L67", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_orunmila_orunmila", - "target": "docs_orunmila_api_endpoints" + "source": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine", + "target": "superpowers_uvicorn_worker_scaling_plan_b2_\u00e2_cache_under_n_1_must_fix" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/orunmila.md", - "source_location": "L72", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L79", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_orunmila_orunmila", - "target": "docs_orunmila_license" + "source": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine", + "target": "superpowers_uvicorn_worker_scaling_plan_b3_\u00e2_db_pools_must_fix_at_n\u00e2_3_on_one_server" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/orunmila.md", - "source_location": "L9", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L98", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_orunmila_usage", - "target": "docs_orunmila_codeblock_1" + "source": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine", + "target": "superpowers_uvicorn_worker_scaling_plan_b4_\u00e2_migrations_must_fix" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/orunmila.md", - "source_location": "L49", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L107", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_orunmila_usage", - "target": "docs_orunmila_codeblock_2" + "source": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine", + "target": "superpowers_uvicorn_worker_scaling_plan_b5_\u00e2_per_process_state_ranked_scope_by_service" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/orunmila.md", - "source_location": "L55", + "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", + "source_location": "L123", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_orunmila_workflow", - "target": "docs_orunmila_codeblock_3" + "source": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine", + "target": "superpowers_uvicorn_worker_scaling_plan_b6_\u00e2_deployment_glue_must_build" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/scraper_b3.md", + "source_file": "docs/superpowers/wallet-orchestrator-prompt.md", "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_scraper_b3_md", - "target": "docs_scraper_b3_b3_market_scraper" + "source": "docs_superpowers_wallet_orchestrator_prompt_md", + "target": "superpowers_wallet_orchestrator_prompt_wallet_orchestrator_prompt_p1_p2_p3_one_goal_per_scope" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/scraper_b3.md", - "source_location": "L1", + "source_file": "docs/superpowers/wallet-orchestrator-prompt.md", + "source_location": "L10", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_scraper_b3_md", - "target": "docs_scraper_b3_brazilian_stocks_market_scraper" + "source": "superpowers_wallet_orchestrator_prompt_wallet_orchestrator_prompt_p1_p2_p3_one_goal_per_scope", + "target": "superpowers_wallet_orchestrator_prompt_the_three_goals_sequential_one_at_a_time_never_parallel" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/scraper_b3.md", - "source_location": "L5", + "source_file": "docs/superpowers/wallet-orchestrator-prompt.md", + "source_location": "L30", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_scraper_b3_b3_market_scraper", - "target": "docs_scraper_b3_sources_6" + "source": "superpowers_wallet_orchestrator_prompt_wallet_orchestrator_prompt_p1_p2_p3_one_goal_per_scope", + "target": "superpowers_wallet_orchestrator_prompt_swarm_protocol_all_three_goals" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/scraper_b3.md", - "source_location": "L19", + "source_file": "docs/superpowers/wallet-orchestrator-prompt.md", + "source_location": "L40", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_scraper_b3_b3_market_scraper", - "target": "docs_scraper_b3_scheduling_config_config_py_77_81_scraper_service_py_23_36" + "source": "superpowers_wallet_orchestrator_prompt_wallet_orchestrator_prompt_p1_p2_p3_one_goal_per_scope", + "target": "superpowers_wallet_orchestrator_prompt_standing_rules_do_not_re_derive" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/scraper_b3.md", - "source_location": "L31", + "source_file": "docs/superpowers/wallet-orchestrator-prompt.md", + "source_location": "L78", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_scraper_b3_b3_market_scraper", - "target": "docs_scraper_b3_xango_score_main_app_scraper_b3_xango_py" + "source": "superpowers_wallet_orchestrator_prompt_wallet_orchestrator_prompt_p1_p2_p3_one_goal_per_scope", + "target": "superpowers_wallet_orchestrator_prompt_environment" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/scraper_b3.md", - "source_location": "L41", + "source_file": "docs/superpowers/benchmarks/stocks-cache-ttl.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_scraper_b3_b3_market_scraper", - "target": "docs_scraper_b3_outputs" + "source": "docs_superpowers_benchmarks_stocks_cache_ttl_md", + "target": "benchmarks_stocks_cache_ttl_stocks_endpoint_cache_ttl_6h_rss_check" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/scraper_b3.md", - "source_location": "L21", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_scraper_b3_scheduling_config_config_py_77_81_scraper_service_py_23_36", - "target": "docs_scraper_b3_codeblock_1" + "source": "docs_superpowers_plans_2026_08_09_sse_resume_md", + "target": "plans_2026_08_09_sse_resume_sse_resume_implementation_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/scraper_b3.md", - "source_location": "L8", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L11", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_scraper_b3_usage", - "target": "docs_scraper_b3_codeblock_1" + "source": "plans_2026_08_09_sse_resume_sse_resume_implementation_plan", + "target": "plans_2026_08_09_sse_resume_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L26", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_md", - "target": "docs_stocks_api_brazilian_stocks_market_api" + "source": "plans_2026_08_09_sse_resume_global_constraints", + "target": "plans_2026_08_09_sse_resume_task_1_streambus_module_with_unit_tests" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L7", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L242", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_brazilian_stocks_market_api", - "target": "docs_stocks_api_usage" + "source": "plans_2026_08_09_sse_resume_global_constraints", + "target": "plans_2026_08_09_sse_resume_task_2_background_run_get_resume_route_in_prometheus_controller" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L22", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L412", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_brazilian_stocks_market_api", - "target": "docs_stocks_api_auth" + "source": "plans_2026_08_09_sse_resume_global_constraints", + "target": "plans_2026_08_09_sse_resume_task_3_frontend_api_js_shared_sse_parser_resumechat_cursor_tracking" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L32", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L576", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_brazilian_stocks_market_api", - "target": "docs_stocks_api_api_endpoints" + "source": "plans_2026_08_09_sse_resume_global_constraints", + "target": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L90", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L863", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_brazilian_stocks_market_api", - "target": "docs_stocks_api_response_format" + "source": "plans_2026_08_09_sse_resume_global_constraints", + "target": "plans_2026_08_09_sse_resume_task_5_full_verification_todo_check_off" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L119", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L41", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_brazilian_stocks_market_api", - "target": "docs_stocks_api_architecture" + "source": "plans_2026_08_09_sse_resume_task_1_streambus_module_with_unit_tests", + "target": "plans_2026_08_09_sse_resume_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L113", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L130", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_brazilian_stocks_market_api", - "target": "docs_stocks_api_license" + "source": "plans_2026_08_09_sse_resume_task_1_streambus_module_with_unit_tests", + "target": "plans_2026_08_09_sse_resume_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L9", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L235", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_usage", - "target": "docs_stocks_api_codeblock_1" + "source": "plans_2026_08_09_sse_resume_task_1_streambus_module_with_unit_tests", + "target": "plans_2026_08_09_sse_resume_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L34", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L257", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_api_endpoints", - "target": "docs_stocks_api_health_check" + "source": "plans_2026_08_09_sse_resume_task_2_background_run_get_resume_route_in_prometheus_controller", + "target": "plans_2026_08_09_sse_resume_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L40", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L329", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_api_endpoints", - "target": "docs_stocks_api_field_discovery" + "source": "plans_2026_08_09_sse_resume_task_2_background_run_get_resume_route_in_prometheus_controller", + "target": "plans_2026_08_09_sse_resume_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L53", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L405", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_api_endpoints", - "target": "docs_stocks_api_historical_data" + "source": "plans_2026_08_09_sse_resume_task_2_background_run_get_resume_route_in_prometheus_controller", + "target": "plans_2026_08_09_sse_resume_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L72", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L426", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_api_endpoints", - "target": "docs_stocks_api_fundamental_data" + "source": "plans_2026_08_09_sse_resume_task_3_frontend_api_js_shared_sse_parser_resumechat_cursor_tracking", + "target": "plans_2026_08_09_sse_resume_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L74", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L498", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_api_endpoints", - "target": "docs_stocks_api_cotations_10_year_daily_history" + "source": "plans_2026_08_09_sse_resume_task_3_frontend_api_js_shared_sse_parser_resumechat_cursor_tracking", + "target": "plans_2026_08_09_sse_resume_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L87", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L569", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_api_endpoints", - "target": "docs_stocks_api_live_price" + "source": "plans_2026_08_09_sse_resume_task_3_frontend_api_js_shared_sse_parser_resumechat_cursor_tracking", + "target": "plans_2026_08_09_sse_resume_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L98", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L590", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_api_endpoints", - "target": "docs_stocks_api_mcp_ai_agent_tools" + "source": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume", + "target": "plans_2026_08_09_sse_resume_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L40", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L659", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_api_endpoints", - "target": "docs_stocks_api_api_key_verification" + "source": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume", + "target": "plans_2026_08_09_sse_resume_codeblock_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L45", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L681", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_api_endpoints", - "target": "docs_stocks_api_key_management" + "source": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume", + "target": "plans_2026_08_09_sse_resume_codeblock_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L35", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L768", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_health_check", - "target": "docs_stocks_api_codeblock_2" + "source": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume", + "target": "plans_2026_08_09_sse_resume_codeblock_13" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L42", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L835", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_field_discovery", - "target": "docs_stocks_api_codeblock_3" + "source": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume", + "target": "plans_2026_08_09_sse_resume_codeblock_14" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L41", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L856", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_api_key_verification", - "target": "docs_stocks_api_codeblock_3" + "source": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume", + "target": "plans_2026_08_09_sse_resume_codeblock_15" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L50", + "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", + "source_location": "L889", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_historical_data", - "target": "docs_stocks_api_codeblock_4" + "source": "plans_2026_08_09_sse_resume_task_5_full_verification_todo_check_off", + "target": "plans_2026_08_09_sse_resume_codeblock_16" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L55", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_historical_data", - "target": "docs_stocks_api_codeblock_5" + "source": "docs_superpowers_plans_2026_08_15_stocks_api_perf_md", + "target": "plans_2026_08_15_stocks_api_perf_stocks_api_performance_pre_materialized_cache_sync_handlers_implementation_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L68", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_historical_data", - "target": "docs_stocks_api_codeblock_6" + "source": "plans_2026_08_15_stocks_api_perf_stocks_api_performance_pre_materialized_cache_sync_handlers_implementation_plan", + "target": "plans_2026_08_15_stocks_api_perf_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L47", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L23", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_key_management", - "target": "docs_stocks_api_codeblock_4" + "source": "plans_2026_08_15_stocks_api_perf_stocks_api_performance_pre_materialized_cache_sync_handlers_implementation_plan", + "target": "plans_2026_08_15_stocks_api_perf_file_structure" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L63", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L633", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_fundamental_data", - "target": "docs_stocks_api_codeblock_5" + "source": "plans_2026_08_15_stocks_api_perf_stocks_api_performance_pre_materialized_cache_sync_handlers_implementation_plan", + "target": "plans_2026_08_15_stocks_api_perf_self_review" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L74", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L35", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_fundamental_data", - "target": "docs_stocks_api_codeblock_7" + "source": "plans_2026_08_15_stocks_api_perf_file_structure", + "target": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L86", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L251", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_fundamental_data", - "target": "docs_stocks_api_codeblock_8" + "source": "plans_2026_08_15_stocks_api_perf_file_structure", + "target": "plans_2026_08_15_stocks_api_perf_task_2_fast_paths_in_stocksquerymanager_for_default_shaped_queries" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L76", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L392", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_cotations_10_year_daily_history", - "target": "docs_stocks_api_codeblock_6" + "source": "plans_2026_08_15_stocks_api_perf_file_structure", + "target": "plans_2026_08_15_stocks_api_perf_task_3_convert_query_handlers_to_sync_def" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L89", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L468", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_live_price", - "target": "docs_stocks_api_codeblock_7" + "source": "plans_2026_08_15_stocks_api_perf_file_structure", + "target": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L106", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L613", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_response_format", - "target": "docs_stocks_api_codeblock_8" + "source": "plans_2026_08_15_stocks_api_perf_file_structure", + "target": "plans_2026_08_15_stocks_api_perf_task_5_full_verification_graphify_update" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/stocks_api.md", - "source_location": "L94", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L49", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_stocks_api_response_format", - "target": "docs_stocks_api_codeblock_9" + "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L88", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_md", - "target": "docs_user_user_management" + "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L5", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L118", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_user_management", - "target": "docs_user_roles_and_permissions" + "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L17", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L131", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_user_management", - "target": "docs_user_api_endpoints" + "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L59", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L177", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_user_management", - "target": "docs_user_session_management" + "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L112", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L228", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_user_management", - "target": "docs_user_api_keys_stocks_api" + "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L123", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L244", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_user_management", - "target": "docs_user_rate_limits_related_services" + "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L135", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L263", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_user_management", - "target": "docs_user_not_implemented" + "source": "plans_2026_08_15_stocks_api_perf_task_2_fast_paths_in_stocksquerymanager_for_default_shaped_queries", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L156", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L315", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_user_management", - "target": "docs_user_workflow" + "source": "plans_2026_08_15_stocks_api_perf_task_2_fast_paths_in_stocksquerymanager_for_default_shaped_queries", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L177", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L349", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_user_management", - "target": "docs_user_license" + "source": "plans_2026_08_15_stocks_api_perf_task_2_fast_paths_in_stocksquerymanager_for_default_shaped_queries", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L140", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L405", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_user_management", - "target": "docs_user_permission_system" + "source": "plans_2026_08_15_stocks_api_perf_task_3_convert_query_handlers_to_sync_def", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L19", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L461", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_api_endpoints", - "target": "docs_user_health_check" + "source": "plans_2026_08_15_stocks_api_perf_task_3_convert_query_handlers_to_sync_def", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L25", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L482", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_api_endpoints", - "target": "docs_user_get_profile" + "source": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_13" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L53", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L512", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_api_endpoints", - "target": "docs_user_admin_access" + "source": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_14" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L41", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L519", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_api_endpoints", - "target": "docs_user_upgrade_to_developer_starter" + "source": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_15" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L47", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L539", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_api_endpoints", - "target": "docs_user_upgrade_to_developer_enterprise" + "source": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_16" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L20", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L548", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_health_check", - "target": "docs_user_codeblock_1" + "source": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_17" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L27", + "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", + "source_location": "L606", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_get_profile", - "target": "docs_user_codeblock_2" + "source": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path", + "target": "plans_2026_08_15_stocks_api_perf_codeblock_18" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L31", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_get_profile", - "target": "docs_user_codeblock_3" + "source": "docs_superpowers_plans_2026_08_15_workspace_endpoints_md", + "target": "plans_2026_08_15_workspace_endpoints_workspace_file_endpoints_agent_serve_file_tool_implementation_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L39", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L16", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_admin_access", - "target": "docs_user_codeblock_3" + "source": "plans_2026_08_15_workspace_endpoints_workspace_file_endpoints_agent_serve_file_tool_implementation_plan", + "target": "plans_2026_08_15_workspace_endpoints_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L55", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L632", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_admin_access", - "target": "docs_user_codeblock_6" + "source": "plans_2026_08_15_workspace_endpoints_workspace_file_endpoints_agent_serve_file_tool_implementation_plan", + "target": "plans_2026_08_15_workspace_endpoints_self_review" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L63", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L29", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_session_management", - "target": "docs_user_list_all_sessions" + "source": "plans_2026_08_15_workspace_endpoints_global_constraints", + "target": "plans_2026_08_15_workspace_endpoints_task_1_sandbox_delete_file_binary_write" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L92", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L152", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_session_management", - "target": "docs_user_get_current_session" + "source": "plans_2026_08_15_workspace_endpoints_global_constraints", + "target": "plans_2026_08_15_workspace_endpoints_task_2_dependency_config_setting" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L114", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L198", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_session_management", - "target": "docs_user_revoke_a_session" + "source": "plans_2026_08_15_workspace_endpoints_global_constraints", + "target": "plans_2026_08_15_workspace_endpoints_task_3_controller_endpoints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L127", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L465", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_session_management", - "target": "docs_user_revoke_all_sessions" + "source": "plans_2026_08_15_workspace_endpoints_global_constraints", + "target": "plans_2026_08_15_workspace_endpoints_task_4_serve_file_agent_tool" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L55", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L611", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_list_all_sessions", - "target": "docs_user_codeblock_4" + "source": "plans_2026_08_15_workspace_endpoints_global_constraints", + "target": "plans_2026_08_15_workspace_endpoints_task_5_full_verification" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L59", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L43", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_list_all_sessions", - "target": "docs_user_codeblock_5" + "source": "plans_2026_08_15_workspace_endpoints_task_1_sandbox_delete_file_binary_write", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L65", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L108", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_list_all_sessions", - "target": "docs_user_codeblock_7" + "source": "plans_2026_08_15_workspace_endpoints_task_1_sandbox_delete_file_binary_write", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L69", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L145", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_list_all_sessions", - "target": "docs_user_codeblock_8" + "source": "plans_2026_08_15_workspace_endpoints_task_1_sandbox_delete_file_binary_write", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L43", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L166", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_upgrade_to_developer_starter", - "target": "docs_user_codeblock_4" + "source": "plans_2026_08_15_workspace_endpoints_task_2_dependency_config_setting", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L49", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L172", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_upgrade_to_developer_enterprise", - "target": "docs_user_codeblock_5" + "source": "plans_2026_08_15_workspace_endpoints_task_2_dependency_config_setting", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L83", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L180", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_get_current_session", - "target": "docs_user_codeblock_6" + "source": "plans_2026_08_15_workspace_endpoints_task_2_dependency_config_setting", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L94", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L191", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_get_current_session", - "target": "docs_user_codeblock_9" + "source": "plans_2026_08_15_workspace_endpoints_task_2_dependency_config_setting", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L98", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L212", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_get_current_session", - "target": "docs_user_codeblock_10" + "source": "plans_2026_08_15_workspace_endpoints_task_3_controller_endpoints", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L91", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L368", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_revoke_a_session", - "target": "docs_user_codeblock_7" + "source": "plans_2026_08_15_workspace_endpoints_task_3_controller_endpoints", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L116", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L375", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_revoke_a_session", - "target": "docs_user_codeblock_11" + "source": "plans_2026_08_15_workspace_endpoints_task_3_controller_endpoints", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L120", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L381", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_revoke_a_session", - "target": "docs_user_codeblock_12" + "source": "plans_2026_08_15_workspace_endpoints_task_3_controller_endpoints", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L101", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L458", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_revoke_all_sessions", - "target": "docs_user_codeblock_8" + "source": "plans_2026_08_15_workspace_endpoints_task_3_controller_endpoints", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L105", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L479", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_revoke_all_sessions", - "target": "docs_user_codeblock_9" + "source": "plans_2026_08_15_workspace_endpoints_task_4_serve_file_agent_tool", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_13" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L129", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L560", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_revoke_all_sessions", - "target": "docs_user_codeblock_13" + "source": "plans_2026_08_15_workspace_endpoints_task_4_serve_file_agent_tool", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_14" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L133", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L566", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_revoke_all_sessions", - "target": "docs_user_codeblock_14" + "source": "plans_2026_08_15_workspace_endpoints_task_4_serve_file_agent_tool", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_15" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L141", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L593", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_workflow", - "target": "docs_user_codeblock_10" + "source": "plans_2026_08_15_workspace_endpoints_task_4_serve_file_agent_tool", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_16" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/user.md", - "source_location": "L158", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L604", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_user_workflow", - "target": "docs_user_codeblock_16" + "source": "plans_2026_08_15_workspace_endpoints_task_4_serve_file_agent_tool", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_17" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", + "source_location": "L626", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_investidor10_wallet_research_md", - "target": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa" + "source": "plans_2026_08_15_workspace_endpoints_task_5_full_verification", + "target": "plans_2026_08_15_workspace_endpoints_codeblock_18" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L10", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", - "target": "superpowers_investidor10_wallet_research_1_feature_inventory_nav_structure" + "source": "docs_superpowers_plans_2026_08_15_workspace_frontend_md", + "target": "plans_2026_08_15_workspace_frontend_workspace_files_ui_promptbox_upload_implementation_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L30", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", - "target": "superpowers_investidor10_wallet_research_2_user_lifecycle_end_to_end" + "source": "plans_2026_08_15_workspace_frontend_workspace_files_ui_promptbox_upload_implementation_plan", + "target": "plans_2026_08_15_workspace_frontend_backend_contract_source_of_truth_for_api_js" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L40", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L32", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", - "target": "superpowers_investidor10_wallet_research_3_wallet_api_reference" + "source": "plans_2026_08_15_workspace_frontend_workspace_files_ui_promptbox_upload_implementation_plan", + "target": "plans_2026_08_15_workspace_frontend_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L65", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L43", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", - "target": "superpowers_investidor10_wallet_research_4_data_model_inference_from_payloads_no_db_access" + "source": "plans_2026_08_15_workspace_frontend_global_constraints", + "target": "plans_2026_08_15_workspace_frontend_task_1_api_layer_workspace_functions_in_src_api_js" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L74", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L176", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", - "target": "superpowers_investidor10_wallet_research_5_product_logic" + "source": "plans_2026_08_15_workspace_frontend_global_constraints", + "target": "plans_2026_08_15_workspace_frontend_task_2_settings_menu_workspace_files_grid_in_sessionsidebar" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L82", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L294", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", - "target": "superpowers_investidor10_wallet_research_5b_gaps_unverified_do_not_treat_as_fact" + "source": "plans_2026_08_15_workspace_frontend_global_constraints", + "target": "plans_2026_08_15_workspace_frontend_task_3_drag_drop_file_upload_in_the_promptbox_inputbar_jsx" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-research.md", - "source_location": "L86", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L403", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_research_investidor10_wallet_empirical_research_for_mansa", - "target": "superpowers_investidor10_wallet_research_6_concrete_mansa_proposal_build_first_later_minimal_sketches" + "source": "plans_2026_08_15_workspace_frontend_global_constraints", + "target": "plans_2026_08_15_workspace_frontend_task_4_docker_restart_e2e_of_prometheus_chat_stream_performed_by_controller_not_a_subagent" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L61", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_investidor10_wallet_spec_md", - "target": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec" + "source": "plans_2026_08_15_workspace_frontend_task_1_api_layer_workspace_functions_in_src_api_js", + "target": "plans_2026_08_15_workspace_frontend_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L12", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L122", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", - "target": "superpowers_investidor10_wallet_spec_1_requirements" + "source": "plans_2026_08_15_workspace_frontend_task_1_api_layer_workspace_functions_in_src_api_js", + "target": "plans_2026_08_15_workspace_frontend_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L38", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L169", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", - "target": "superpowers_investidor10_wallet_spec_2_domain_model" + "source": "plans_2026_08_15_workspace_frontend_task_1_api_layer_workspace_functions_in_src_api_js", + "target": "plans_2026_08_15_workspace_frontend_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L49", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L191", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", - "target": "superpowers_investidor10_wallet_spec_3_api_contracts_all_under_wallet_chain_main_controller_wallet_controller_py_main_service_wallet_service_py_fn_main_models_wallet_py_model_auth_depends_usermanager_getcurrentuser_depends_getsession_throughout" + "source": "plans_2026_08_15_workspace_frontend_task_2_settings_menu_workspace_files_grid_in_sessionsidebar", + "target": "plans_2026_08_15_workspace_frontend_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L66", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L246", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", - "target": "superpowers_investidor10_wallet_spec_4_phased_build_plan_writing_plans_each_phase_independently_reviewable_reviewer_pass_per_phase" + "source": "plans_2026_08_15_workspace_frontend_task_2_settings_menu_workspace_files_grid_in_sessionsidebar", + "target": "plans_2026_08_15_workspace_frontend_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L72", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L272", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", - "target": "superpowers_investidor10_wallet_spec_5_risks_assumptions_honest_flags_carried_over_do_not_treat_as_fact" + "source": "plans_2026_08_15_workspace_frontend_task_2_settings_menu_workspace_files_grid_in_sessionsidebar", + "target": "plans_2026_08_15_workspace_frontend_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L81", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L287", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", - "target": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1" + "source": "plans_2026_08_15_workspace_frontend_task_2_settings_menu_workspace_files_grid_in_sessionsidebar", + "target": "plans_2026_08_15_workspace_frontend_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L121", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L308", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", - "target": "superpowers_investidor10_wallet_spec_7_independent_re_verification_swarm_s4_2026_09_29_corrections_to_6" + "source": "plans_2026_08_15_workspace_frontend_task_3_drag_drop_file_upload_in_the_promptbox_inputbar_jsx", + "target": "plans_2026_08_15_workspace_frontend_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L49", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L372", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_mansa_wallet_spec_driven_implementation_spec", - "target": "superpowers_investidor10_wallet_spec_3_api_contracts_all_under_api_wallet_chain_main_controller_wallet_controller_py_main_service_wallet_service_py_fn_main_models_wallet_py_model_auth_depends_usermanager_getcurrentuser_depends_getsession_throughout" + "source": "plans_2026_08_15_workspace_frontend_task_3_drag_drop_file_upload_in_the_promptbox_inputbar_jsx", + "target": "plans_2026_08_15_workspace_frontend_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L14", + "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", + "source_location": "L396", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_1_requirements", - "target": "superpowers_investidor10_wallet_spec_1_1_functional_per_surface_tags_exists_build_on_it_partial_half_reusable_missing_greenfield" + "source": "plans_2026_08_15_workspace_frontend_task_3_drag_drop_file_upload_in_the_promptbox_inputbar_jsx", + "target": "plans_2026_08_15_workspace_frontend_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L28", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_1_requirements", - "target": "superpowers_investidor10_wallet_spec_1_2_non_functional" + "source": "docs_superpowers_plans_2026_08_17_openui_migration_md", + "target": "plans_2026_08_17_openui_migration_openui_migration_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L87", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L20", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", - "target": "superpowers_investidor10_wallet_spec_6_1_db_migrations_user_db_contested_7_1_3_actions_incl_one_destructive_autogenerate_risk" + "source": "plans_2026_08_17_openui_migration_openui_migration_plan", + "target": "plans_2026_08_17_openui_migration_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L94", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L30", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", - "target": "superpowers_investidor10_wallet_spec_6_2_stocks_price_access_confirmed_extended_7_2" + "source": "plans_2026_08_17_openui_migration_openui_migration_plan", + "target": "plans_2026_08_17_openui_migration_file_structure" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L100", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L52", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", - "target": "superpowers_investidor10_wallet_spec_6_3_wiring_auth_tests_contested_7_3_mounting_true_gating_test_seams_missing" + "source": "plans_2026_08_17_openui_migration_openui_migration_plan", + "target": "plans_2026_08_17_openui_migration_task_1_install_openui_remove_mdocui" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L106", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L80", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", - "target": "superpowers_investidor10_wallet_spec_6_4_scraper_pipeline_p2_dividends_has_b3_contested_7_4_data_present_source_staleness_gaps" + "source": "plans_2026_08_17_openui_migration_openui_migration_plan", + "target": "plans_2026_08_17_openui_migration_task_2_define_prometheus_component_library" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L110", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L385", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", - "target": "superpowers_investidor10_wallet_spec_6_5_ordered_actions_before_p1_code" + "source": "plans_2026_08_17_openui_migration_openui_migration_plan", + "target": "plans_2026_08_17_openui_migration_task_3_create_openui_renderer" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L85", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L455", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", - "target": "superpowers_investidor10_wallet_spec_6_1_db_migrations_user_db_ready_2_actions" + "source": "plans_2026_08_17_openui_migration_openui_migration_plan", + "target": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L92", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L610", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", - "target": "superpowers_investidor10_wallet_spec_6_2_stocks_price_access_ready_for_full_series_one_new_helper_needed" + "source": "plans_2026_08_17_openui_migration_openui_migration_plan", + "target": "plans_2026_08_17_openui_migration_task_5_integration_test" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L98", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L640", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", - "target": "superpowers_investidor10_wallet_spec_6_3_wiring_auth_tests_ready" + "source": "plans_2026_08_17_openui_migration_openui_migration_plan", + "target": "plans_2026_08_17_openui_migration_verification_checklist" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L104", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L32", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_6_readiness_assessment_s3_verified_2026_09_29_prerequisites_before_p1", - "target": "superpowers_investidor10_wallet_spec_6_4_scraper_pipeline_p2_dividends_has_b3_ready_public_sources_only" + "source": "plans_2026_08_17_openui_migration_file_structure", + "target": "plans_2026_08_17_openui_migration_frontend_local_only_never_committed" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L125", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L43", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_7_independent_re_verification_swarm_s4_2026_09_29_corrections_to_6", - "target": "superpowers_investidor10_wallet_spec_7_1_db_migrations_6_1_contested_3_actions_one_destructive_risk" + "source": "plans_2026_08_17_openui_migration_file_structure", + "target": "plans_2026_08_17_openui_migration_backend_commit" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L133", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L58", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_7_independent_re_verification_swarm_s4_2026_09_29_corrections_to_6", - "target": "superpowers_investidor10_wallet_spec_7_2_stocks_price_access_6_2_confirmed_incomplete" + "source": "plans_2026_08_17_openui_migration_task_1_install_openui_remove_mdocui", + "target": "plans_2026_08_17_openui_migration_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L143", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L66", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_7_independent_re_verification_swarm_s4_2026_09_29_corrections_to_6", - "target": "superpowers_investidor10_wallet_spec_7_3_wiring_auth_tests_6_3_contested_mounting_true" + "source": "plans_2026_08_17_openui_migration_task_1_install_openui_remove_mdocui", + "target": "plans_2026_08_17_openui_migration_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L150", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L72", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_7_independent_re_verification_swarm_s4_2026_09_29_corrections_to_6", - "target": "superpowers_investidor10_wallet_spec_7_4_scraper_pipeline_6_4_contested" + "source": "plans_2026_08_17_openui_migration_task_1_install_openui_remove_mdocui", + "target": "plans_2026_08_17_openui_migration_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/investidor10-wallet-spec.md", - "source_location": "L159", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L86", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_investidor10_wallet_spec_7_independent_re_verification_swarm_s4_2026_09_29_corrections_to_6", - "target": "superpowers_investidor10_wallet_spec_7_5_revised_pre_p1_actions_supersedes_6_5" + "source": "plans_2026_08_17_openui_migration_task_2_define_prometheus_component_library", + "target": "plans_2026_08_17_openui_migration_component_mapping" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L101", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_nginx_scaling_plan_md", - "target": "superpowers_nginx_scaling_plan_nginx_scaling_plan_reverse_proxy_response_cache_for_stocks_and_the_multi_server_evolution" + "source": "plans_2026_08_17_openui_migration_component_mapping", + "target": "plans_2026_08_17_openui_migration_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L64", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L339", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_nginx_scaling_plan_md", - "target": "superpowers_nginx_scaling_plan_part_1_implementation_plan" + "source": "plans_2026_08_17_openui_migration_component_mapping", + "target": "plans_2026_08_17_openui_migration_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L347", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L396", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_nginx_scaling_plan_md", - "target": "superpowers_nginx_scaling_plan_part_2_benchmark_plan" + "source": "plans_2026_08_17_openui_migration_task_3_create_openui_renderer", + "target": "plans_2026_08_17_openui_migration_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L510", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L428", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_nginx_scaling_plan_md", - "target": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks" + "source": "plans_2026_08_17_openui_migration_task_3_create_openui_renderer", + "target": "plans_2026_08_17_openui_migration_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L661", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L435", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_nginx_scaling_plan_md", - "target": "superpowers_nginx_scaling_plan_open_decisions_blocking_or_product_owned" + "source": "plans_2026_08_17_openui_migration_task_3_create_openui_renderer", + "target": "plans_2026_08_17_openui_migration_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L669", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L442", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_nginx_scaling_plan_md", - "target": "superpowers_nginx_scaling_plan_next_actions_not_in_scope_here" + "source": "plans_2026_08_17_openui_migration_task_3_create_openui_renderer", + "target": "plans_2026_08_17_openui_migration_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L17", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L449", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_nginx_scaling_plan_reverse_proxy_response_cache_for_stocks_and_the_multi_server_evolution", - "target": "superpowers_nginx_scaling_plan_0_purpose_and_constraints" + "source": "plans_2026_08_17_openui_migration_task_3_create_openui_renderer", + "target": "plans_2026_08_17_openui_migration_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L35", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L467", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_nginx_scaling_plan_reverse_proxy_response_cache_for_stocks_and_the_multi_server_evolution", - "target": "superpowers_nginx_scaling_plan_0_1_rev_2_do_first_app_cache_ttl_increase_fields_cache_no_nginx_no_redis" + "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", + "target": "plans_2026_08_17_openui_migration_codeblock_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L66", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L486", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", - "target": "superpowers_nginx_scaling_plan_1_1_architecture_decision" + "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", + "target": "plans_2026_08_17_openui_migration_codeblock_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L79", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L501", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", - "target": "superpowers_nginx_scaling_plan_1_2_file_layout" + "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", + "target": "plans_2026_08_17_openui_migration_codeblock_13" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L96", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L542", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", - "target": "superpowers_nginx_scaling_plan_1_3_phase_p0_nginx_service_config_skeleton" + "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", + "target": "plans_2026_08_17_openui_migration_codeblock_14" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L152", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L555", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", - "target": "superpowers_nginx_scaling_plan_1_4_phase_p1_cache_locations_ttl_table_directives" + "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", + "target": "plans_2026_08_17_openui_migration_codeblock_15" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L251", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L572", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", - "target": "superpowers_nginx_scaling_plan_1_5_phase_p2_port_scheme_worker_containers_keepalive" + "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", + "target": "plans_2026_08_17_openui_migration_codeblock_16" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L277", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L577", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", - "target": "superpowers_nginx_scaling_plan_1_6_phase_p3_remote_vps_upstreams_health_strategy" + "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", + "target": "plans_2026_08_17_openui_migration_codeblock_17" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L309", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L590", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", - "target": "superpowers_nginx_scaling_plan_1_7_phase_p4_handoff_design_no_code_in_this_plan" + "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", + "target": "plans_2026_08_17_openui_migration_codeblock_18" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L320", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L596", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", - "target": "superpowers_nginx_scaling_plan_1_8_quota_rate_limit_semantics_after_caching" + "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", + "target": "plans_2026_08_17_openui_migration_codeblock_19" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L332", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L602", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", - "target": "superpowers_nginx_scaling_plan_1_9_anti_scraping_note_todo_17" + "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", + "target": "plans_2026_08_17_openui_migration_codeblock_20" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L336", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L614", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_1_implementation_plan", - "target": "superpowers_nginx_scaling_plan_1_10_edge_cases_risks_implementation" + "source": "plans_2026_08_17_openui_migration_task_5_integration_test", + "target": "plans_2026_08_17_openui_migration_codeblock_21" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L82", + "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_location": "L620", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_1_2_file_layout", - "target": "superpowers_nginx_scaling_plan_codeblock_1" + "source": "plans_2026_08_17_openui_migration_task_5_integration_test", + "target": "plans_2026_08_17_openui_migration_codeblock_22" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L98", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_1_3_phase_p0_nginx_service_config_skeleton", - "target": "superpowers_nginx_scaling_plan_codeblock_2" + "source": "docs_superpowers_plans_2026_09_03_followup_hardening_md", + "target": "plans_2026_09_03_followup_hardening_follow_up_hardening_implementation_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L118", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_1_3_phase_p0_nginx_service_config_skeleton", - "target": "superpowers_nginx_scaling_plan_codeblock_3" + "source": "plans_2026_09_03_followup_hardening_follow_up_hardening_implementation_plan", + "target": "plans_2026_09_03_followup_hardening_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L139", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L26", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_1_3_phase_p0_nginx_service_config_skeleton", - "target": "superpowers_nginx_scaling_plan_codeblock_4" + "source": "plans_2026_09_03_followup_hardening_follow_up_hardening_implementation_plan", + "target": "plans_2026_09_03_followup_hardening_file_map" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L155", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L814", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_1_4_phase_p1_cache_locations_ttl_table_directives", - "target": "superpowers_nginx_scaling_plan_codeblock_5" + "source": "plans_2026_09_03_followup_hardening_follow_up_hardening_implementation_plan", + "target": "plans_2026_09_03_followup_hardening_self_review" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L186", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L44", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_1_4_phase_p1_cache_locations_ttl_table_directives", - "target": "superpowers_nginx_scaling_plan_codeblock_6" + "source": "plans_2026_09_03_followup_hardening_file_map", + "target": "plans_2026_09_03_followup_hardening_task_1_thoth_maat_permission_decision" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L242", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L127", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_1_4_phase_p1_cache_locations_ttl_table_directives", - "target": "superpowers_nginx_scaling_plan_codeblock_7" + "source": "plans_2026_09_03_followup_hardening_file_map", + "target": "plans_2026_09_03_followup_hardening_task_2_p6_redis_cashews_insertion_behind_existing_sync_cache" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L257", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L240", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_1_5_phase_p2_port_scheme_worker_containers_keepalive", - "target": "superpowers_nginx_scaling_plan_codeblock_8" + "source": "plans_2026_09_03_followup_hardening_file_map", + "target": "plans_2026_09_03_followup_hardening_task_3_zstd_hot_path_rework_via_feather_to_dict_zstd_migration" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L279", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L337", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_1_6_phase_p3_remote_vps_upstreams_health_strategy", - "target": "superpowers_nginx_scaling_plan_codeblock_9" + "source": "plans_2026_09_03_followup_hardening_file_map", + "target": "plans_2026_09_03_followup_hardening_task_4_queryhistorical_queryfundamental_presort_invariant_guard" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L291", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L415", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_1_6_phase_p3_remote_vps_upstreams_health_strategy", - "target": "superpowers_nginx_scaling_plan_codeblock_10" + "source": "plans_2026_09_03_followup_hardening_file_map", + "target": "plans_2026_09_03_followup_hardening_task_5_history_backfill_dedup_indices_as_logging_only" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L349", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L509", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", - "target": "superpowers_nginx_scaling_plan_2_0_grounding_what_the_code_actually_does" + "source": "plans_2026_09_03_followup_hardening_file_map", + "target": "plans_2026_09_03_followup_hardening_task_6_stocks_api_limiter_design_design_only_do_not_enable" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L381", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L562", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", - "target": "superpowers_nginx_scaling_plan_2_1_hypotheses" + "source": "plans_2026_09_03_followup_hardening_file_map", + "target": "plans_2026_09_03_followup_hardening_task_7_remove_temporary_run_py_scraper_debug_endpoint" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L390", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L623", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", - "target": "superpowers_nginx_scaling_plan_2_2_tooling" + "source": "plans_2026_09_03_followup_hardening_file_map", + "target": "plans_2026_09_03_followup_hardening_task_8_fix_20_pre_existing_environmental_failures" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L440", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L712", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", - "target": "superpowers_nginx_scaling_plan_2_3_scenarios" + "source": "plans_2026_09_03_followup_hardening_file_map", + "target": "plans_2026_09_03_followup_hardening_task_9_session_refresh_token_rotation_follow_up" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L452", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L61", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", - "target": "superpowers_nginx_scaling_plan_2_4_protocol" + "source": "plans_2026_09_03_followup_hardening_task_1_thoth_maat_permission_decision", + "target": "plans_2026_09_03_followup_hardening_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L463", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L80", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", - "target": "superpowers_nginx_scaling_plan_2_5_metrics" + "source": "plans_2026_09_03_followup_hardening_task_1_thoth_maat_permission_decision", + "target": "plans_2026_09_03_followup_hardening_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L467", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L96", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", - "target": "superpowers_nginx_scaling_plan_2_6_acceptance_thresholds_all_proposed_freeze_after_first_real_run" + "source": "plans_2026_09_03_followup_hardening_task_1_thoth_maat_permission_decision", + "target": "plans_2026_09_03_followup_hardening_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L484", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L120", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", - "target": "superpowers_nginx_scaling_plan_2_7_results_doc_layout" + "source": "plans_2026_09_03_followup_hardening_task_1_thoth_maat_permission_decision", + "target": "plans_2026_09_03_followup_hardening_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L493", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L143", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", - "target": "superpowers_nginx_scaling_plan_2_8_feeding_status_todo_14" + "source": "plans_2026_09_03_followup_hardening_task_2_p6_redis_cashews_insertion_behind_existing_sync_cache", + "target": "plans_2026_09_03_followup_hardening_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L499", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L185", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_2_benchmark_plan", - "target": "superpowers_nginx_scaling_plan_2_9_benchmark_risks" + "source": "plans_2026_09_03_followup_hardening_task_2_p6_redis_cashews_insertion_behind_existing_sync_cache", + "target": "plans_2026_09_03_followup_hardening_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L393", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L198", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_2_2_tooling", - "target": "superpowers_nginx_scaling_plan_codeblock_11" + "source": "plans_2026_09_03_followup_hardening_task_2_p6_redis_cashews_insertion_behind_existing_sync_cache", + "target": "plans_2026_09_03_followup_hardening_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L406", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L204", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_2_2_tooling", - "target": "superpowers_nginx_scaling_plan_codeblock_12" + "source": "plans_2026_09_03_followup_hardening_task_2_p6_redis_cashews_insertion_behind_existing_sync_cache", + "target": "plans_2026_09_03_followup_hardening_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L414", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L233", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_2_2_tooling", - "target": "superpowers_nginx_scaling_plan_codeblock_13" + "source": "plans_2026_09_03_followup_hardening_task_2_p6_redis_cashews_insertion_behind_existing_sync_cache", + "target": "plans_2026_09_03_followup_hardening_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L420", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L256", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_2_2_tooling", - "target": "superpowers_nginx_scaling_plan_codeblock_14" + "source": "plans_2026_09_03_followup_hardening_task_3_zstd_hot_path_rework_via_feather_to_dict_zstd_migration", + "target": "plans_2026_09_03_followup_hardening_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L431", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L284", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_2_2_tooling", - "target": "superpowers_nginx_scaling_plan_codeblock_15" + "source": "plans_2026_09_03_followup_hardening_task_3_zstd_hot_path_rework_via_feather_to_dict_zstd_migration", + "target": "plans_2026_09_03_followup_hardening_codeblock_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L486", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L298", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_2_7_results_doc_layout", - "target": "superpowers_nginx_scaling_plan_codeblock_16" + "source": "plans_2026_09_03_followup_hardening_task_3_zstd_hot_path_rework_via_feather_to_dict_zstd_migration", + "target": "plans_2026_09_03_followup_hardening_codeblock_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L512", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L330", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", - "target": "superpowers_nginx_scaling_plan_3_0_verified_ground_truth" + "source": "plans_2026_09_03_followup_hardening_task_3_zstd_hot_path_rework_via_feather_to_dict_zstd_migration", + "target": "plans_2026_09_03_followup_hardening_codeblock_13" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L529", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L351", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", - "target": "superpowers_nginx_scaling_plan_3_1_target_topology" + "source": "plans_2026_09_03_followup_hardening_task_4_queryhistorical_queryfundamental_presort_invariant_guard", + "target": "plans_2026_09_03_followup_hardening_codeblock_14" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L546", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L390", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", - "target": "superpowers_nginx_scaling_plan_3_2_worker_container_extraction" + "source": "plans_2026_09_03_followup_hardening_task_4_queryhistorical_queryfundamental_presort_invariant_guard", + "target": "plans_2026_09_03_followup_hardening_codeblock_15" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L563", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L408", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", - "target": "superpowers_nginx_scaling_plan_3_3_nginx_upstream_evolution_validated_against_the_user_s_plan" + "source": "plans_2026_09_03_followup_hardening_task_4_queryhistorical_queryfundamental_presort_invariant_guard", + "target": "plans_2026_09_03_followup_hardening_codeblock_16" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L584", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L429", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", - "target": "superpowers_nginx_scaling_plan_3_4_todo_13_migration_drop_service_host_service_port" + "source": "plans_2026_09_03_followup_hardening_task_5_history_backfill_dedup_indices_as_logging_only", + "target": "plans_2026_09_03_followup_hardening_codeblock_17" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L591", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L451", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", - "target": "superpowers_nginx_scaling_plan_3_5_redis_exactly_two_jobs" + "source": "plans_2026_09_03_followup_hardening_task_5_history_backfill_dedup_indices_as_logging_only", + "target": "plans_2026_09_03_followup_hardening_codeblock_18" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L607", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L502", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", - "target": "superpowers_nginx_scaling_plan_3_6_cache_strategy_across_boxes" + "source": "plans_2026_09_03_followup_hardening_task_5_history_backfill_dedup_indices_as_logging_only", + "target": "plans_2026_09_03_followup_hardening_codeblock_19" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L613", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L525", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", - "target": "superpowers_nginx_scaling_plan_3_7_autoscaling_story_todo_11" + "source": "plans_2026_09_03_followup_hardening_task_6_stocks_api_limiter_design_design_only_do_not_enable", + "target": "plans_2026_09_03_followup_hardening_codeblock_20" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L618", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L541", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", - "target": "superpowers_nginx_scaling_plan_3_8_forgevm_interplay_todo_12" + "source": "plans_2026_09_03_followup_hardening_task_6_stocks_api_limiter_design_design_only_do_not_enable", + "target": "plans_2026_09_03_followup_hardening_codeblock_21" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L622", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L555", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", - "target": "superpowers_nginx_scaling_plan_3_9_risk_register" + "source": "plans_2026_09_03_followup_hardening_task_6_stocks_api_limiter_design_design_only_do_not_enable", + "target": "plans_2026_09_03_followup_hardening_codeblock_22" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L642", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L577", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_part_3_future_scaling_evolution_risks", - "target": "superpowers_nginx_scaling_plan_3_10_migration_sequence_verification" + "source": "plans_2026_09_03_followup_hardening_task_7_remove_temporary_run_py_scraper_debug_endpoint", + "target": "plans_2026_09_03_followup_hardening_codeblock_23" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L534", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L598", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_3_1_target_topology", - "target": "superpowers_nginx_scaling_plan_codeblock_17" + "source": "plans_2026_09_03_followup_hardening_task_7_remove_temporary_run_py_scraper_debug_endpoint", + "target": "plans_2026_09_03_followup_hardening_codeblock_24" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/nginx-scaling-plan.md", - "source_location": "L567", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L616", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_nginx_scaling_plan_3_3_nginx_upstream_evolution_validated_against_the_user_s_plan", - "target": "superpowers_nginx_scaling_plan_codeblock_18" + "source": "plans_2026_09_03_followup_hardening_task_7_remove_temporary_run_py_scraper_debug_endpoint", + "target": "plans_2026_09_03_followup_hardening_codeblock_25" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L640", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_uvicorn_worker_scaling_plan_md", - "target": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change" + "source": "plans_2026_09_03_followup_hardening_task_8_fix_20_pre_existing_environmental_failures", + "target": "plans_2026_09_03_followup_hardening_codeblock_26" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L668", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_uvicorn_worker_scaling_plan_md", - "target": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_scaling_verified_state_and_evaluated_plan" + "source": "plans_2026_09_03_followup_hardening_task_8_fix_20_pre_existing_environmental_failures", + "target": "plans_2026_09_03_followup_hardening_codeblock_27" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L676", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_uvicorn_worker_scaling_plan_md", - "target": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_scaling_verified_state_evaluated_plan" + "source": "plans_2026_09_03_followup_hardening_task_8_fix_20_pre_existing_environmental_failures", + "target": "plans_2026_09_03_followup_hardening_codeblock_28" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L17", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L705", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", - "target": "superpowers_uvicorn_worker_scaling_plan_0_the_blockers_ranked" + "source": "plans_2026_09_03_followup_hardening_task_8_fix_20_pre_existing_environmental_failures", + "target": "plans_2026_09_03_followup_hardening_codeblock_29" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L32", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L731", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", - "target": "superpowers_uvicorn_worker_scaling_plan_1_verified_state_compact" + "source": "plans_2026_09_03_followup_hardening_task_9_session_refresh_token_rotation_follow_up", + "target": "plans_2026_09_03_followup_hardening_codeblock_30" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L52", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L753", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", - "target": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine" + "source": "plans_2026_09_03_followup_hardening_task_9_session_refresh_token_rotation_follow_up", + "target": "plans_2026_09_03_followup_hardening_codeblock_31" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L135", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L769", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", - "target": "superpowers_uvicorn_worker_scaling_plan_3_rulings_conflicts_i_adjudicated" + "source": "plans_2026_09_03_followup_hardening_task_9_session_refresh_token_rotation_follow_up", + "target": "plans_2026_09_03_followup_hardening_codeblock_32" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L147", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L780", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", - "target": "superpowers_uvicorn_worker_scaling_plan_4_design_spec_alignment_2026_09_29_nginx_scaling_design_md" + "source": "plans_2026_09_03_followup_hardening_task_9_session_refresh_token_rotation_follow_up", + "target": "plans_2026_09_03_followup_hardening_codeblock_33" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L162", + "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", + "source_location": "L807", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", - "target": "superpowers_uvicorn_worker_scaling_plan_5_sequencing_verification_and_bans" + "source": "plans_2026_09_03_followup_hardening_task_9_session_refresh_token_rotation_follow_up", + "target": "plans_2026_09_03_followup_hardening_codeblock_34" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L174", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", - "target": "superpowers_uvicorn_worker_scaling_plan_6_options_demoted" + "source": "docs_superpowers_plans_2026_09_04_wallet_management_md", + "target": "plans_2026_09_04_wallet_management_wallet_management_thoth_iyagba_implementation_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L186", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", - "target": "superpowers_uvicorn_worker_scaling_plan_7_risks" + "source": "plans_2026_09_04_wallet_management_wallet_management_thoth_iyagba_implementation_plan", + "target": "plans_2026_09_04_wallet_management_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L200", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L35", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_uvicorn_worker_migration_\u00e2_what_must_change", - "target": "superpowers_uvicorn_worker_scaling_plan_8_evidence_index" + "source": "plans_2026_09_04_wallet_management_wallet_management_thoth_iyagba_implementation_plan", + "target": "plans_2026_09_04_wallet_management_file_structure" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L54", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L60", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine", - "target": "superpowers_uvicorn_worker_scaling_plan_b1_\u00e2_startup_and_process_model_must_fix" + "source": "plans_2026_09_04_wallet_management_file_structure", + "target": "plans_2026_09_04_wallet_management_task_1_wallet_models_and_user_relationship" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L67", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L166", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine", - "target": "superpowers_uvicorn_worker_scaling_plan_b2_\u00e2_cache_under_n_1_must_fix" + "source": "plans_2026_09_04_wallet_management_file_structure", + "target": "plans_2026_09_04_wallet_management_task_2_alembic_migration_for_wallet_tables" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L79", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L269", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine", - "target": "superpowers_uvicorn_worker_scaling_plan_b3_\u00e2_db_pools_must_fix_at_n\u00e2_3_on_one_server" + "source": "plans_2026_09_04_wallet_management_file_structure", + "target": "plans_2026_09_04_wallet_management_task_3_pure_derivation_math" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L98", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L391", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine", - "target": "superpowers_uvicorn_worker_scaling_plan_b4_\u00e2_migrations_must_fix" + "source": "plans_2026_09_04_wallet_management_file_structure", + "target": "plans_2026_09_04_wallet_management_task_4_holding_endpoints_create_holding_and_retarget_weight" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L107", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L567", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine", - "target": "superpowers_uvicorn_worker_scaling_plan_b5_\u00e2_per_process_state_ranked_scope_by_service" + "source": "plans_2026_09_04_wallet_management_file_structure", + "target": "plans_2026_09_04_wallet_management_task_5_lot_endpoint_append_immutable_buy_sell_lots" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/uvicorn-worker-scaling-plan.md", - "source_location": "L123", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L720", "weight": 1.0, "confidence_score": 1.0, - "source": "superpowers_uvicorn_worker_scaling_plan_2_change_inventory_the_spine", - "target": "superpowers_uvicorn_worker_scaling_plan_b6_\u00e2_deployment_glue_must_build" + "source": "plans_2026_09_04_wallet_management_file_structure", + "target": "plans_2026_09_04_wallet_management_task_6_price_client_one_batched_stocks_api_fetch_per_snapshot" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/benchmarks/stocks-cache-ttl.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L869", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_benchmarks_stocks_cache_ttl_md", - "target": "benchmarks_stocks_cache_ttl_stocks_endpoint_cache_ttl_6h_rss_check" + "source": "plans_2026_09_04_wallet_management_file_structure", + "target": "plans_2026_09_04_wallet_management_task_7_snapshot_endpoint_derived_portfolio_read_with_live_prices" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1000", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_08_09_sse_resume_md", - "target": "plans_2026_08_09_sse_resume_sse_resume_implementation_plan" + "source": "plans_2026_09_04_wallet_management_file_structure", + "target": "plans_2026_09_04_wallet_management_task_8_history_endpoint_paginated_lots_with_per_sell_realized_gain" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L11", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1115", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_sse_resume_implementation_plan", - "target": "plans_2026_08_09_sse_resume_global_constraints" + "source": "plans_2026_09_04_wallet_management_file_structure", + "target": "plans_2026_09_04_wallet_management_task_9_walletservice_wiring_quality_gate_full_suite_ruff_mypy_coverage" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L26", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1224", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_global_constraints", - "target": "plans_2026_08_09_sse_resume_task_1_streambus_module_with_unit_tests" + "source": "plans_2026_09_04_wallet_management_file_structure", + "target": "plans_2026_09_04_wallet_management_task_10_first_party_get_stocks_dividends_adjusted_docstring_fix" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L242", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1325", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_global_constraints", - "target": "plans_2026_08_09_sse_resume_task_2_background_run_get_resume_route_in_prometheus_controller" + "source": "plans_2026_09_04_wallet_management_file_structure", + "target": "plans_2026_09_04_wallet_management_task_11_wallet_receipt_ledger_wallet_dividends_table_receipt_suggestion_endpoints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L412", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1482", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_global_constraints", - "target": "plans_2026_08_09_sse_resume_task_3_frontend_api_js_shared_sse_parser_resumechat_cursor_tracking" + "source": "plans_2026_09_04_wallet_management_file_structure", + "target": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L576", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1618", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_global_constraints", - "target": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume" + "source": "plans_2026_09_04_wallet_management_file_structure", + "target": "plans_2026_09_04_wallet_management_task_13_corporate_actions_table_read_time_scaling_sobras_rule_definitive_full_gate" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L863", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L73", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_global_constraints", - "target": "plans_2026_08_09_sse_resume_task_5_full_verification_todo_check_off" + "source": "plans_2026_09_04_wallet_management_task_1_wallet_models_and_user_relationship", + "target": "plans_2026_09_04_wallet_management_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L41", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L101", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_1_streambus_module_with_unit_tests", - "target": "plans_2026_08_09_sse_resume_codeblock_1" + "source": "plans_2026_09_04_wallet_management_task_1_wallet_models_and_user_relationship", + "target": "plans_2026_09_04_wallet_management_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L130", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L138", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_1_streambus_module_with_unit_tests", - "target": "plans_2026_08_09_sse_resume_codeblock_2" + "source": "plans_2026_09_04_wallet_management_task_1_wallet_models_and_user_relationship", + "target": "plans_2026_09_04_wallet_management_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L235", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L144", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_1_streambus_module_with_unit_tests", - "target": "plans_2026_08_09_sse_resume_codeblock_3" + "source": "plans_2026_09_04_wallet_management_task_1_wallet_models_and_user_relationship", + "target": "plans_2026_09_04_wallet_management_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L257", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L159", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_2_background_run_get_resume_route_in_prometheus_controller", - "target": "plans_2026_08_09_sse_resume_codeblock_4" + "source": "plans_2026_09_04_wallet_management_task_1_wallet_models_and_user_relationship", + "target": "plans_2026_09_04_wallet_management_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L329", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L189", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_2_background_run_get_resume_route_in_prometheus_controller", - "target": "plans_2026_08_09_sse_resume_codeblock_5" + "source": "plans_2026_09_04_wallet_management_task_2_alembic_migration_for_wallet_tables", + "target": "plans_2026_09_04_wallet_management_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L405", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L248", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_2_background_run_get_resume_route_in_prometheus_controller", - "target": "plans_2026_08_09_sse_resume_codeblock_6" + "source": "plans_2026_09_04_wallet_management_task_2_alembic_migration_for_wallet_tables", + "target": "plans_2026_09_04_wallet_management_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L426", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L262", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_3_frontend_api_js_shared_sse_parser_resumechat_cursor_tracking", - "target": "plans_2026_08_09_sse_resume_codeblock_7" + "source": "plans_2026_09_04_wallet_management_task_2_alembic_migration_for_wallet_tables", + "target": "plans_2026_09_04_wallet_management_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L498", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L281", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_3_frontend_api_js_shared_sse_parser_resumechat_cursor_tracking", - "target": "plans_2026_08_09_sse_resume_codeblock_8" + "source": "plans_2026_09_04_wallet_management_task_3_pure_derivation_math", + "target": "plans_2026_09_04_wallet_management_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L569", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L325", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_3_frontend_api_js_shared_sse_parser_resumechat_cursor_tracking", - "target": "plans_2026_08_09_sse_resume_codeblock_9" + "source": "plans_2026_09_04_wallet_management_task_3_pure_derivation_math", + "target": "plans_2026_09_04_wallet_management_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L590", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L384", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume", - "target": "plans_2026_08_09_sse_resume_codeblock_10" + "source": "plans_2026_09_04_wallet_management_task_3_pure_derivation_math", + "target": "plans_2026_09_04_wallet_management_codeblock_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L659", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L404", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume", - "target": "plans_2026_08_09_sse_resume_codeblock_11" + "source": "plans_2026_09_04_wallet_management_task_4_holding_endpoints_create_holding_and_retarget_weight", + "target": "plans_2026_09_04_wallet_management_codeblock_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L681", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L471", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume", - "target": "plans_2026_08_09_sse_resume_codeblock_12" + "source": "plans_2026_09_04_wallet_management_task_4_holding_endpoints_create_holding_and_retarget_weight", + "target": "plans_2026_09_04_wallet_management_codeblock_13" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L768", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L524", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume", - "target": "plans_2026_08_09_sse_resume_codeblock_13" + "source": "plans_2026_09_04_wallet_management_task_4_holding_endpoints_create_holding_and_retarget_weight", + "target": "plans_2026_09_04_wallet_management_codeblock_14" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L835", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L560", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume", - "target": "plans_2026_08_09_sse_resume_codeblock_14" + "source": "plans_2026_09_04_wallet_management_task_4_holding_endpoints_create_holding_and_retarget_weight", + "target": "plans_2026_09_04_wallet_management_codeblock_15" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L856", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L580", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_4_frontend_app_jsx_resume_lifecycle_boot_resume", - "target": "plans_2026_08_09_sse_resume_codeblock_15" + "source": "plans_2026_09_04_wallet_management_task_5_lot_endpoint_append_immutable_buy_sell_lots", + "target": "plans_2026_09_04_wallet_management_codeblock_16" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-09-sse-resume.md", - "source_location": "L889", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L649", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_09_sse_resume_task_5_full_verification_todo_check_off", - "target": "plans_2026_08_09_sse_resume_codeblock_16" + "source": "plans_2026_09_04_wallet_management_task_5_lot_endpoint_append_immutable_buy_sell_lots", + "target": "plans_2026_09_04_wallet_management_codeblock_17" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L659", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_08_15_stocks_api_perf_md", - "target": "plans_2026_08_15_stocks_api_perf_stocks_api_performance_pre_materialized_cache_sync_handlers_implementation_plan" + "source": "plans_2026_09_04_wallet_management_task_5_lot_endpoint_append_immutable_buy_sell_lots", + "target": "plans_2026_09_04_wallet_management_codeblock_18" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L13", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L693", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_stocks_api_performance_pre_materialized_cache_sync_handlers_implementation_plan", - "target": "plans_2026_08_15_stocks_api_perf_global_constraints" + "source": "plans_2026_09_04_wallet_management_task_5_lot_endpoint_append_immutable_buy_sell_lots", + "target": "plans_2026_09_04_wallet_management_codeblock_19" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L23", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L713", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_stocks_api_performance_pre_materialized_cache_sync_handlers_implementation_plan", - "target": "plans_2026_08_15_stocks_api_perf_file_structure" + "source": "plans_2026_09_04_wallet_management_task_5_lot_endpoint_append_immutable_buy_sell_lots", + "target": "plans_2026_09_04_wallet_management_codeblock_20" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L633", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L732", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_stocks_api_performance_pre_materialized_cache_sync_handlers_implementation_plan", - "target": "plans_2026_08_15_stocks_api_perf_self_review" + "source": "plans_2026_09_04_wallet_management_task_6_price_client_one_batched_stocks_api_fetch_per_snapshot", + "target": "plans_2026_09_04_wallet_management_codeblock_21" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L35", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L804", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_file_structure", - "target": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh" + "source": "plans_2026_09_04_wallet_management_task_6_price_client_one_batched_stocks_api_fetch_per_snapshot", + "target": "plans_2026_09_04_wallet_management_codeblock_22" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L251", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L862", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_file_structure", - "target": "plans_2026_08_15_stocks_api_perf_task_2_fast_paths_in_stocksquerymanager_for_default_shaped_queries" + "source": "plans_2026_09_04_wallet_management_task_6_price_client_one_batched_stocks_api_fetch_per_snapshot", + "target": "plans_2026_09_04_wallet_management_codeblock_23" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L392", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L882", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_file_structure", - "target": "plans_2026_08_15_stocks_api_perf_task_3_convert_query_handlers_to_sync_def" + "source": "plans_2026_09_04_wallet_management_task_7_snapshot_endpoint_derived_portfolio_read_with_live_prices", + "target": "plans_2026_09_04_wallet_management_codeblock_24" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L468", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L944", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_file_structure", - "target": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path" + "source": "plans_2026_09_04_wallet_management_task_7_snapshot_endpoint_derived_portfolio_read_with_live_prices", + "target": "plans_2026_09_04_wallet_management_codeblock_25" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L613", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L972", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_file_structure", - "target": "plans_2026_08_15_stocks_api_perf_task_5_full_verification_graphify_update" + "source": "plans_2026_09_04_wallet_management_task_7_snapshot_endpoint_derived_portfolio_read_with_live_prices", + "target": "plans_2026_09_04_wallet_management_codeblock_26" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L49", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L993", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_1" + "source": "plans_2026_09_04_wallet_management_task_7_snapshot_endpoint_derived_portfolio_read_with_live_prices", + "target": "plans_2026_09_04_wallet_management_codeblock_27" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L88", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1013", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_2" + "source": "plans_2026_09_04_wallet_management_task_8_history_endpoint_paginated_lots_with_per_sell_realized_gain", + "target": "plans_2026_09_04_wallet_management_codeblock_28" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L118", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1062", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_3" + "source": "plans_2026_09_04_wallet_management_task_8_history_endpoint_paginated_lots_with_per_sell_realized_gain", + "target": "plans_2026_09_04_wallet_management_codeblock_29" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L131", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1095", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_4" + "source": "plans_2026_09_04_wallet_management_task_8_history_endpoint_paginated_lots_with_per_sell_realized_gain", + "target": "plans_2026_09_04_wallet_management_codeblock_30" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L177", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1108", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_5" + "source": "plans_2026_09_04_wallet_management_task_8_history_endpoint_paginated_lots_with_per_sell_realized_gain", + "target": "plans_2026_09_04_wallet_management_codeblock_31" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L228", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1143", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_6" + "source": "plans_2026_09_04_wallet_management_task_9_walletservice_wiring_quality_gate_full_suite_ruff_mypy_coverage", + "target": "plans_2026_09_04_wallet_management_codeblock_32" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L244", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1157", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_1_tickerpayloadcache_pre_materialize_per_ticker_payloads_at_refresh", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_7" + "source": "plans_2026_09_04_wallet_management_task_9_walletservice_wiring_quality_gate_full_suite_ruff_mypy_coverage", + "target": "plans_2026_09_04_wallet_management_codeblock_33" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L263", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1165", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_2_fast_paths_in_stocksquerymanager_for_default_shaped_queries", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_8" + "source": "plans_2026_09_04_wallet_management_task_9_walletservice_wiring_quality_gate_full_suite_ruff_mypy_coverage", + "target": "plans_2026_09_04_wallet_management_codeblock_34" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L315", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1192", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_2_fast_paths_in_stocksquerymanager_for_default_shaped_queries", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_9" + "source": "plans_2026_09_04_wallet_management_task_9_walletservice_wiring_quality_gate_full_suite_ruff_mypy_coverage", + "target": "plans_2026_09_04_wallet_management_codeblock_35" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L349", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1217", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_2_fast_paths_in_stocksquerymanager_for_default_shaped_queries", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_10" + "source": "plans_2026_09_04_wallet_management_task_9_walletservice_wiring_quality_gate_full_suite_ruff_mypy_coverage", + "target": "plans_2026_09_04_wallet_management_codeblock_36" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L405", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1237", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_3_convert_query_handlers_to_sync_def", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_11" + "source": "plans_2026_09_04_wallet_management_task_10_first_party_get_stocks_dividends_adjusted_docstring_fix", + "target": "plans_2026_09_04_wallet_management_codeblock_37" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L461", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1276", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_3_convert_query_handlers_to_sync_def", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_12" + "source": "plans_2026_09_04_wallet_management_task_10_first_party_get_stocks_dividends_adjusted_docstring_fix", + "target": "plans_2026_09_04_wallet_management_codeblock_38" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L482", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1299", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_13" + "source": "plans_2026_09_04_wallet_management_task_10_first_party_get_stocks_dividends_adjusted_docstring_fix", + "target": "plans_2026_09_04_wallet_management_codeblock_39" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L512", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1318", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_14" + "source": "plans_2026_09_04_wallet_management_task_10_first_party_get_stocks_dividends_adjusted_docstring_fix", + "target": "plans_2026_09_04_wallet_management_codeblock_40" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L519", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1341", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_15" + "source": "plans_2026_09_04_wallet_management_task_11_wallet_receipt_ledger_wallet_dividends_table_receipt_suggestion_endpoints", + "target": "plans_2026_09_04_wallet_management_codeblock_41" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L539", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1397", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_16" + "source": "plans_2026_09_04_wallet_management_task_11_wallet_receipt_ledger_wallet_dividends_table_receipt_suggestion_endpoints", + "target": "plans_2026_09_04_wallet_management_codeblock_42" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L548", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1419", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_17" + "source": "plans_2026_09_04_wallet_management_task_11_wallet_receipt_ledger_wallet_dividends_table_receipt_suggestion_endpoints", + "target": "plans_2026_09_04_wallet_management_codeblock_43" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-stocks-api-perf.md", - "source_location": "L606", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1452", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_stocks_api_perf_task_4_pre_parsed_cotation_date_index_replace_filtercotationcolumn_hot_path", - "target": "plans_2026_08_15_stocks_api_perf_codeblock_18" + "source": "plans_2026_09_04_wallet_management_task_11_wallet_receipt_ledger_wallet_dividends_table_receipt_suggestion_endpoints", + "target": "plans_2026_09_04_wallet_management_codeblock_44" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1475", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_08_15_workspace_endpoints_md", - "target": "plans_2026_08_15_workspace_endpoints_workspace_file_endpoints_agent_serve_file_tool_implementation_plan" + "source": "plans_2026_09_04_wallet_management_task_11_wallet_receipt_ledger_wallet_dividends_table_receipt_suggestion_endpoints", + "target": "plans_2026_09_04_wallet_management_codeblock_45" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L16", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1496", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_workspace_file_endpoints_agent_serve_file_tool_implementation_plan", - "target": "plans_2026_08_15_workspace_endpoints_global_constraints" + "source": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate", + "target": "plans_2026_09_04_wallet_management_codeblock_46" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L632", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1512", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_workspace_file_endpoints_agent_serve_file_tool_implementation_plan", - "target": "plans_2026_08_15_workspace_endpoints_self_review" + "source": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate", + "target": "plans_2026_09_04_wallet_management_codeblock_47" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L29", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1528", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_global_constraints", - "target": "plans_2026_08_15_workspace_endpoints_task_1_sandbox_delete_file_binary_write" + "source": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate", + "target": "plans_2026_09_04_wallet_management_codeblock_48" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L152", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1546", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_global_constraints", - "target": "plans_2026_08_15_workspace_endpoints_task_2_dependency_config_setting" + "source": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate", + "target": "plans_2026_09_04_wallet_management_codeblock_49" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L198", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1582", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_global_constraints", - "target": "plans_2026_08_15_workspace_endpoints_task_3_controller_endpoints" + "source": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate", + "target": "plans_2026_09_04_wallet_management_codeblock_50" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L465", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1613", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_global_constraints", - "target": "plans_2026_08_15_workspace_endpoints_task_4_serve_file_agent_tool" + "source": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate", + "target": "plans_2026_09_04_wallet_management_codeblock_51" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L611", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1635", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_global_constraints", - "target": "plans_2026_08_15_workspace_endpoints_task_5_full_verification" + "source": "plans_2026_09_04_wallet_management_task_13_corporate_actions_table_read_time_scaling_sobras_rule_definitive_full_gate", + "target": "plans_2026_09_04_wallet_management_codeblock_52" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L43", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1661", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_1_sandbox_delete_file_binary_write", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_1" + "source": "plans_2026_09_04_wallet_management_task_13_corporate_actions_table_read_time_scaling_sobras_rule_definitive_full_gate", + "target": "plans_2026_09_04_wallet_management_codeblock_53" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L108", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1686", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_1_sandbox_delete_file_binary_write", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_2" + "source": "plans_2026_09_04_wallet_management_task_13_corporate_actions_table_read_time_scaling_sobras_rule_definitive_full_gate", + "target": "plans_2026_09_04_wallet_management_codeblock_54" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L145", + "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", + "source_location": "L1727", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_1_sandbox_delete_file_binary_write", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_3" + "source": "plans_2026_09_04_wallet_management_task_13_corporate_actions_table_read_time_scaling_sobras_rule_definitive_full_gate", + "target": "plans_2026_09_04_wallet_management_codeblock_55" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L166", + "source_file": "docs/superpowers/plans/2026-09-12-artifact-removal-cache-verdict.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_2_dependency_config_setting", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_4" + "source": "docs_superpowers_plans_2026_09_12_artifact_removal_cache_verdict_md", + "target": "plans_2026_09_12_artifact_removal_cache_verdict_artifact_removal_matrix_cache_verdict_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L172", + "source_file": "docs/superpowers/plans/2026-09-12-artifact-removal-cache-verdict.md", + "source_location": "L3", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_2_dependency_config_setting", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_5" + "source": "plans_2026_09_12_artifact_removal_cache_verdict_artifact_removal_matrix_cache_verdict_plan", + "target": "plans_2026_09_12_artifact_removal_cache_verdict_part_1_deletions_safe_no_live_referrers" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L180", + "source_file": "docs/superpowers/plans/2026-09-12-artifact-removal-cache-verdict.md", + "source_location": "L25", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_2_dependency_config_setting", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_6" + "source": "plans_2026_09_12_artifact_removal_cache_verdict_artifact_removal_matrix_cache_verdict_plan", + "target": "plans_2026_09_12_artifact_removal_cache_verdict_part_2_cache_verdict_keep_the_dict_skip_cashews" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L191", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_2_dependency_config_setting", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_7" + "source": "docs_superpowers_plans_2026_09_14_memory_postgres_pgvector_plan_md", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_memory_postgres_pgvector_migration_implementation_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L212", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_3_controller_endpoints", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_8" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_memory_postgres_pgvector_migration_implementation_plan", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L368", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L24", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_3_controller_endpoints", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_9" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_global_constraints", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_task_1_pgvector_migration_backfill" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L375", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L79", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_3_controller_endpoints", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_10" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_global_constraints", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_task_2_delete_vector_py_rewrite_search" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L381", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L139", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_3_controller_endpoints", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_11" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_global_constraints", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_task_3_update_the_test_files" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L458", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L171", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_3_controller_endpoints", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_12" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_global_constraints", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_task_4_full_test_sweep_18_suites_postgres_ci_parity" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L479", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L185", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_4_serve_file_agent_tool", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_13" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_global_constraints", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_task_5_docs_close" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L560", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L35", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_4_serve_file_agent_tool", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_14" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_1_pgvector_migration_backfill", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L566", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L65", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_4_serve_file_agent_tool", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_15" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_1_pgvector_migration_backfill", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L593", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L74", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_4_serve_file_agent_tool", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_16" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_1_pgvector_migration_backfill", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L604", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L97", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_4_serve_file_agent_tool", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_17" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_2_delete_vector_py_rewrite_search", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-endpoints.md", - "source_location": "L626", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L134", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_endpoints_task_5_full_verification", - "target": "plans_2026_08_15_workspace_endpoints_codeblock_18" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_2_delete_vector_py_rewrite_search", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L148", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_08_15_workspace_frontend_md", - "target": "plans_2026_08_15_workspace_frontend_workspace_files_ui_promptbox_upload_implementation_plan" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_3_update_the_test_files", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L13", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L166", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_workspace_files_ui_promptbox_upload_implementation_plan", - "target": "plans_2026_08_15_workspace_frontend_backend_contract_source_of_truth_for_api_js" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_3_update_the_test_files", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L32", + "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", + "source_location": "L189", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_workspace_files_ui_promptbox_upload_implementation_plan", - "target": "plans_2026_08_15_workspace_frontend_global_constraints" + "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_5_docs_close", + "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L43", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_global_constraints", - "target": "plans_2026_08_15_workspace_frontend_task_1_api_layer_workspace_functions_in_src_api_js" + "source": "docs_superpowers_plans_2026_09_15_adopt_libs_md", + "target": "plans_2026_09_15_adopt_libs_adopt_libs_implementation_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L176", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_global_constraints", - "target": "plans_2026_08_15_workspace_frontend_task_2_settings_menu_workspace_files_grid_in_sessionsidebar" + "source": "plans_2026_09_15_adopt_libs_adopt_libs_implementation_plan", + "target": "plans_2026_09_15_adopt_libs_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L294", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L24", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_global_constraints", - "target": "plans_2026_08_15_workspace_frontend_task_3_drag_drop_file_upload_in_the_promptbox_inputbar_jsx" + "source": "plans_2026_09_15_adopt_libs_global_constraints", + "target": "plans_2026_09_15_adopt_libs_task_1_tenacity_replaces_bespoke_retries" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L403", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L56", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_global_constraints", - "target": "plans_2026_08_15_workspace_frontend_task_4_docker_restart_e2e_of_prometheus_chat_stream_performed_by_controller_not_a_subagent" + "source": "plans_2026_09_15_adopt_libs_global_constraints", + "target": "plans_2026_09_15_adopt_libs_task_2_cashews_native_probe_first" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L61", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L76", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_task_1_api_layer_workspace_functions_in_src_api_js", - "target": "plans_2026_08_15_workspace_frontend_codeblock_1" + "source": "plans_2026_09_15_adopt_libs_global_constraints", + "target": "plans_2026_09_15_adopt_libs_task_3_pydantic_validates_llm_extraction_json" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L122", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L102", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_task_1_api_layer_workspace_functions_in_src_api_js", - "target": "plans_2026_08_15_workspace_frontend_codeblock_2" + "source": "plans_2026_09_15_adopt_libs_global_constraints", + "target": "plans_2026_09_15_adopt_libs_task_4_sse_starlette_replaces_hand_sse_bus" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L169", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L117", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_task_1_api_layer_workspace_functions_in_src_api_js", - "target": "plans_2026_08_15_workspace_frontend_codeblock_3" + "source": "plans_2026_09_15_adopt_libs_global_constraints", + "target": "plans_2026_09_15_adopt_libs_task_5_rapidfuzz_memory_key_dedup" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L191", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L132", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_task_2_settings_menu_workspace_files_grid_in_sessionsidebar", - "target": "plans_2026_08_15_workspace_frontend_codeblock_4" + "source": "plans_2026_09_15_adopt_libs_global_constraints", + "target": "plans_2026_09_15_adopt_libs_task_6_cachetools_bounds_token_cache" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L246", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L143", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_task_2_settings_menu_workspace_files_grid_in_sessionsidebar", - "target": "plans_2026_08_15_workspace_frontend_codeblock_5" + "source": "plans_2026_09_15_adopt_libs_global_constraints", + "target": "plans_2026_09_15_adopt_libs_task_7_user_agents_fills_device_fields_optional" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L272", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L154", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_task_2_settings_menu_workspace_files_grid_in_sessionsidebar", - "target": "plans_2026_08_15_workspace_frontend_codeblock_6" + "source": "plans_2026_09_15_adopt_libs_global_constraints", + "target": "plans_2026_09_15_adopt_libs_task_8_pytest_plugin_set" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L287", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L38", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_task_2_settings_menu_workspace_files_grid_in_sessionsidebar", - "target": "plans_2026_08_15_workspace_frontend_codeblock_7" + "source": "plans_2026_09_15_adopt_libs_task_1_tenacity_replaces_bespoke_retries", + "target": "plans_2026_09_15_adopt_libs_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L308", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L51", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_task_3_drag_drop_file_upload_in_the_promptbox_inputbar_jsx", - "target": "plans_2026_08_15_workspace_frontend_codeblock_8" + "source": "plans_2026_09_15_adopt_libs_task_1_tenacity_replaces_bespoke_retries", + "target": "plans_2026_09_15_adopt_libs_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L372", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L72", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_task_3_drag_drop_file_upload_in_the_promptbox_inputbar_jsx", - "target": "plans_2026_08_15_workspace_frontend_codeblock_9" + "source": "plans_2026_09_15_adopt_libs_task_2_cashews_native_probe_first", + "target": "plans_2026_09_15_adopt_libs_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-15-workspace-frontend.md", - "source_location": "L396", + "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", + "source_location": "L88", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_15_workspace_frontend_task_3_drag_drop_file_upload_in_the_promptbox_inputbar_jsx", - "target": "plans_2026_08_15_workspace_frontend_codeblock_10" + "source": "plans_2026_09_15_adopt_libs_task_3_pydantic_validates_llm_extraction_json", + "target": "plans_2026_09_15_adopt_libs_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_08_17_openui_migration_md", - "target": "plans_2026_08_17_openui_migration_openui_migration_plan" + "source": "docs_superpowers_plans_2026_09_29_nginx_response_cache_md", + "target": "plans_2026_09_29_nginx_response_cache_nginx_response_cache_implementation_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L20", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L14", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_openui_migration_plan", - "target": "plans_2026_08_17_openui_migration_global_constraints" + "source": "plans_2026_09_29_nginx_response_cache_nginx_response_cache_implementation_plan", + "target": "plans_2026_09_29_nginx_response_cache_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L30", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L25", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_openui_migration_plan", - "target": "plans_2026_08_17_openui_migration_file_structure" + "source": "plans_2026_09_29_nginx_response_cache_nginx_response_cache_implementation_plan", + "target": "plans_2026_09_29_nginx_response_cache_review_focus_spec_implied_inputs_most_likely_to_bite" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L52", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L375", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_openui_migration_plan", - "target": "plans_2026_08_17_openui_migration_task_1_install_openui_remove_mdocui" + "source": "plans_2026_09_29_nginx_response_cache_nginx_response_cache_implementation_plan", + "target": "plans_2026_09_29_nginx_response_cache_execution_handoff" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L80", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L36", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_openui_migration_plan", - "target": "plans_2026_08_17_openui_migration_task_2_define_prometheus_component_library" + "source": "plans_2026_09_29_nginx_response_cache_review_focus_spec_implied_inputs_most_likely_to_bite", + "target": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L385", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L183", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_openui_migration_plan", - "target": "plans_2026_08_17_openui_migration_task_3_create_openui_renderer" + "source": "plans_2026_09_29_nginx_response_cache_review_focus_spec_implied_inputs_most_likely_to_bite", + "target": "plans_2026_09_29_nginx_response_cache_task_2_cached_locations_shared_proxy_snippet_mirrored_ttls" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L455", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L302", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_openui_migration_plan", - "target": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt" + "source": "plans_2026_09_29_nginx_response_cache_review_focus_spec_implied_inputs_most_likely_to_bite", + "target": "plans_2026_09_29_nginx_response_cache_task_3_measure_the_gil_relief_and_record_it" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L610", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L51", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_openui_migration_plan", - "target": "plans_2026_08_17_openui_migration_task_5_integration_test" + "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L640", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L62", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_openui_migration_plan", - "target": "plans_2026_08_17_openui_migration_verification_checklist" + "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L32", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L87", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_file_structure", - "target": "plans_2026_08_17_openui_migration_frontend_local_only_never_committed" + "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L43", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L101", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_file_structure", - "target": "plans_2026_08_17_openui_migration_backend_commit" + "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L58", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L116", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_1_install_openui_remove_mdocui", - "target": "plans_2026_08_17_openui_migration_codeblock_1" + "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L66", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L131", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_1_install_openui_remove_mdocui", - "target": "plans_2026_08_17_openui_migration_codeblock_2" + "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L72", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L152", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_1_install_openui_remove_mdocui", - "target": "plans_2026_08_17_openui_migration_codeblock_3" + "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L86", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L164", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_2_define_prometheus_component_library", - "target": "plans_2026_08_17_openui_migration_component_mapping" + "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L101", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L176", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_component_mapping", - "target": "plans_2026_08_17_openui_migration_codeblock_4" + "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L339", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L195", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_component_mapping", - "target": "plans_2026_08_17_openui_migration_codeblock_5" + "source": "plans_2026_09_29_nginx_response_cache_task_2_cached_locations_shared_proxy_snippet_mirrored_ttls", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L396", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L206", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_3_create_openui_renderer", - "target": "plans_2026_08_17_openui_migration_codeblock_6" + "source": "plans_2026_09_29_nginx_response_cache_task_2_cached_locations_shared_proxy_snippet_mirrored_ttls", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L428", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L246", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_3_create_openui_renderer", - "target": "plans_2026_08_17_openui_migration_codeblock_7" + "source": "plans_2026_09_29_nginx_response_cache_task_2_cached_locations_shared_proxy_snippet_mirrored_ttls", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L435", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L282", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_3_create_openui_renderer", - "target": "plans_2026_08_17_openui_migration_codeblock_8" + "source": "plans_2026_09_29_nginx_response_cache_task_2_cached_locations_shared_proxy_snippet_mirrored_ttls", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_13" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L442", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L295", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_3_create_openui_renderer", - "target": "plans_2026_08_17_openui_migration_codeblock_9" + "source": "plans_2026_09_29_nginx_response_cache_task_2_cached_locations_shared_proxy_snippet_mirrored_ttls", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_14" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L449", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L314", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_3_create_openui_renderer", - "target": "plans_2026_08_17_openui_migration_codeblock_10" + "source": "plans_2026_09_29_nginx_response_cache_task_3_measure_the_gil_relief_and_record_it", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_15" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L467", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L321", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", - "target": "plans_2026_08_17_openui_migration_codeblock_11" + "source": "plans_2026_09_29_nginx_response_cache_task_3_measure_the_gil_relief_and_record_it", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_16" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L486", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L333", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", - "target": "plans_2026_08_17_openui_migration_codeblock_12" + "source": "plans_2026_09_29_nginx_response_cache_task_3_measure_the_gil_relief_and_record_it", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_17" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L501", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L346", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", - "target": "plans_2026_08_17_openui_migration_codeblock_13" + "source": "plans_2026_09_29_nginx_response_cache_task_3_measure_the_gil_relief_and_record_it", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_18" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L542", + "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_location": "L367", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", - "target": "plans_2026_08_17_openui_migration_codeblock_14" + "source": "plans_2026_09_29_nginx_response_cache_task_3_measure_the_gil_relief_and_record_it", + "target": "plans_2026_09_29_nginx_response_cache_codeblock_19" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L555", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", - "target": "plans_2026_08_17_openui_migration_codeblock_15" + "source": "docs_superpowers_plans_2026_09_29_stocks_cache_ttl_md", + "target": "plans_2026_09_29_stocks_cache_ttl_stocks_api_cache_ttl_fields_cache_implementation_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L572", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", - "target": "plans_2026_08_17_openui_migration_codeblock_16" + "source": "plans_2026_09_29_stocks_cache_ttl_stocks_api_cache_ttl_fields_cache_implementation_plan", + "target": "plans_2026_09_29_stocks_cache_ttl_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L577", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L25", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", - "target": "plans_2026_08_17_openui_migration_codeblock_17" + "source": "plans_2026_09_29_stocks_cache_ttl_stocks_api_cache_ttl_fields_cache_implementation_plan", + "target": "plans_2026_09_29_stocks_cache_ttl_review_focus_spec_implied_inputs_most_likely_to_bite" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L590", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L410", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", - "target": "plans_2026_08_17_openui_migration_codeblock_18" + "source": "plans_2026_09_29_stocks_cache_ttl_stocks_api_cache_ttl_fields_cache_implementation_plan", + "target": "plans_2026_09_29_stocks_cache_ttl_execution_handoff" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L596", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L36", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", - "target": "plans_2026_08_17_openui_migration_codeblock_19" + "source": "plans_2026_09_29_stocks_cache_ttl_review_focus_spec_implied_inputs_most_likely_to_bite", + "target": "plans_2026_09_29_stocks_cache_ttl_task_1_ttl_constants_6h_on_the_three_data_routes_header_alignment" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L602", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L136", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_4_backend_system_prompt", - "target": "plans_2026_08_17_openui_migration_codeblock_20" + "source": "plans_2026_09_29_stocks_cache_ttl_review_focus_spec_implied_inputs_most_likely_to_bite", + "target": "plans_2026_09_29_stocks_cache_ttl_task_2_cache_stocks_fields" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L614", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L254", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_5_integration_test", - "target": "plans_2026_08_17_openui_migration_codeblock_21" + "source": "plans_2026_09_29_stocks_cache_ttl_review_focus_spec_implied_inputs_most_likely_to_bite", + "target": "plans_2026_09_29_stocks_cache_ttl_task_3_invalidate_the_endpoint_cache_on_feather_reload" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-08-17-openui-migration.md", - "source_location": "L620", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L340", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_08_17_openui_migration_task_5_integration_test", - "target": "plans_2026_08_17_openui_migration_codeblock_22" + "source": "plans_2026_09_29_stocks_cache_ttl_review_focus_spec_implied_inputs_most_likely_to_bite", + "target": "plans_2026_09_29_stocks_cache_ttl_task_4_measure_the_6h_window_rss_and_record_the_verdict" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L50", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_09_03_followup_hardening_md", - "target": "plans_2026_09_03_followup_hardening_follow_up_hardening_implementation_plan" + "source": "plans_2026_09_29_stocks_cache_ttl_task_1_ttl_constants_6h_on_the_three_data_routes_header_alignment", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L13", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L91", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_follow_up_hardening_implementation_plan", - "target": "plans_2026_09_03_followup_hardening_global_constraints" + "source": "plans_2026_09_29_stocks_cache_ttl_task_1_ttl_constants_6h_on_the_three_data_routes_header_alignment", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L26", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L103", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_follow_up_hardening_implementation_plan", - "target": "plans_2026_09_03_followup_hardening_file_map" + "source": "plans_2026_09_29_stocks_cache_ttl_task_1_ttl_constants_6h_on_the_three_data_routes_header_alignment", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L814", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L112", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_follow_up_hardening_implementation_plan", - "target": "plans_2026_09_03_followup_hardening_self_review" + "source": "plans_2026_09_29_stocks_cache_ttl_task_1_ttl_constants_6h_on_the_three_data_routes_header_alignment", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L44", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L129", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_file_map", - "target": "plans_2026_09_03_followup_hardening_task_1_thoth_maat_permission_decision" + "source": "plans_2026_09_29_stocks_cache_ttl_task_1_ttl_constants_6h_on_the_three_data_routes_header_alignment", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L127", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L152", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_file_map", - "target": "plans_2026_09_03_followup_hardening_task_2_p6_redis_cashews_insertion_behind_existing_sync_cache" + "source": "plans_2026_09_29_stocks_cache_ttl_task_2_cache_stocks_fields", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L240", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L165", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_file_map", - "target": "plans_2026_09_03_followup_hardening_task_3_zstd_hot_path_rework_via_feather_to_dict_zstd_migration" + "source": "plans_2026_09_29_stocks_cache_ttl_task_2_cache_stocks_fields", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L337", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L220", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_file_map", - "target": "plans_2026_09_03_followup_hardening_task_4_queryhistorical_queryfundamental_presort_invariant_guard" + "source": "plans_2026_09_29_stocks_cache_ttl_task_2_cache_stocks_fields", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L415", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L228", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_file_map", - "target": "plans_2026_09_03_followup_hardening_task_5_history_backfill_dedup_indices_as_logging_only" + "source": "plans_2026_09_29_stocks_cache_ttl_task_2_cache_stocks_fields", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L509", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L247", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_file_map", - "target": "plans_2026_09_03_followup_hardening_task_6_stocks_api_limiter_design_design_only_do_not_enable" + "source": "plans_2026_09_29_stocks_cache_ttl_task_2_cache_stocks_fields", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L562", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L269", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_file_map", - "target": "plans_2026_09_03_followup_hardening_task_7_remove_temporary_run_py_scraper_debug_endpoint" + "source": "plans_2026_09_29_stocks_cache_ttl_task_3_invalidate_the_endpoint_cache_on_feather_reload", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L623", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L301", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_file_map", - "target": "plans_2026_09_03_followup_hardening_task_8_fix_20_pre_existing_environmental_failures" + "source": "plans_2026_09_29_stocks_cache_ttl_task_3_invalidate_the_endpoint_cache_on_feather_reload", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L712", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L311", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_file_map", - "target": "plans_2026_09_03_followup_hardening_task_9_session_refresh_token_rotation_follow_up" + "source": "plans_2026_09_29_stocks_cache_ttl_task_3_invalidate_the_endpoint_cache_on_feather_reload", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_13" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L61", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L333", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_1_thoth_maat_permission_decision", - "target": "plans_2026_09_03_followup_hardening_codeblock_1" + "source": "plans_2026_09_29_stocks_cache_ttl_task_3_invalidate_the_endpoint_cache_on_feather_reload", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_14" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L80", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L352", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_1_thoth_maat_permission_decision", - "target": "plans_2026_09_03_followup_hardening_codeblock_2" + "source": "plans_2026_09_29_stocks_cache_ttl_task_4_measure_the_6h_window_rss_and_record_the_verdict", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_15" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L96", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L363", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_1_thoth_maat_permission_decision", - "target": "plans_2026_09_03_followup_hardening_codeblock_3" + "source": "plans_2026_09_29_stocks_cache_ttl_task_4_measure_the_6h_window_rss_and_record_the_verdict", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_16" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L120", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L376", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_1_thoth_maat_permission_decision", - "target": "plans_2026_09_03_followup_hardening_codeblock_4" + "source": "plans_2026_09_29_stocks_cache_ttl_task_4_measure_the_6h_window_rss_and_record_the_verdict", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_17" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L143", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L384", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_2_p6_redis_cashews_insertion_behind_existing_sync_cache", - "target": "plans_2026_09_03_followup_hardening_codeblock_5" + "source": "plans_2026_09_29_stocks_cache_ttl_task_4_measure_the_6h_window_rss_and_record_the_verdict", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_18" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L185", + "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", + "source_location": "L402", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_2_p6_redis_cashews_insertion_behind_existing_sync_cache", - "target": "plans_2026_09_03_followup_hardening_codeblock_6" + "source": "plans_2026_09_29_stocks_cache_ttl_task_4_measure_the_6h_window_rss_and_record_the_verdict", + "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_19" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L198", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_2_p6_redis_cashews_insertion_behind_existing_sync_cache", - "target": "plans_2026_09_03_followup_hardening_codeblock_7" + "source": "docs_superpowers_plans_2026_09_29_uvicorn_worker_scaling_md", + "target": "plans_2026_09_29_uvicorn_worker_scaling_uvicorn_fastapi_worker_scaling_implementation_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L204", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_2_p6_redis_cashews_insertion_behind_existing_sync_cache", - "target": "plans_2026_09_03_followup_hardening_codeblock_8" + "source": "plans_2026_09_29_uvicorn_worker_scaling_uvicorn_fastapi_worker_scaling_implementation_plan", + "target": "plans_2026_09_29_uvicorn_worker_scaling_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L233", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L23", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_2_p6_redis_cashews_insertion_behind_existing_sync_cache", - "target": "plans_2026_09_03_followup_hardening_codeblock_9" + "source": "plans_2026_09_29_uvicorn_worker_scaling_uvicorn_fastapi_worker_scaling_implementation_plan", + "target": "plans_2026_09_29_uvicorn_worker_scaling_review_focus" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L256", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L725", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_3_zstd_hot_path_rework_via_feather_to_dict_zstd_migration", - "target": "plans_2026_09_03_followup_hardening_codeblock_10" + "source": "plans_2026_09_29_uvicorn_worker_scaling_uvicorn_fastapi_worker_scaling_implementation_plan", + "target": "plans_2026_09_29_uvicorn_worker_scaling_self_review" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L284", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L35", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_3_zstd_hot_path_rework_via_feather_to_dict_zstd_migration", - "target": "plans_2026_09_03_followup_hardening_codeblock_11" + "source": "plans_2026_09_29_uvicorn_worker_scaling_review_focus", + "target": "plans_2026_09_29_uvicorn_worker_scaling_task_1_measure_the_concurrency_ceiling_and_record_the_decision" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L298", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L170", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_3_zstd_hot_path_rework_via_feather_to_dict_zstd_migration", - "target": "plans_2026_09_03_followup_hardening_codeblock_12" + "source": "plans_2026_09_29_uvicorn_worker_scaling_review_focus", + "target": "plans_2026_09_29_uvicorn_worker_scaling_task_2_load_the_cache_on_the_build_loser_path" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L330", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L292", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_3_zstd_hot_path_rework_via_feather_to_dict_zstd_migration", - "target": "plans_2026_09_03_followup_hardening_codeblock_13" + "source": "plans_2026_09_29_uvicorn_worker_scaling_review_focus", + "target": "plans_2026_09_29_uvicorn_worker_scaling_task_3_run_migrations_exactly_once_per_deploy" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L351", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L365", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_4_queryhistorical_queryfundamental_presort_invariant_guard", - "target": "plans_2026_09_03_followup_hardening_codeblock_14" + "source": "plans_2026_09_29_uvicorn_worker_scaling_review_focus", + "target": "plans_2026_09_29_uvicorn_worker_scaling_task_4_size_database_pools_by_process_count" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L390", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L431", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_4_queryhistorical_queryfundamental_presort_invariant_guard", - "target": "plans_2026_09_03_followup_hardening_codeblock_15" + "source": "plans_2026_09_29_uvicorn_worker_scaling_review_focus", + "target": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L408", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L654", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_4_queryhistorical_queryfundamental_presort_invariant_guard", - "target": "plans_2026_09_03_followup_hardening_codeblock_16" + "source": "plans_2026_09_29_uvicorn_worker_scaling_review_focus", + "target": "plans_2026_09_29_uvicorn_worker_scaling_task_6_verify_the_fleet_single_build_one_migration_shared_frame" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L429", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L47", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_5_history_backfill_dedup_indices_as_logging_only", - "target": "plans_2026_09_03_followup_hardening_codeblock_17" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_1_measure_the_concurrency_ceiling_and_record_the_decision", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L451", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L145", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_5_history_backfill_dedup_indices_as_logging_only", - "target": "plans_2026_09_03_followup_hardening_codeblock_18" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_1_measure_the_concurrency_ceiling_and_record_the_decision", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L502", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L158", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_5_history_backfill_dedup_indices_as_logging_only", - "target": "plans_2026_09_03_followup_hardening_codeblock_19" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_1_measure_the_concurrency_ceiling_and_record_the_decision", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L525", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L182", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_6_stocks_api_limiter_design_design_only_do_not_enable", - "target": "plans_2026_09_03_followup_hardening_codeblock_20" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_2_load_the_cache_on_the_build_loser_path", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L541", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L228", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_6_stocks_api_limiter_design_design_only_do_not_enable", - "target": "plans_2026_09_03_followup_hardening_codeblock_21" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_2_load_the_cache_on_the_build_loser_path", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L555", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L244", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_6_stocks_api_limiter_design_design_only_do_not_enable", - "target": "plans_2026_09_03_followup_hardening_codeblock_22" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_2_load_the_cache_on_the_build_loser_path", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L577", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L285", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_7_remove_temporary_run_py_scraper_debug_endpoint", - "target": "plans_2026_09_03_followup_hardening_codeblock_23" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_2_load_the_cache_on_the_build_loser_path", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L598", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L304", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_7_remove_temporary_run_py_scraper_debug_endpoint", - "target": "plans_2026_09_03_followup_hardening_codeblock_24" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_3_run_migrations_exactly_once_per_deploy", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L616", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L333", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_7_remove_temporary_run_py_scraper_debug_endpoint", - "target": "plans_2026_09_03_followup_hardening_codeblock_25" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_3_run_migrations_exactly_once_per_deploy", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L640", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L358", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_8_fix_20_pre_existing_environmental_failures", - "target": "plans_2026_09_03_followup_hardening_codeblock_26" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_3_run_migrations_exactly_once_per_deploy", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L668", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L377", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_8_fix_20_pre_existing_environmental_failures", - "target": "plans_2026_09_03_followup_hardening_codeblock_27" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_4_size_database_pools_by_process_count", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L676", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L407", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_8_fix_20_pre_existing_environmental_failures", - "target": "plans_2026_09_03_followup_hardening_codeblock_28" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_4_size_database_pools_by_process_count", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L705", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L424", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_8_fix_20_pre_existing_environmental_failures", - "target": "plans_2026_09_03_followup_hardening_codeblock_29" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_4_size_database_pools_by_process_count", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_13" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L731", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L444", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_9_session_refresh_token_rotation_follow_up", - "target": "plans_2026_09_03_followup_hardening_codeblock_30" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_14" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L753", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L476", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_9_session_refresh_token_rotation_follow_up", - "target": "plans_2026_09_03_followup_hardening_codeblock_31" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_15" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L769", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L483", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_9_session_refresh_token_rotation_follow_up", - "target": "plans_2026_09_03_followup_hardening_codeblock_32" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_16" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L780", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L494", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_9_session_refresh_token_rotation_follow_up", - "target": "plans_2026_09_03_followup_hardening_codeblock_33" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_17" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-03-followup-hardening.md", - "source_location": "L807", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L618", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_03_followup_hardening_task_9_session_refresh_token_rotation_follow_up", - "target": "plans_2026_09_03_followup_hardening_codeblock_34" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_18" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L647", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_09_04_wallet_management_md", - "target": "plans_2026_09_04_wallet_management_wallet_management_thoth_iyagba_implementation_plan" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_19" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L13", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L666", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_wallet_management_thoth_iyagba_implementation_plan", - "target": "plans_2026_09_04_wallet_management_global_constraints" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_6_verify_the_fleet_single_build_one_migration_shared_frame", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_20" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L35", + "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", + "source_location": "L718", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_wallet_management_thoth_iyagba_implementation_plan", - "target": "plans_2026_09_04_wallet_management_file_structure" + "source": "plans_2026_09_29_uvicorn_worker_scaling_task_6_verify_the_fleet_single_build_one_migration_shared_frame", + "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_21" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L60", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_file_structure", - "target": "plans_2026_09_04_wallet_management_task_1_wallet_models_and_user_relationship" + "source": "docs_superpowers_plans_2026_09_29_zerocopy_stocks_cache_md", + "target": "plans_2026_09_29_zerocopy_stocks_cache_zero_copy_memory_mapped_stocks_cache_implementation_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L166", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_file_structure", - "target": "plans_2026_09_04_wallet_management_task_2_alembic_migration_for_wallet_tables" + "source": "plans_2026_09_29_zerocopy_stocks_cache_zero_copy_memory_mapped_stocks_cache_implementation_plan", + "target": "plans_2026_09_29_zerocopy_stocks_cache_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L269", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L23", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_file_structure", - "target": "plans_2026_09_04_wallet_management_task_3_pure_derivation_math" + "source": "plans_2026_09_29_zerocopy_stocks_cache_zero_copy_memory_mapped_stocks_cache_implementation_plan", + "target": "plans_2026_09_29_zerocopy_stocks_cache_review_focus_spec_implied_inputs_most_likely_to_bite" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L391", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L353", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_file_structure", - "target": "plans_2026_09_04_wallet_management_task_4_holding_endpoints_create_holding_and_retarget_weight" + "source": "plans_2026_09_29_zerocopy_stocks_cache_zero_copy_memory_mapped_stocks_cache_implementation_plan", + "target": "plans_2026_09_29_zerocopy_stocks_cache_execution_handoff" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L567", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L33", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_file_structure", - "target": "plans_2026_09_04_wallet_management_task_5_lot_endpoint_append_immutable_buy_sell_lots" + "source": "plans_2026_09_29_zerocopy_stocks_cache_review_focus_spec_implied_inputs_most_likely_to_bite", + "target": "plans_2026_09_29_zerocopy_stocks_cache_task_1_presort_at_build_time_order_by_b3_presorted_marker" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L720", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L125", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_file_structure", - "target": "plans_2026_09_04_wallet_management_task_6_price_client_one_batched_stocks_api_fetch_per_snapshot" + "source": "plans_2026_09_29_zerocopy_stocks_cache_review_focus_spec_implied_inputs_most_likely_to_bite", + "target": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L869", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L292", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_file_structure", - "target": "plans_2026_09_04_wallet_management_task_7_snapshot_endpoint_derived_portfolio_read_with_live_prices" + "source": "plans_2026_09_29_zerocopy_stocks_cache_review_focus_spec_implied_inputs_most_likely_to_bite", + "target": "plans_2026_09_29_zerocopy_stocks_cache_task_3_arrowdtype_aware_json_column_decompression_query_py_guard" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1000", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L47", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_file_structure", - "target": "plans_2026_09_04_wallet_management_task_8_history_endpoint_paginated_lots_with_per_sell_realized_gain" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_1_presort_at_build_time_order_by_b3_presorted_marker", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1115", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L93", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_file_structure", - "target": "plans_2026_09_04_wallet_management_task_9_walletservice_wiring_quality_gate_full_suite_ruff_mypy_coverage" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_1_presort_at_build_time_order_by_b3_presorted_marker", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1224", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L101", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_file_structure", - "target": "plans_2026_09_04_wallet_management_task_10_first_party_get_stocks_dividends_adjusted_docstring_fix" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_1_presort_at_build_time_order_by_b3_presorted_marker", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1325", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L107", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_file_structure", - "target": "plans_2026_09_04_wallet_management_task_11_wallet_receipt_ledger_wallet_dividends_table_receipt_suggestion_endpoints" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_1_presort_at_build_time_order_by_b3_presorted_marker", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1482", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L118", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_file_structure", - "target": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_1_presort_at_build_time_order_by_b3_presorted_marker", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1618", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L142", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_file_structure", - "target": "plans_2026_09_04_wallet_management_task_13_corporate_actions_table_read_time_scaling_sobras_rule_definitive_full_gate" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L73", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L148", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_1_wallet_models_and_user_relationship", - "target": "plans_2026_09_04_wallet_management_codeblock_1" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L101", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L152", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_1_wallet_models_and_user_relationship", - "target": "plans_2026_09_04_wallet_management_codeblock_2" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L138", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L159", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_1_wallet_models_and_user_relationship", - "target": "plans_2026_09_04_wallet_management_codeblock_3" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L144", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L165", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_1_wallet_models_and_user_relationship", - "target": "plans_2026_09_04_wallet_management_codeblock_4" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L159", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L250", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_1_wallet_models_and_user_relationship", - "target": "plans_2026_09_04_wallet_management_codeblock_5" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L189", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L256", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_2_alembic_migration_for_wallet_tables", - "target": "plans_2026_09_04_wallet_management_codeblock_6" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L248", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L268", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_2_alembic_migration_for_wallet_tables", - "target": "plans_2026_09_04_wallet_management_codeblock_7" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_13" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L262", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L285", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_2_alembic_migration_for_wallet_tables", - "target": "plans_2026_09_04_wallet_management_codeblock_8" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_14" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L281", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L306", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_3_pure_derivation_math", - "target": "plans_2026_09_04_wallet_management_codeblock_9" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_3_arrowdtype_aware_json_column_decompression_query_py_guard", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_15" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L325", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L327", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_3_pure_derivation_math", - "target": "plans_2026_09_04_wallet_management_codeblock_10" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_3_arrowdtype_aware_json_column_decompression_query_py_guard", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_16" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L384", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L331", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_3_pure_derivation_math", - "target": "plans_2026_09_04_wallet_management_codeblock_11" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_3_arrowdtype_aware_json_column_decompression_query_py_guard", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_17" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L404", + "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", + "source_location": "L346", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_4_holding_endpoints_create_holding_and_retarget_weight", - "target": "plans_2026_09_04_wallet_management_codeblock_12" + "source": "plans_2026_09_29_zerocopy_stocks_cache_task_3_arrowdtype_aware_json_column_decompression_query_py_guard", + "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_18" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L471", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_4_holding_endpoints_create_holding_and_retarget_weight", - "target": "plans_2026_09_04_wallet_management_codeblock_13" + "source": "docs_superpowers_plans_2026_09_30_wallet_p1_md", + "target": "plans_2026_09_30_wallet_p1_mansa_wallet_implementation_plan_p1_p2_p3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L524", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_4_holding_endpoints_create_holding_and_retarget_weight", - "target": "plans_2026_09_04_wallet_management_codeblock_14" + "source": "plans_2026_09_30_wallet_p1_mansa_wallet_implementation_plan_p1_p2_p3", + "target": "plans_2026_09_30_wallet_p1_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L560", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L29", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_4_holding_endpoints_create_holding_and_retarget_weight", - "target": "plans_2026_09_04_wallet_management_codeblock_15" + "source": "plans_2026_09_30_wallet_p1_mansa_wallet_implementation_plan_p1_p2_p3", + "target": "plans_2026_09_30_wallet_p1_review_focus" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L580", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1060", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_5_lot_endpoint_append_immutable_buy_sell_lots", - "target": "plans_2026_09_04_wallet_management_codeblock_16" + "source": "plans_2026_09_30_wallet_p1_mansa_wallet_implementation_plan_p1_p2_p3", + "target": "plans_2026_09_30_wallet_p1_goal_2_p2_earnings_performance_starts_only_after_goal_1_complete" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L649", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1304", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_5_lot_endpoint_append_immutable_buy_sell_lots", - "target": "plans_2026_09_04_wallet_management_codeblock_17" + "source": "plans_2026_09_30_wallet_p1_mansa_wallet_implementation_plan_p1_p2_p3", + "target": "plans_2026_09_30_wallet_p1_goal_3_p3_assist_narration_starts_only_after_goal_2_complete" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L659", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L43", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_5_lot_endpoint_append_immutable_buy_sell_lots", - "target": "plans_2026_09_04_wallet_management_codeblock_18" + "source": "plans_2026_09_30_wallet_p1_review_focus", + "target": "plans_2026_09_30_wallet_p1_task_1_permission_wallet_on_the_base_role_ripple_fixes" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L693", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L131", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_5_lot_endpoint_append_immutable_buy_sell_lots", - "target": "plans_2026_09_04_wallet_management_codeblock_19" + "source": "plans_2026_09_30_wallet_p1_review_focus", + "target": "plans_2026_09_30_wallet_p1_task_2_wallet_orm_models_5_tables_user_db" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L713", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L265", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_5_lot_endpoint_append_immutable_buy_sell_lots", - "target": "plans_2026_09_04_wallet_management_codeblock_20" + "source": "plans_2026_09_30_wallet_p1_review_focus", + "target": "plans_2026_09_30_wallet_p1_task_3_alembic_revision_for_the_wallet_tables_needs_mysql" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L732", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L316", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_6_price_client_one_batched_stocks_api_fetch_per_snapshot", - "target": "plans_2026_09_04_wallet_management_codeblock_21" + "source": "plans_2026_09_30_wallet_p1_review_focus", + "target": "plans_2026_09_30_wallet_p1_task_4_wallet_auth_dependency_introspect_contract_raw_token_resolver" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L804", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L452", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_6_price_client_one_batched_stocks_api_fetch_per_snapshot", - "target": "plans_2026_09_04_wallet_management_codeblock_22" + "source": "plans_2026_09_30_wallet_p1_review_focus", + "target": "plans_2026_09_30_wallet_p1_task_5_wallets_crud_mount_make_wallet_client" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L862", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L627", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_6_price_client_one_batched_stocks_api_fetch_per_snapshot", - "target": "plans_2026_09_04_wallet_management_codeblock_23" + "source": "plans_2026_09_30_wallet_p1_review_focus", + "target": "plans_2026_09_30_wallet_p1_task_6_entries_ledger_holdings_recalc_avg_price_engine" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L882", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L789", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_7_snapshot_endpoint_derived_portfolio_read_with_live_prices", - "target": "plans_2026_09_04_wallet_management_codeblock_24" + "source": "plans_2026_09_30_wallet_p1_review_focus", + "target": "plans_2026_09_30_wallet_p1_task_7_positions_live_price_join_over_http" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L944", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L964", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_7_snapshot_endpoint_derived_portfolio_read_with_live_prices", - "target": "plans_2026_09_04_wallet_management_codeblock_25" + "source": "plans_2026_09_30_wallet_p1_review_focus", + "target": "plans_2026_09_30_wallet_p1_task_8_summary_snapshots_allocation_targets_ratings" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L972", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1029", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_7_snapshot_endpoint_derived_portfolio_read_with_live_prices", - "target": "plans_2026_09_04_wallet_management_codeblock_26" + "source": "plans_2026_09_30_wallet_p1_review_focus", + "target": "plans_2026_09_30_wallet_p1_task_9_full_gate_ci_ps1_green_coverage_fallout" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L993", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L60", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_7_snapshot_endpoint_derived_portfolio_read_with_live_prices", - "target": "plans_2026_09_04_wallet_management_codeblock_27" + "source": "plans_2026_09_30_wallet_p1_task_1_permission_wallet_on_the_base_role_ripple_fixes", + "target": "plans_2026_09_30_wallet_p1_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1013", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L93", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_8_history_endpoint_paginated_lots_with_per_sell_realized_gain", - "target": "plans_2026_09_04_wallet_management_codeblock_28" + "source": "plans_2026_09_30_wallet_p1_task_1_permission_wallet_on_the_base_role_ripple_fixes", + "target": "plans_2026_09_30_wallet_p1_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1062", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L115", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_8_history_endpoint_paginated_lots_with_per_sell_realized_gain", - "target": "plans_2026_09_04_wallet_management_codeblock_29" + "source": "plans_2026_09_30_wallet_p1_task_1_permission_wallet_on_the_base_role_ripple_fixes", + "target": "plans_2026_09_30_wallet_p1_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1095", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L124", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_8_history_endpoint_paginated_lots_with_per_sell_realized_gain", - "target": "plans_2026_09_04_wallet_management_codeblock_30" + "source": "plans_2026_09_30_wallet_p1_task_1_permission_wallet_on_the_base_role_ripple_fixes", + "target": "plans_2026_09_30_wallet_p1_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1108", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L143", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_8_history_endpoint_paginated_lots_with_per_sell_realized_gain", - "target": "plans_2026_09_04_wallet_management_codeblock_31" + "source": "plans_2026_09_30_wallet_p1_task_2_wallet_orm_models_5_tables_user_db", + "target": "plans_2026_09_30_wallet_p1_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1143", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L172", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_9_walletservice_wiring_quality_gate_full_suite_ruff_mypy_coverage", - "target": "plans_2026_09_04_wallet_management_codeblock_32" + "source": "plans_2026_09_30_wallet_p1_task_2_wallet_orm_models_5_tables_user_db", + "target": "plans_2026_09_30_wallet_p1_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1157", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L258", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_9_walletservice_wiring_quality_gate_full_suite_ruff_mypy_coverage", - "target": "plans_2026_09_04_wallet_management_codeblock_33" + "source": "plans_2026_09_30_wallet_p1_task_2_wallet_orm_models_5_tables_user_db", + "target": "plans_2026_09_30_wallet_p1_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1165", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L282", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_9_walletservice_wiring_quality_gate_full_suite_ruff_mypy_coverage", - "target": "plans_2026_09_04_wallet_management_codeblock_34" + "source": "plans_2026_09_30_wallet_p1_task_3_alembic_revision_for_the_wallet_tables_needs_mysql", + "target": "plans_2026_09_30_wallet_p1_codeblock_8" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1192", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L309", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_9_walletservice_wiring_quality_gate_full_suite_ruff_mypy_coverage", - "target": "plans_2026_09_04_wallet_management_codeblock_35" + "source": "plans_2026_09_30_wallet_p1_task_3_alembic_revision_for_the_wallet_tables_needs_mysql", + "target": "plans_2026_09_30_wallet_p1_codeblock_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1217", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L328", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_9_walletservice_wiring_quality_gate_full_suite_ruff_mypy_coverage", - "target": "plans_2026_09_04_wallet_management_codeblock_36" + "source": "plans_2026_09_30_wallet_p1_task_4_wallet_auth_dependency_introspect_contract_raw_token_resolver", + "target": "plans_2026_09_30_wallet_p1_codeblock_10" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1237", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L395", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_10_first_party_get_stocks_dividends_adjusted_docstring_fix", - "target": "plans_2026_09_04_wallet_management_codeblock_37" + "source": "plans_2026_09_30_wallet_p1_task_4_wallet_auth_dependency_introspect_contract_raw_token_resolver", + "target": "plans_2026_09_30_wallet_p1_codeblock_11" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1276", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L445", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_10_first_party_get_stocks_dividends_adjusted_docstring_fix", - "target": "plans_2026_09_04_wallet_management_codeblock_38" + "source": "plans_2026_09_30_wallet_p1_task_4_wallet_auth_dependency_introspect_contract_raw_token_resolver", + "target": "plans_2026_09_30_wallet_p1_codeblock_12" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1299", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L467", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_10_first_party_get_stocks_dividends_adjusted_docstring_fix", - "target": "plans_2026_09_04_wallet_management_codeblock_39" + "source": "plans_2026_09_30_wallet_p1_task_5_wallets_crud_mount_make_wallet_client", + "target": "plans_2026_09_30_wallet_p1_codeblock_13" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1318", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L491", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_10_first_party_get_stocks_dividends_adjusted_docstring_fix", - "target": "plans_2026_09_04_wallet_management_codeblock_40" + "source": "plans_2026_09_30_wallet_p1_task_5_wallets_crud_mount_make_wallet_client", + "target": "plans_2026_09_30_wallet_p1_codeblock_14" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1341", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L515", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_11_wallet_receipt_ledger_wallet_dividends_table_receipt_suggestion_endpoints", - "target": "plans_2026_09_04_wallet_management_codeblock_41" + "source": "plans_2026_09_30_wallet_p1_task_5_wallets_crud_mount_make_wallet_client", + "target": "plans_2026_09_30_wallet_p1_codeblock_15" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1397", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L553", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_11_wallet_receipt_ledger_wallet_dividends_table_receipt_suggestion_endpoints", - "target": "plans_2026_09_04_wallet_management_codeblock_42" + "source": "plans_2026_09_30_wallet_p1_task_5_wallets_crud_mount_make_wallet_client", + "target": "plans_2026_09_30_wallet_p1_codeblock_16" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1419", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L573", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_11_wallet_receipt_ledger_wallet_dividends_table_receipt_suggestion_endpoints", - "target": "plans_2026_09_04_wallet_management_codeblock_43" + "source": "plans_2026_09_30_wallet_p1_task_5_wallets_crud_mount_make_wallet_client", + "target": "plans_2026_09_30_wallet_p1_codeblock_17" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1452", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L620", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_11_wallet_receipt_ledger_wallet_dividends_table_receipt_suggestion_endpoints", - "target": "plans_2026_09_04_wallet_management_codeblock_44" + "source": "plans_2026_09_30_wallet_p1_task_5_wallets_crud_mount_make_wallet_client", + "target": "plans_2026_09_30_wallet_p1_codeblock_18" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1475", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L642", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_11_wallet_receipt_ledger_wallet_dividends_table_receipt_suggestion_endpoints", - "target": "plans_2026_09_04_wallet_management_codeblock_45" + "source": "plans_2026_09_30_wallet_p1_task_6_entries_ledger_holdings_recalc_avg_price_engine", + "target": "plans_2026_09_30_wallet_p1_codeblock_19" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1496", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L691", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate", - "target": "plans_2026_09_04_wallet_management_codeblock_46" + "source": "plans_2026_09_30_wallet_p1_task_6_entries_ledger_holdings_recalc_avg_price_engine", + "target": "plans_2026_09_30_wallet_p1_codeblock_20" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1512", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L782", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate", - "target": "plans_2026_09_04_wallet_management_codeblock_47" + "source": "plans_2026_09_30_wallet_p1_task_6_entries_ledger_holdings_recalc_avg_price_engine", + "target": "plans_2026_09_30_wallet_p1_codeblock_21" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1528", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L804", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate", - "target": "plans_2026_09_04_wallet_management_codeblock_48" + "source": "plans_2026_09_30_wallet_p1_task_7_positions_live_price_join_over_http", + "target": "plans_2026_09_30_wallet_p1_codeblock_22" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1546", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L888", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate", - "target": "plans_2026_09_04_wallet_management_codeblock_49" + "source": "plans_2026_09_30_wallet_p1_task_7_positions_live_price_join_over_http", + "target": "plans_2026_09_30_wallet_p1_codeblock_23" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1582", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L926", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate", - "target": "plans_2026_09_04_wallet_management_codeblock_50" + "source": "plans_2026_09_30_wallet_p1_task_7_positions_live_price_join_over_http", + "target": "plans_2026_09_30_wallet_p1_codeblock_24" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1613", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L957", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_12_split_cliff_regression_test_snapshot_history_dividend_extension_final_gate", - "target": "plans_2026_09_04_wallet_management_codeblock_51" + "source": "plans_2026_09_30_wallet_p1_task_7_positions_live_price_join_over_http", + "target": "plans_2026_09_30_wallet_p1_codeblock_25" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1635", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L979", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_13_corporate_actions_table_read_time_scaling_sobras_rule_definitive_full_gate", - "target": "plans_2026_09_04_wallet_management_codeblock_52" + "source": "plans_2026_09_30_wallet_p1_task_8_summary_snapshots_allocation_targets_ratings", + "target": "plans_2026_09_30_wallet_p1_codeblock_26" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1661", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1022", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_13_corporate_actions_table_read_time_scaling_sobras_rule_definitive_full_gate", - "target": "plans_2026_09_04_wallet_management_codeblock_53" + "source": "plans_2026_09_30_wallet_p1_task_8_summary_snapshots_allocation_targets_ratings", + "target": "plans_2026_09_30_wallet_p1_codeblock_27" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1686", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1051", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_13_corporate_actions_table_read_time_scaling_sobras_rule_definitive_full_gate", - "target": "plans_2026_09_04_wallet_management_codeblock_54" + "source": "plans_2026_09_30_wallet_p1_task_9_full_gate_ci_ps1_green_coverage_fallout", + "target": "plans_2026_09_30_wallet_p1_codeblock_28" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", - "source_location": "L1727", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1064", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_04_wallet_management_task_13_corporate_actions_table_read_time_scaling_sobras_rule_definitive_full_gate", - "target": "plans_2026_09_04_wallet_management_codeblock_55" + "source": "plans_2026_09_30_wallet_p1_goal_2_p2_earnings_performance_starts_only_after_goal_1_complete", + "target": "plans_2026_09_30_wallet_p1_task_p2_1_earning_model_second_migration_revision" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-12-artifact-removal-cache-verdict.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1146", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_09_12_artifact_removal_cache_verdict_md", - "target": "plans_2026_09_12_artifact_removal_cache_verdict_artifact_removal_matrix_cache_verdict_plan" + "source": "plans_2026_09_30_wallet_p1_goal_2_p2_earnings_performance_starts_only_after_goal_1_complete", + "target": "plans_2026_09_30_wallet_p1_task_p2_2_earnings_sync_accrue_transition_pull_based" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-12-artifact-removal-cache-verdict.md", - "source_location": "L3", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1236", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_12_artifact_removal_cache_verdict_artifact_removal_matrix_cache_verdict_plan", - "target": "plans_2026_09_12_artifact_removal_cache_verdict_part_1_deletions_safe_no_live_referrers" + "source": "plans_2026_09_30_wallet_p1_goal_2_p2_earnings_performance_starts_only_after_goal_1_complete", + "target": "plans_2026_09_30_wallet_p1_task_p2_3_performance_windows_on_demand_reconstruction_no_new_table" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-12-artifact-removal-cache-verdict.md", - "source_location": "L25", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1080", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_12_artifact_removal_cache_verdict_artifact_removal_matrix_cache_verdict_plan", - "target": "plans_2026_09_12_artifact_removal_cache_verdict_part_2_cache_verdict_keep_the_dict_skip_cashews" + "source": "plans_2026_09_30_wallet_p1_task_p2_1_earning_model_second_migration_revision", + "target": "plans_2026_09_30_wallet_p1_codeblock_29" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1108", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_09_14_memory_postgres_pgvector_plan_md", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_memory_postgres_pgvector_migration_implementation_plan" + "source": "plans_2026_09_30_wallet_p1_task_p2_1_earning_model_second_migration_revision", + "target": "plans_2026_09_30_wallet_p1_codeblock_30" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L13", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1139", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_memory_postgres_pgvector_migration_implementation_plan", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_global_constraints" + "source": "plans_2026_09_30_wallet_p1_task_p2_1_earning_model_second_migration_revision", + "target": "plans_2026_09_30_wallet_p1_codeblock_31" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L24", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1159", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_global_constraints", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_task_1_pgvector_migration_backfill" + "source": "plans_2026_09_30_wallet_p1_task_p2_2_earnings_sync_accrue_transition_pull_based", + "target": "plans_2026_09_30_wallet_p1_codeblock_32" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L79", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1167", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_global_constraints", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_task_2_delete_vector_py_rewrite_search" + "source": "plans_2026_09_30_wallet_p1_task_p2_2_earnings_sync_accrue_transition_pull_based", + "target": "plans_2026_09_30_wallet_p1_codeblock_33" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L139", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1229", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_global_constraints", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_task_3_update_the_test_files" + "source": "plans_2026_09_30_wallet_p1_task_p2_2_earnings_sync_accrue_transition_pull_based", + "target": "plans_2026_09_30_wallet_p1_codeblock_34" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L171", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1251", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_global_constraints", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_task_4_full_test_sweep_18_suites_postgres_ci_parity" + "source": "plans_2026_09_30_wallet_p1_task_p2_3_performance_windows_on_demand_reconstruction_no_new_table", + "target": "plans_2026_09_30_wallet_p1_codeblock_35" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L185", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1297", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_global_constraints", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_task_5_docs_close" + "source": "plans_2026_09_30_wallet_p1_task_p2_3_performance_windows_on_demand_reconstruction_no_new_table", + "target": "plans_2026_09_30_wallet_p1_codeblock_36" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L35", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1308", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_1_pgvector_migration_backfill", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_1" + "source": "plans_2026_09_30_wallet_p1_goal_3_p3_assist_narration_starts_only_after_goal_2_complete", + "target": "plans_2026_09_30_wallet_p1_task_p3_0_write_the_p3_detailed_plan_required_before_p3_1_p3_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L65", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1312", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_1_pgvector_migration_backfill", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_2" + "source": "plans_2026_09_30_wallet_p1_goal_3_p3_assist_narration_starts_only_after_goal_2_complete", + "target": "plans_2026_09_30_wallet_p1_task_p3_1_ratings_assist_tuning_gated_on_the_p3_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L74", + "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", + "source_location": "L1316", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_1_pgvector_migration_backfill", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_3" + "source": "plans_2026_09_30_wallet_p1_goal_3_p3_assist_narration_starts_only_after_goal_2_complete", + "target": "plans_2026_09_30_wallet_p1_task_p3_2_orunmila_narration_tools_gated_on_the_p3_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L97", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_2_delete_vector_py_rewrite_search", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_4" + "source": "docs_superpowers_plans_2026_10_01_wallet_p3_md", + "target": "plans_2026_10_01_wallet_p3_mansa_wallet_p3_detailed_plan_assist_narration" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L134", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_2_delete_vector_py_rewrite_search", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_5" + "source": "plans_2026_10_01_wallet_p3_mansa_wallet_p3_detailed_plan_assist_narration", + "target": "plans_2026_10_01_wallet_p3_global_constraints" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L148", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L31", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_3_update_the_test_files", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_6" + "source": "plans_2026_10_01_wallet_p3_mansa_wallet_p3_detailed_plan_assist_narration", + "target": "plans_2026_10_01_wallet_p3_review_focus" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L166", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L307", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_3_update_the_test_files", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_7" + "source": "plans_2026_10_01_wallet_p3_mansa_wallet_p3_detailed_plan_assist_narration", + "target": "plans_2026_10_01_wallet_p3_out_of_scope_for_p3_unchanged_from_spec_4_goal_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-14-memory-postgres-pgvector-plan.md", - "source_location": "L189", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L311", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_14_memory_postgres_pgvector_plan_task_5_docs_close", - "target": "plans_2026_09_14_memory_postgres_pgvector_plan_codeblock_8" + "source": "plans_2026_10_01_wallet_p3_mansa_wallet_p3_detailed_plan_assist_narration", + "target": "plans_2026_10_01_wallet_p3_standing_rules_carried_over" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L1", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L315", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_09_15_adopt_libs_md", - "target": "plans_2026_09_15_adopt_libs_adopt_libs_implementation_plan" + "source": "plans_2026_10_01_wallet_p3_mansa_wallet_p3_detailed_plan_assist_narration", + "target": "plans_2026_10_01_wallet_p3_finding_9_charter_gap_note" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L13", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L45", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_15_adopt_libs_adopt_libs_implementation_plan", - "target": "plans_2026_09_15_adopt_libs_global_constraints" + "source": "plans_2026_10_01_wallet_p3_review_focus", + "target": "plans_2026_10_01_wallet_p3_task_p3_1_ratings_assist_tuning_xango_informed_buy_flag_gated_on_this_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L24", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L185", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_15_adopt_libs_global_constraints", - "target": "plans_2026_09_15_adopt_libs_task_1_tenacity_replaces_bespoke_retries" + "source": "plans_2026_10_01_wallet_p3_review_focus", + "target": "plans_2026_10_01_wallet_p3_task_p3_2_orunmila_narration_tools_narrate_positions_first_gated_on_this_plan" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L56", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L58", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_15_adopt_libs_global_constraints", - "target": "plans_2026_09_15_adopt_libs_task_2_cashews_native_probe_first" + "source": "plans_2026_10_01_wallet_p3_task_p3_1_ratings_assist_tuning_xango_informed_buy_flag_gated_on_this_plan", + "target": "plans_2026_10_01_wallet_p3_codeblock_1" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L76", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L68", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_15_adopt_libs_global_constraints", - "target": "plans_2026_09_15_adopt_libs_task_3_pydantic_validates_llm_extraction_json" + "source": "plans_2026_10_01_wallet_p3_task_p3_1_ratings_assist_tuning_xango_informed_buy_flag_gated_on_this_plan", + "target": "plans_2026_10_01_wallet_p3_codeblock_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L102", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L83", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_15_adopt_libs_global_constraints", - "target": "plans_2026_09_15_adopt_libs_task_4_sse_starlette_replaces_hand_sse_bus" + "source": "plans_2026_10_01_wallet_p3_task_p3_1_ratings_assist_tuning_xango_informed_buy_flag_gated_on_this_plan", + "target": "plans_2026_10_01_wallet_p3_codeblock_3" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L117", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L178", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_15_adopt_libs_global_constraints", - "target": "plans_2026_09_15_adopt_libs_task_5_rapidfuzz_memory_key_dedup" + "source": "plans_2026_10_01_wallet_p3_task_p3_1_ratings_assist_tuning_xango_informed_buy_flag_gated_on_this_plan", + "target": "plans_2026_10_01_wallet_p3_codeblock_4" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L132", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L198", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_15_adopt_libs_global_constraints", - "target": "plans_2026_09_15_adopt_libs_task_6_cachetools_bounds_token_cache" + "source": "plans_2026_10_01_wallet_p3_task_p3_2_orunmila_narration_tools_narrate_positions_first_gated_on_this_plan", + "target": "plans_2026_10_01_wallet_p3_codeblock_5" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L143", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L227", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_15_adopt_libs_global_constraints", - "target": "plans_2026_09_15_adopt_libs_task_7_user_agents_fills_device_fields_optional" + "source": "plans_2026_10_01_wallet_p3_task_p3_2_orunmila_narration_tools_narrate_positions_first_gated_on_this_plan", + "target": "plans_2026_10_01_wallet_p3_codeblock_6" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L154", + "source_file": "docs/superpowers/plans/2026-10-01-wallet-p3.md", + "source_location": "L300", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_15_adopt_libs_global_constraints", - "target": "plans_2026_09_15_adopt_libs_task_8_pytest_plugin_set" + "source": "plans_2026_10_01_wallet_p3_task_p3_2_orunmila_narration_tools_narrate_positions_first_gated_on_this_plan", + "target": "plans_2026_10_01_wallet_p3_codeblock_7" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L38", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_15_adopt_libs_task_1_tenacity_replaces_bespoke_retries", - "target": "plans_2026_09_15_adopt_libs_codeblock_1" + "source": "docs_superpowers_specs_2026_09_04_wallet_design_md", + "target": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L51", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L8", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_15_adopt_libs_task_1_tenacity_replaces_bespoke_retries", - "target": "plans_2026_09_15_adopt_libs_codeblock_2" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_1_context" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L72", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L46", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_15_adopt_libs_task_2_cashews_native_probe_first", - "target": "plans_2026_09_15_adopt_libs_codeblock_3" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_2_decision_design_a_pure_event_log_derive_at_read_time" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-15-adopt-libs.md", - "source_location": "L88", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L68", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_15_adopt_libs_task_3_pydantic_validates_llm_extraction_json", - "target": "plans_2026_09_15_adopt_libs_codeblock_4" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_3_data_model_user_db_alembic" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L1", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L131", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_09_29_nginx_response_cache_md", - "target": "plans_2026_09_29_nginx_response_cache_nginx_response_cache_implementation_plan" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_4_derivations_all_at_read_time_date_order" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L14", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L175", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_nginx_response_cache_implementation_plan", - "target": "plans_2026_09_29_nginx_response_cache_global_constraints" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_5_endpoints_wallet_on_the_user_port_via_walletservice_getcurrentuser_gate_inline_body_query" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L25", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L203", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_nginx_response_cache_implementation_plan", - "target": "plans_2026_09_29_nginx_response_cache_review_focus_spec_implied_inputs_most_likely_to_bite" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_6_live_prices_endpoint_only_isolation" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L375", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L235", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_nginx_response_cache_implementation_plan", - "target": "plans_2026_09_29_nginx_response_cache_execution_handoff" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_7_validation_422_naming_the_rule_503_for_price_outages" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L36", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L266", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_review_focus_spec_implied_inputs_most_likely_to_bite", - "target": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_8_testing_quality_gates_precedents_to_honor" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L183", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L287", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_review_focus_spec_implied_inputs_most_likely_to_bite", - "target": "plans_2026_09_29_nginx_response_cache_task_2_cached_locations_shared_proxy_snippet_mirrored_ttls" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_9_scope" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", "source_location": "L302", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_review_focus_spec_implied_inputs_most_likely_to_bite", - "target": "plans_2026_09_29_nginx_response_cache_task_3_measure_the_gil_relief_and_record_it" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_10_splits_served_prices_are_raw_by_default_verified_verdict_encode_as_is" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L51", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L326", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_1" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_11_dividends_no_dedicated_endpoint_verified_verdict_encode_as_is" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L62", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L364", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_2" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_12_corporate_actions_splits_and_grupamentos_via_one_read_time_mechanism" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L87", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L403", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_3" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_13_dividend_methodology_ex_date_smoothing_check_both_branches_test_decides" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L101", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L422", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_4" + "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", + "target": "specs_2026_09_04_wallet_design_spec_self_review" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L116", + "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", + "source_location": "L53", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_5" + "source": "specs_2026_09_04_wallet_design_2_decision_design_a_pure_event_log_derive_at_read_time", + "target": "specs_2026_09_04_wallet_design_approaches_considered" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L131", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L1", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_6" + "source": "docs_superpowers_specs_2026_09_29_nginx_scaling_design_md", + "target": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L152", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L9", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_7" + "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", + "target": "specs_2026_09_29_nginx_scaling_design_1_context" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L164", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L40", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_8" + "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", + "target": "specs_2026_09_29_nginx_scaling_design_2_decisions" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L176", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L103", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_1_nginx_compose_service_http_context_config_upstream_bypass_routing", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_9" + "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", + "target": "specs_2026_09_29_nginx_scaling_design_3_caching_policy_canonical" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L195", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L130", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_2_cached_locations_shared_proxy_snippet_mirrored_ttls", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_10" + "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", + "target": "specs_2026_09_29_nginx_scaling_design_4_topology" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L206", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L148", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_2_cached_locations_shared_proxy_snippet_mirrored_ttls", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_11" + "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", + "target": "specs_2026_09_29_nginx_scaling_design_5_quota_and_rate_limits_after_caching" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L246", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L159", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_2_cached_locations_shared_proxy_snippet_mirrored_ttls", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_12" + "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", + "target": "specs_2026_09_29_nginx_scaling_design_6_non_goals" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L282", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L163", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_2_cached_locations_shared_proxy_snippet_mirrored_ttls", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_13" + "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", + "target": "specs_2026_09_29_nginx_scaling_design_7_acceptance_criteria" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L295", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L173", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_2_cached_locations_shared_proxy_snippet_mirrored_ttls", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_14" + "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", + "target": "specs_2026_09_29_nginx_scaling_design_8_open_decisions_product_owned" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L314", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L182", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_3_measure_the_gil_relief_and_record_it", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_15" + "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", + "target": "specs_2026_09_29_nginx_scaling_design_9_risks_top_of_the_register_full_15_row_table_in_the_source_document_3_9" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L321", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L195", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_3_measure_the_gil_relief_and_record_it", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_16" + "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", + "target": "specs_2026_09_29_nginx_scaling_design_10_plans_and_follow_ups" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L333", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L42", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_3_measure_the_gil_relief_and_record_it", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_17" + "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", + "target": "specs_2026_09_29_nginx_scaling_design_d1_put_an_nginx_response_cache_in_front_of_stocks_accepted" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L346", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L55", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_3_measure_the_gil_relief_and_record_it", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_18" + "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", + "target": "specs_2026_09_29_nginx_scaling_design_d2_raise_the_app_layer_ttls_and_cache_fields_before_any_nginx_work_accepted_rev_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-nginx-response-cache.md", - "source_location": "L367", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L59", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_nginx_response_cache_task_3_measure_the_gil_relief_and_record_it", - "target": "plans_2026_09_29_nginx_response_cache_codeblock_19" + "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", + "target": "specs_2026_09_29_nginx_scaling_design_d3_pinned_static_upstreams_now_docker_swarm_routing_mesh_only_at_5_nodes_accepted" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L1", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L75", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_09_29_stocks_cache_ttl_md", - "target": "plans_2026_09_29_stocks_cache_ttl_stocks_api_cache_ttl_fields_cache_implementation_plan" + "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", + "target": "specs_2026_09_29_nginx_scaling_design_d4_cache_is_per_node_rebuilt_on_version_not_nfs_not_rsync_accepted" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L13", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L79", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_stocks_api_cache_ttl_fields_cache_implementation_plan", - "target": "plans_2026_09_29_stocks_cache_ttl_global_constraints" + "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", + "target": "specs_2026_09_29_nginx_scaling_design_d5_redis_is_deferred_accepted_rev_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L25", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L83", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_stocks_api_cache_ttl_fields_cache_implementation_plan", - "target": "plans_2026_09_29_stocks_cache_ttl_review_focus_spec_implied_inputs_most_likely_to_bite" + "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", + "target": "specs_2026_09_29_nginx_scaling_design_d6_extraction_order_stocks_api_orunmila_forgevm_user_scraper_accepted" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L410", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L87", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_stocks_api_cache_ttl_fields_cache_implementation_plan", - "target": "plans_2026_09_29_stocks_cache_ttl_execution_handoff" + "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", + "target": "specs_2026_09_29_nginx_scaling_design_d7_health_strategy_stays_passive_until_a_black_hole_is_observed_accepted" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L36", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L91", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_review_focus_spec_implied_inputs_most_likely_to_bite", - "target": "plans_2026_09_29_stocks_cache_ttl_task_1_ttl_constants_6h_on_the_three_data_routes_header_alignment" + "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", + "target": "specs_2026_09_29_nginx_scaling_design_d8_cached_hits_bypass_the_monthly_quota_counter_accepted_product_visible" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L136", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L95", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_review_focus_spec_implied_inputs_most_likely_to_bite", - "target": "plans_2026_09_29_stocks_cache_ttl_task_2_cache_stocks_fields" + "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", + "target": "specs_2026_09_29_nginx_scaling_design_d9_benchmark_result_artifacts_follow_the_draft_convention_accepted_rev_2" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L254", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L99", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_review_focus_spec_implied_inputs_most_likely_to_bite", - "target": "plans_2026_09_29_stocks_cache_ttl_task_3_invalidate_the_endpoint_cache_on_feather_reload" + "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", + "target": "specs_2026_09_29_nginx_scaling_design_d10_the_endpoint_cache_is_invalidated_on_every_feather_reload_accepted" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L340", + "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", + "source_location": "L135", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_review_focus_spec_implied_inputs_most_likely_to_bite", - "target": "plans_2026_09_29_stocks_cache_ttl_task_4_measure_the_6h_window_rss_and_record_the_verdict" + "source": "specs_2026_09_29_nginx_scaling_design_4_topology", + "target": "specs_2026_09_29_nginx_scaling_design_codeblock_1" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L50", + "source_file": "main/app/wallet/positions.py", + "source_location": "L59", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_1_ttl_constants_6h_on_the_three_data_routes_header_alignment", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_1" + "source": "wallet_positions_rationale_59", + "target": "wallet_positions_scorebuyflag" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L91", + "source_file": "main/app/wallet/positions.py", + "source_location": "L36", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_1_ttl_constants_6h_on_the_three_data_routes_header_alignment", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_2" + "source": "wallet_positions_rationale_36", + "target": "wallet_positions_scorebuyflag" }, { - "relation": "contains", + "relation": "imports_from", + "context": "import", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L103", + "source_file": "main/app/wallet/auth.py", + "source_location": "L3", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_1_ttl_constants_6h_on_the_three_data_routes_header_alignment", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_3" + "source": "main_app_wallet_auth_py", + "target": "fastapi" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L112", + "source_file": "main/app/wallet/auth.py", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_1_ttl_constants_6h_on_the_three_data_routes_header_alignment", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_4" + "source": "main_app_wallet_auth_py", + "target": "wallet_auth_resolverawtoken" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L129", + "source_file": "main/app/wallet/auth.py", + "source_location": "L26", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_1_ttl_constants_6h_on_the_three_data_routes_header_alignment", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_5" + "source": "main_app_wallet_auth_py", + "target": "wallet_auth_getwalletidentity" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L152", + "source_file": "main/app/wallet/auth.py", + "source_location": "L30", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_2_cache_stocks_fields", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_6" + "source": "main_app_wallet_auth_py", + "target": "wallet_auth_requirewalletuser" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L165", + "source_file": "main/app/wallet/auth.py", + "source_location": "L36", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_2_cache_stocks_fields", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_7" + "source": "main_app_wallet_auth_py", + "target": "wallet_auth_requirewalletownership" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L220", + "source_file": "main/app/wallet/auth.py", + "source_location": "L27", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_2_cache_stocks_fields", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_8" + "source": "wallet_auth_getwalletidentity", + "target": "wallet_auth_resolverawtoken" }, { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L228", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/wallets.py", + "source_location": "L17", "weight": 1.0, - "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_2_cache_stocks_fields", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_9" + "source": "wallet_wallets_getownedwallet", + "target": "wallet_auth_requirewalletownership" }, { - "relation": "contains", + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L68", + "weight": 1.0, + "source": "wallet_wallet_service_getownedwallet", + "target": "wallet_auth_requirewalletownership" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/service/wallet_service.py", + "source_location": "L50", + "weight": 1.0, + "source": "service_wallet_service_get_owned_wallet", + "target": "wallet_auth_requirewalletownership" + }, + { + "relation": "imports_from", + "context": "import", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L247", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_2_cache_stocks_fields", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_10" + "source": "main_app_wallet_wallet_service_py", + "target": "fastapi" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L269", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L36", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_3_invalidate_the_endpoint_cache_on_feather_reload", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_11" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchxangoscores" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L301", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L48", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_3_invalidate_the_endpoint_cache_on_feather_reload", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_12" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_scorebuyflag" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L311", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L32", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_3_invalidate_the_endpoint_cache_on_feather_reload", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_13" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_createwallet" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L333", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L40", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_3_invalidate_the_endpoint_cache_on_feather_reload", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_14" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_listwallets" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L352", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L44", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_4_measure_the_6h_window_rss_and_record_the_verdict", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_15" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_entrycreate" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L363", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L55", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_4_measure_the_6h_window_rss_and_record_the_verdict", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_16" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_entryupdate" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L376", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L62", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_4_measure_the_6h_window_rss_and_record_the_verdict", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_17" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getownedwallet" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L384", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L72", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_4_measure_the_6h_window_rss_and_record_the_verdict", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_18" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_applyentries" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-stocks-cache-ttl.md", - "source_location": "L402", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L88", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_stocks_cache_ttl_task_4_measure_the_6h_window_rss_and_record_the_verdict", - "target": "plans_2026_09_29_stocks_cache_ttl_codeblock_19" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_recalcholding" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L1", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L112", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_09_29_uvicorn_worker_scaling_md", - "target": "plans_2026_09_29_uvicorn_worker_scaling_uvicorn_fastapi_worker_scaling_implementation_plan" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_addentry" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L13", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L138", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_uvicorn_fastapi_worker_scaling_implementation_plan", - "target": "plans_2026_09_29_uvicorn_worker_scaling_global_constraints" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_listentries" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L23", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L150", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_uvicorn_fastapi_worker_scaling_implementation_plan", - "target": "plans_2026_09_29_uvicorn_worker_scaling_review_focus" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_updateentry" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L725", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L172", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_uvicorn_fastapi_worker_scaling_implementation_plan", - "target": "plans_2026_09_29_uvicorn_worker_scaling_self_review" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_deleteentry" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L35", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L193", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_review_focus", - "target": "plans_2026_09_29_uvicorn_worker_scaling_task_1_measure_the_concurrency_ceiling_and_record_the_decision" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_stocksapibase" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L170", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L197", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_review_focus", - "target": "plans_2026_09_29_uvicorn_worker_scaling_task_2_load_the_cache_on_the_build_loser_path" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_stocksapiheaders" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L292", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L202", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_review_focus", - "target": "plans_2026_09_29_uvicorn_worker_scaling_task_3_run_migrations_exactly_once_per_deploy" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchliveprices" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L365", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L227", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_review_focus", - "target": "plans_2026_09_29_uvicorn_worker_scaling_task_4_size_database_pools_by_process_count" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchcachedclose" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L431", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L247", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_review_focus", - "target": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getpositions" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L654", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L306", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_review_focus", - "target": "plans_2026_09_29_uvicorn_worker_scaling_task_6_verify_the_fleet_single_build_one_migration_shared_frame" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_targetupsert" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L47", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L313", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_1_measure_the_concurrency_ceiling_and_record_the_decision", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_1" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_ratingupsert" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L145", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L319", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_1_measure_the_concurrency_ceiling_and_record_the_decision", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_2" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getsummary" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L158", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L370", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_1_measure_the_concurrency_ceiling_and_record_the_decision", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_3" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getallocation" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L182", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L396", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_2_load_the_cache_on_the_build_loser_path", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_4" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_upserttarget" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L228", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L422", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_2_load_the_cache_on_the_build_loser_path", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_5" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_set_rating" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L244", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L433", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_2_load_the_cache_on_the_build_loser_path", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_6" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_positionatdate" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L285", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L440", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_2_load_the_cache_on_the_build_loser_path", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_7" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchmarketdividends" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L304", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L458", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_3_run_migrations_exactly_once_per_deploy", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_8" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_syncearnings" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L333", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L525", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_3_run_migrations_exactly_once_per_deploy", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_9" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_listearnings" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L358", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L536", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_3_run_migrations_exactly_once_per_deploy", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_10" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchpadraocloses" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L377", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L559", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_4_size_database_pools_by_process_count", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_11" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_cachedperformance" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L407", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L662", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_4_size_database_pools_by_process_count", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_12" + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getperformance" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L424", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L331", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_4_size_database_pools_by_process_count", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_13" + "source": "wallet_wallet_service_getpositions", + "target": "wallet_wallet_service_fetchxangoscores" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L444", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L37", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_14" + "source": "wallet_wallet_service_rationale_37", + "target": "wallet_wallet_service_fetchxangoscores" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L476", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L354", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_15" + "source": "wallet_wallet_service_getpositions", + "target": "wallet_wallet_service_scorebuyflag" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L483", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L55", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_16" + "source": "wallet_wallet_service_rationale_55", + "target": "wallet_wallet_service_scorebuyflag" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L494", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L113", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_17" + "source": "wallet_wallet_service_addentry", + "target": "wallet_wallet_service_getownedwallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L618", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L141", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_18" + "source": "wallet_wallet_service_listentries", + "target": "wallet_wallet_service_getownedwallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L647", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L154", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_5_run_stocks_api_as_n_single_service_processes_behind_nginx", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_19" + "source": "wallet_wallet_service_updateentry", + "target": "wallet_wallet_service_getownedwallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L666", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L176", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_6_verify_the_fleet_single_build_one_migration_shared_frame", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_20" + "source": "wallet_wallet_service_deleteentry", + "target": "wallet_wallet_service_getownedwallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-uvicorn-worker-scaling.md", - "source_location": "L718", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L248", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_uvicorn_worker_scaling_task_6_verify_the_fleet_single_build_one_migration_shared_frame", - "target": "plans_2026_09_29_uvicorn_worker_scaling_codeblock_21" + "source": "wallet_wallet_service_getpositions", + "target": "wallet_wallet_service_getownedwallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L1", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L320", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_plans_2026_09_29_zerocopy_stocks_cache_md", - "target": "plans_2026_09_29_zerocopy_stocks_cache_zero_copy_memory_mapped_stocks_cache_implementation_plan" + "source": "wallet_wallet_service_getsummary", + "target": "wallet_wallet_service_getownedwallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L13", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L371", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_zero_copy_memory_mapped_stocks_cache_implementation_plan", - "target": "plans_2026_09_29_zerocopy_stocks_cache_global_constraints" + "source": "wallet_wallet_service_getallocation", + "target": "wallet_wallet_service_getownedwallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L23", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L397", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_zero_copy_memory_mapped_stocks_cache_implementation_plan", - "target": "plans_2026_09_29_zerocopy_stocks_cache_review_focus_spec_implied_inputs_most_likely_to_bite" + "source": "wallet_wallet_service_upserttarget", + "target": "wallet_wallet_service_getownedwallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L353", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L423", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_zero_copy_memory_mapped_stocks_cache_implementation_plan", - "target": "plans_2026_09_29_zerocopy_stocks_cache_execution_handoff" + "source": "wallet_wallet_service_set_rating", + "target": "wallet_wallet_service_getownedwallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L33", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L459", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_review_focus_spec_implied_inputs_most_likely_to_bite", - "target": "plans_2026_09_29_zerocopy_stocks_cache_task_1_presort_at_build_time_order_by_b3_presorted_marker" + "source": "wallet_wallet_service_syncearnings", + "target": "wallet_wallet_service_getownedwallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L125", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L526", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_review_focus_spec_implied_inputs_most_likely_to_bite", - "target": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip" + "source": "wallet_wallet_service_listearnings", + "target": "wallet_wallet_service_getownedwallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L292", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L665", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_review_focus_spec_implied_inputs_most_likely_to_bite", - "target": "plans_2026_09_29_zerocopy_stocks_cache_task_3_arrowdtype_aware_json_column_decompression_query_py_guard" + "source": "wallet_wallet_service_getperformance", + "target": "wallet_wallet_service_getownedwallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L47", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L100", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_1_presort_at_build_time_order_by_b3_presorted_marker", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_1" + "source": "wallet_wallet_service_recalcholding", + "target": "wallet_wallet_service_applyentries" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L93", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L436", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_1_presort_at_build_time_order_by_b3_presorted_marker", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_2" + "source": "wallet_wallet_service_positionatdate", + "target": "wallet_wallet_service_applyentries" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L101", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L592", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_1_presort_at_build_time_order_by_b3_presorted_marker", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_3" + "source": "wallet_wallet_service_cachedperformance", + "target": "wallet_wallet_service_applyentries" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L107", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L130", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_1_presort_at_build_time_order_by_b3_presorted_marker", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_4" + "source": "wallet_wallet_service_addentry", + "target": "wallet_wallet_service_recalcholding" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L118", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L161", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_1_presort_at_build_time_order_by_b3_presorted_marker", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_5" + "source": "wallet_wallet_service_updateentry", + "target": "wallet_wallet_service_recalcholding" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L142", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L182", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_6" + "source": "wallet_wallet_service_deleteentry", + "target": "wallet_wallet_service_recalcholding" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L148", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L230", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_7" + "source": "wallet_wallet_service_fetchcachedclose", + "target": "wallet_wallet_service_stocksapibase" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L152", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L443", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_8" + "source": "wallet_wallet_service_fetchmarketdividends", + "target": "wallet_wallet_service_stocksapibase" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L159", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L539", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_9" + "source": "wallet_wallet_service_fetchpadraocloses", + "target": "wallet_wallet_service_stocksapibase" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L165", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L232", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_10" + "source": "wallet_wallet_service_fetchcachedclose", + "target": "wallet_wallet_service_stocksapiheaders" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L250", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L445", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_11" + "source": "wallet_wallet_service_fetchmarketdividends", + "target": "wallet_wallet_service_stocksapiheaders" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L256", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L541", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_12" + "source": "wallet_wallet_service_fetchpadraocloses", + "target": "wallet_wallet_service_stocksapiheaders" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L268", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L251", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_13" + "source": "wallet_wallet_service_getpositions", + "target": "wallet_wallet_service_fetchliveprices" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L285", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L324", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_2_zero_copy_mmap_load_readfeatherdataframe_marker_aware_sort_skip", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_14" + "source": "wallet_wallet_service_getsummary", + "target": "wallet_wallet_service_fetchliveprices" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L306", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L374", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_3_arrowdtype_aware_json_column_decompression_query_py_guard", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_15" + "source": "wallet_wallet_service_getallocation", + "target": "wallet_wallet_service_fetchliveprices" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L327", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L254", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_3_arrowdtype_aware_json_column_decompression_query_py_guard", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_16" + "source": "wallet_wallet_service_getpositions", + "target": "wallet_wallet_service_fetchcachedclose" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L331", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L327", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_3_arrowdtype_aware_json_column_decompression_query_py_guard", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_17" + "source": "wallet_wallet_service_getsummary", + "target": "wallet_wallet_service_fetchcachedclose" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/plans/2026-09-29-zerocopy-stocks-cache.md", - "source_location": "L346", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L377", "weight": 1.0, "confidence_score": 1.0, - "source": "plans_2026_09_29_zerocopy_stocks_cache_task_3_arrowdtype_aware_json_column_decompression_query_py_guard", - "target": "plans_2026_09_29_zerocopy_stocks_cache_codeblock_18" + "source": "wallet_wallet_service_getallocation", + "target": "wallet_wallet_service_fetchcachedclose" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L1", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L487", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_specs_2026_09_04_wallet_design_md", - "target": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec" + "source": "wallet_wallet_service_syncearnings", + "target": "wallet_wallet_service_positionatdate" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L8", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L474", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_1_context" + "source": "wallet_wallet_service_syncearnings", + "target": "wallet_wallet_service_fetchmarketdividends" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L46", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L581", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_2_decision_design_a_pure_event_log_derive_at_read_time" + "source": "wallet_wallet_service_cachedperformance", + "target": "wallet_wallet_service_fetchpadraocloses" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L68", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L692", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_3_data_model_user_db_alembic" + "source": "wallet_wallet_service_getperformance", + "target": "wallet_wallet_service_cachedperformance" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L131", + "source_file": "main/service/wallet_service.py", + "source_location": "L95", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_4_derivations_all_at_read_time_date_order" + "source": "service_wallet_service_add_entry", + "target": "service_wallet_service_get_owned_wallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L175", + "source_file": "main/service/wallet_service.py", + "source_location": "L123", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_5_endpoints_wallet_on_the_user_port_via_walletservice_getcurrentuser_gate_inline_body_query" + "source": "service_wallet_service_list_entries", + "target": "service_wallet_service_get_owned_wallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L203", + "source_file": "main/service/wallet_service.py", + "source_location": "L136", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_6_live_prices_endpoint_only_isolation" + "source": "service_wallet_service_update_entry", + "target": "service_wallet_service_get_owned_wallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L235", + "source_file": "main/service/wallet_service.py", + "source_location": "L158", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_7_validation_422_naming_the_rule_503_for_price_outages" + "source": "service_wallet_service_delete_entry", + "target": "service_wallet_service_get_owned_wallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L266", + "source_file": "main/service/wallet_service.py", + "source_location": "L235", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_8_testing_quality_gates_precedents_to_honor" + "source": "service_wallet_service_get_positions", + "target": "service_wallet_service_get_owned_wallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L287", + "source_file": "main/service/wallet_service.py", + "source_location": "L307", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_9_scope" + "source": "service_wallet_service_get_summary", + "target": "service_wallet_service_get_owned_wallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L302", + "source_file": "main/service/wallet_service.py", + "source_location": "L358", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_10_splits_served_prices_are_raw_by_default_verified_verdict_encode_as_is" + "source": "service_wallet_service_get_allocation", + "target": "service_wallet_service_get_owned_wallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L326", + "source_file": "main/service/wallet_service.py", + "source_location": "L384", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_11_dividends_no_dedicated_endpoint_verified_verdict_encode_as_is" + "source": "service_wallet_service_upsert_target", + "target": "service_wallet_service_get_owned_wallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L364", + "source_file": "main/service/wallet_service.py", + "source_location": "L410", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_12_corporate_actions_splits_and_grupamentos_via_one_read_time_mechanism" + "source": "service_wallet_service_set_rating", + "target": "service_wallet_service_get_owned_wallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L403", + "source_file": "main/service/wallet_service.py", + "source_location": "L455", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_13_dividend_methodology_ex_date_smoothing_check_both_branches_test_decides" + "source": "service_wallet_service_sync_earnings", + "target": "service_wallet_service_get_owned_wallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L422", + "source_file": "main/service/wallet_service.py", + "source_location": "L522", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_thoth_iyagba_wallet_management_design_spec", - "target": "specs_2026_09_04_wallet_design_spec_self_review" + "source": "service_wallet_service_list_earnings", + "target": "service_wallet_service_get_owned_wallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-04-wallet-design.md", - "source_location": "L53", + "source_file": "main/service/wallet_service.py", + "source_location": "L665", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_04_wallet_design_2_decision_design_a_pure_event_log_derive_at_read_time", - "target": "specs_2026_09_04_wallet_design_approaches_considered" + "source": "service_wallet_service_get_performance", + "target": "service_wallet_service_get_owned_wallet" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L1", + "source_file": "main/service/wallet_service.py", + "source_location": "L82", "weight": 1.0, "confidence_score": 1.0, - "source": "docs_superpowers_specs_2026_09_29_nginx_scaling_design_md", - "target": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec" + "source": "service_wallet_service_recalc_holding", + "target": "service_wallet_service_apply_entries" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L9", + "source_file": "main/service/wallet_service.py", + "source_location": "L432", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", - "target": "specs_2026_09_29_nginx_scaling_design_1_context" + "source": "service_wallet_service_position_at_date", + "target": "service_wallet_service_apply_entries" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L40", + "source_file": "main/service/wallet_service.py", + "source_location": "L592", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", - "target": "specs_2026_09_29_nginx_scaling_design_2_decisions" + "source": "service_wallet_service_cachedperformance", + "target": "service_wallet_service_apply_entries" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L103", + "source_file": "main/service/wallet_service.py", + "source_location": "L112", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", - "target": "specs_2026_09_29_nginx_scaling_design_3_caching_policy_canonical" + "source": "service_wallet_service_add_entry", + "target": "service_wallet_service_recalc_holding" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L130", + "source_file": "main/service/wallet_service.py", + "source_location": "L143", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", - "target": "specs_2026_09_29_nginx_scaling_design_4_topology" + "source": "service_wallet_service_update_entry", + "target": "service_wallet_service_recalc_holding" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L148", + "source_file": "main/service/wallet_service.py", + "source_location": "L164", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", - "target": "specs_2026_09_29_nginx_scaling_design_5_quota_and_rate_limits_after_caching" + "source": "service_wallet_service_delete_entry", + "target": "service_wallet_service_recalc_holding" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L159", + "source_file": "main/service/wallet_service.py", + "source_location": "L217", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", - "target": "specs_2026_09_29_nginx_scaling_design_6_non_goals" + "source": "service_wallet_service_fetchcachedclose", + "target": "service_wallet_service_stocksapibase" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L163", + "source_file": "main/service/wallet_service.py", + "source_location": "L439", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", - "target": "specs_2026_09_29_nginx_scaling_design_7_acceptance_criteria" + "source": "service_wallet_service_fetchmarketdividends", + "target": "service_wallet_service_stocksapibase" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L173", + "source_file": "main/service/wallet_service.py", + "source_location": "L539", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", - "target": "specs_2026_09_29_nginx_scaling_design_8_open_decisions_product_owned" + "source": "service_wallet_service_fetchpadraocloses", + "target": "service_wallet_service_stocksapibase" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L182", + "source_file": "main/service/wallet_service.py", + "source_location": "L219", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", - "target": "specs_2026_09_29_nginx_scaling_design_9_risks_top_of_the_register_full_15_row_table_in_the_source_document_3_9" + "source": "service_wallet_service_fetchcachedclose", + "target": "service_wallet_service_stocksapiheaders" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L195", + "source_file": "main/service/wallet_service.py", + "source_location": "L441", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_nginx_response_cache_multi_server_scaling_design_spec", - "target": "specs_2026_09_29_nginx_scaling_design_10_plans_and_follow_ups" + "source": "service_wallet_service_fetchmarketdividends", + "target": "service_wallet_service_stocksapiheaders" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L42", + "source_file": "main/service/wallet_service.py", + "source_location": "L541", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", - "target": "specs_2026_09_29_nginx_scaling_design_d1_put_an_nginx_response_cache_in_front_of_stocks_accepted" + "source": "service_wallet_service_fetchpadraocloses", + "target": "service_wallet_service_stocksapiheaders" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L55", + "source_file": "main/service/wallet_service.py", + "source_location": "L238", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", - "target": "specs_2026_09_29_nginx_scaling_design_d2_raise_the_app_layer_ttls_and_cache_fields_before_any_nginx_work_accepted_rev_2" + "source": "service_wallet_service_get_positions", + "target": "service_wallet_service_fetchliveprices" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L59", + "source_file": "main/service/wallet_service.py", + "source_location": "L311", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", - "target": "specs_2026_09_29_nginx_scaling_design_d3_pinned_static_upstreams_now_docker_swarm_routing_mesh_only_at_5_nodes_accepted" + "source": "service_wallet_service_get_summary", + "target": "service_wallet_service_fetchliveprices" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L75", + "source_file": "main/service/wallet_service.py", + "source_location": "L361", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", - "target": "specs_2026_09_29_nginx_scaling_design_d4_cache_is_per_node_rebuilt_on_version_not_nfs_not_rsync_accepted" + "source": "service_wallet_service_get_allocation", + "target": "service_wallet_service_fetchliveprices" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L79", + "source_file": "main/service/wallet_service.py", + "source_location": "L241", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", - "target": "specs_2026_09_29_nginx_scaling_design_d5_redis_is_deferred_accepted_rev_2" + "source": "service_wallet_service_get_positions", + "target": "service_wallet_service_fetchcachedclose" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L83", + "source_file": "main/service/wallet_service.py", + "source_location": "L314", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", - "target": "specs_2026_09_29_nginx_scaling_design_d6_extraction_order_stocks_api_orunmila_forgevm_user_scraper_accepted" + "source": "service_wallet_service_get_summary", + "target": "service_wallet_service_fetchcachedclose" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L87", + "source_file": "main/service/wallet_service.py", + "source_location": "L364", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", - "target": "specs_2026_09_29_nginx_scaling_design_d7_health_strategy_stays_passive_until_a_black_hole_is_observed_accepted" + "source": "service_wallet_service_get_allocation", + "target": "service_wallet_service_fetchcachedclose" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L91", + "source_file": "main/service/wallet_service.py", + "source_location": "L483", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", - "target": "specs_2026_09_29_nginx_scaling_design_d8_cached_hits_bypass_the_monthly_quota_counter_accepted_product_visible" + "source": "service_wallet_service_sync_earnings", + "target": "service_wallet_service_position_at_date" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L95", + "source_file": "main/service/wallet_service.py", + "source_location": "L470", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", - "target": "specs_2026_09_29_nginx_scaling_design_d9_benchmark_result_artifacts_follow_the_draft_convention_accepted_rev_2" + "source": "service_wallet_service_sync_earnings", + "target": "service_wallet_service_fetchmarketdividends" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L99", + "source_file": "main/service/wallet_service.py", + "source_location": "L581", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_2_decisions", - "target": "specs_2026_09_29_nginx_scaling_design_d10_the_endpoint_cache_is_invalidated_on_every_feather_reload_accepted" + "source": "service_wallet_service_cachedperformance", + "target": "service_wallet_service_fetchpadraocloses" }, { - "relation": "contains", + "relation": "calls", + "context": "call", "confidence": "EXTRACTED", - "source_file": "docs/superpowers/specs/2026-09-29-nginx-scaling-design.md", - "source_location": "L135", + "source_file": "main/service/wallet_service.py", + "source_location": "L692", "weight": 1.0, "confidence_score": 1.0, - "source": "specs_2026_09_29_nginx_scaling_design_4_topology", - "target": "specs_2026_09_29_nginx_scaling_design_codeblock_1" + "source": "service_wallet_service_get_performance", + "target": "service_wallet_service_cachedperformance" }, { "relation": "rationale_for", @@ -150930,5 +158424,5 @@ "label": "User Authentication & Authorization" } ], - "built_at_commit": "9cfa467f5e182a4a67ff4017297a51199f520f60" + "built_at_commit": "5f6a9589ec29c6af12d284a4fe1d2a4ef4aab7d5" } \ No newline at end of file diff --git a/graphify-out/manifest.json b/graphify-out/manifest.json index 371c8037..6b766be3 100644 --- a/graphify-out/manifest.json +++ b/graphify-out/manifest.json @@ -15,8 +15,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\run.py": { - "mtime": 1789626195.3671405, - "ast_hash": "92577acca4f2a3bbf0ca57a9a27abdcc", + "mtime": 1790822066.405692, + "ast_hash": "c2366bbc2b938c01d94e069076a65f3e", "semantic_hash": "" }, "D:\\Repositories\\server\\frontend\\components.json": { @@ -270,8 +270,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\orunmila\\tools.py": { - "mtime": 1789627519.916649, - "ast_hash": "b45895bba6e8c7b6bfee5dd7c1cfa2c1", + "mtime": 1790824053.1540968, + "ast_hash": "faaac4998b77bd459dc1011925652a9c", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\orunmila\\vector.py": { @@ -280,8 +280,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\scraper_b3\\scraper.py": { - "mtime": 1790736245.276425, - "ast_hash": "860f0d9a1a74c9b33fadce5148077f58", + "mtime": 1790821091.8922184, + "ast_hash": "7bd8236b3758b54442a88eaf8c8c761b", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\scraper_b3\\xango.py": { @@ -320,8 +320,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\stocks_api\\sync_cache.py": { - "mtime": 1790736142.4061236, - "ast_hash": "9f07874bea2f9fcfad9acd239ae7b84e", + "mtime": 1790821091.8932161, + "ast_hash": "f32f01784a16b03442fcd6a1662e1e47", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\stocks_api\\util.py": { @@ -334,6 +334,41 @@ "ast_hash": "a2cf805d0df8ca36122f887ae54c9280", "semantic_hash": "" }, + "D:\\Repositories\\server\\main\\app\\wallet\\earnings.py": { + "mtime": 1790824458.9011092, + "ast_hash": "2e772942089dbed00a2bd81f69d67ee8", + "semantic_hash": "" + }, + "D:\\Repositories\\server\\main\\app\\wallet\\entries.py": { + "mtime": 1790826311.012261, + "ast_hash": "7df758c815bfa3e1507cbb6b87d85147", + "semantic_hash": "" + }, + "D:\\Repositories\\server\\main\\app\\wallet\\market_data.py": { + "mtime": 1790825185.0532987, + "ast_hash": "fd5e532592b3f274c8df7725152028a1", + "semantic_hash": "" + }, + "D:\\Repositories\\server\\main\\app\\wallet\\performance.py": { + "mtime": 1790824052.8533888, + "ast_hash": "61593cfecc93cd23fff7f63dd2c6b1de", + "semantic_hash": "" + }, + "D:\\Repositories\\server\\main\\app\\wallet\\positions.py": { + "mtime": 1790826385.2914288, + "ast_hash": "032c229aa8753ac32ed73b4f14e8cc19", + "semantic_hash": "" + }, + "D:\\Repositories\\server\\main\\app\\wallet\\summary.py": { + "mtime": 1790826317.3061473, + "ast_hash": "9a0d79a453dad99ffdcfe8c19a147b75", + "semantic_hash": "" + }, + "D:\\Repositories\\server\\main\\app\\wallet\\wallets.py": { + "mtime": 1790825037.0556405, + "ast_hash": "468ae0aa9392477efa4a5c6b4990b049", + "semantic_hash": "" + }, "D:\\Repositories\\server\\main\\controller\\authentication_controller.py": { "mtime": 1790721202.5567384, "ast_hash": "8be9ba65e0116ce4ad4867fcc59bae50", @@ -354,6 +389,11 @@ "ast_hash": "3b2e912c481d62f9b638dddd68e142e3", "semantic_hash": "" }, + "D:\\Repositories\\server\\main\\controller\\wallet_controller.py": { + "mtime": 1790826317.3061473, + "ast_hash": "11201d1c6b1580e76f2e2ad752cd9c9b", + "semantic_hash": "" + }, "D:\\Repositories\\server\\main\\models\\base.py": { "mtime": 1789266824.6195102, "ast_hash": "7dcf1fbc4850b465566daca90de0deb4", @@ -394,6 +434,11 @@ "ast_hash": "0245c293779cd189e1e74b2d006af625", "semantic_hash": "" }, + "D:\\Repositories\\server\\main\\models\\wallet.py": { + "mtime": 1790814890.9302452, + "ast_hash": "cf13241575f7af9059fb1ef2fb6421ae", + "semantic_hash": "" + }, "D:\\Repositories\\server\\main\\service\\authentication_service.py": { "mtime": 1790720783.1180828, "ast_hash": "2199185dd36046b7afa30557692a529a", @@ -415,10 +460,15 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\service\\user_service.py": { - "mtime": 1789266824.6290352, + "mtime": 1790821989.9446845, "ast_hash": "aab8360aeaaa776f5d17e5a0e0caf6dd", "semantic_hash": "" }, + "D:\\Repositories\\server\\main\\service\\wallet_service.py": { + "mtime": 1790821975.2138531, + "ast_hash": "40b4f7b2ec5b4daecbdf8773b4cd9834", + "semantic_hash": "" + }, "D:\\Repositories\\server\\main\\utils\\connectivity.py": { "mtime": 1789366037.8517115, "ast_hash": "b9c539f0db7e46481115e3c413fbd8d9", @@ -450,8 +500,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\utils\\roles.py": { - "mtime": 1790707412.4730222, - "ast_hash": "82063fac45e0e82ef3efa1be9248b9ca", + "mtime": 1790810393.7859154, + "ast_hash": "52c32388adb525de40f293c6284d577d", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\utils\\scheduler.py": { @@ -475,8 +525,8 @@ "semantic_hash": "d41d8cd98f00b204e9800998ecf8427e" }, "D:\\Repositories\\server\\migrations\\env.py": { - "mtime": 1789626224.6520696, - "ast_hash": "269f35fa57eecf274cb3a87d613ac006", + "mtime": 1790811516.9732063, + "ast_hash": "e4f56864f7807ea4d1930895670f8fc5", "semantic_hash": "" }, "D:\\Repositories\\server\\migrations\\versions\\25af7ad931e7_initial_migration.py": { @@ -489,6 +539,11 @@ "ast_hash": "6f701ad504554b99772333851ddf4e1b", "semantic_hash": "" }, + "D:\\Repositories\\server\\migrations\\versions\\73211a401c34_wallet_tables.py": { + "mtime": 1790811605.7685833, + "ast_hash": "04ddd9e24fd92a81da67b12c7b5d8049", + "semantic_hash": "" + }, "D:\\Repositories\\server\\migrations\\versions\\9f3b339dde20_drop_unused_user_sessions_columns.py": { "mtime": 1789266824.643073, "ast_hash": "7b002454a5a67cf5b15845847da95ff9", @@ -509,6 +564,11 @@ "ast_hash": "01916ec30942638aac469c4c0ec1171a", "semantic_hash": "" }, + "D:\\Repositories\\server\\migrations\\versions\\c4d1e8f2a917_wallet_earnings.py": { + "mtime": 1790815057.0441616, + "ast_hash": "c39e73dcfcde00bd79b5f2f59b4d113d", + "semantic_hash": "" + }, "D:\\Repositories\\server\\migrations\\versions\\d3df3fc5ca72_rename_memory_base_score.py": { "mtime": 1789266824.6456323, "ast_hash": "598b19c1d4efb7dccf7917244aa145ee", @@ -565,13 +625,13 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\TODO.md": { - "mtime": 1790726042.3421116, - "ast_hash": "0eafe0ff835b328c0ef66fdbe6e75100", + "mtime": 1790823747.2733662, + "ast_hash": "80cf4ec3d1860dcb876aa2d5a5cb577f", "semantic_hash": "" }, "D:\\Repositories\\server\\docs\\authentication.md": { - "mtime": 1789627715.725813, - "ast_hash": "418f5a3a5d92e6afdd9a8867235bfa38", + "mtime": 1790810393.8014698, + "ast_hash": "eae0f9cacc413290c0c7b8aa9daaa1a5", "semantic_hash": "" }, "D:\\Repositories\\server\\docs\\orunmila.md": { @@ -590,18 +650,18 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\docs\\user.md": { - "mtime": 1789627715.7248125, - "ast_hash": "1441362ec9c24f3e04abfd6c913b8efe", + "mtime": 1790810393.8024735, + "ast_hash": "39586406ef3546456171e268b4bc8ad0", "semantic_hash": "" }, "D:\\Repositories\\server\\docs\\superpowers\\investidor10-wallet-research.md": { - "mtime": 1790722729.1475766, - "ast_hash": "350d3ac11cb57db7093fcbcfcebd423a", + "mtime": 1790796927.2642908, + "ast_hash": "74a582531bcddde54964f93a79b24494", "semantic_hash": "" }, "D:\\Repositories\\server\\docs\\superpowers\\investidor10-wallet-spec.md": { - "mtime": 1790722776.4594035, - "ast_hash": "5b5eb1d6eb186eebcc200bc3b4f8d77c", + "mtime": 1790808403.552102, + "ast_hash": "65d55b3ae08cc3f49631aed7813c6eca", "semantic_hash": "" }, "D:\\Repositories\\server\\docs\\superpowers\\nginx-scaling-plan.md": { @@ -609,11 +669,21 @@ "ast_hash": "821d1ab64e7ea4f1a8903c26adcdffb8", "semantic_hash": "" }, + "D:\\Repositories\\server\\docs\\superpowers\\orunmila-harness-gaps.md": { + "mtime": 1790811138.244111, + "ast_hash": "89f83eff48117a8d76064a3c122a357f", + "semantic_hash": "" + }, "D:\\Repositories\\server\\docs\\superpowers\\uvicorn-worker-scaling-plan.md": { "mtime": 1790723409.2143178, "ast_hash": "5bc55983f02c9f640b96fe2ade89e7d2", "semantic_hash": "" }, + "D:\\Repositories\\server\\docs\\superpowers\\wallet-orchestrator-prompt.md": { + "mtime": 1790809389.5735018, + "ast_hash": "8c85c0d12852e051ed29945371763875", + "semantic_hash": "" + }, "D:\\Repositories\\server\\docs\\superpowers\\benchmarks\\stocks-cache-ttl.md": { "mtime": 1790725744.0210347, "ast_hash": "02bdda14a198a7ce352314ec84cd36a6", @@ -670,8 +740,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\docs\\superpowers\\plans\\2026-09-29-nginx-response-cache.md": { - "mtime": 1790716965.7762914, - "ast_hash": "81c18d85ba503d04f69a56700b821fd8", + "mtime": 1790744356.819669, + "ast_hash": "7c84290f4abbc549ec39f3bef36c2cb7", "semantic_hash": "" }, "D:\\Repositories\\server\\docs\\superpowers\\plans\\2026-09-29-stocks-cache-ttl.md": { @@ -689,6 +759,16 @@ "ast_hash": "99973b0d3da44a0a7cbc01959fc8157a", "semantic_hash": "" }, + "D:\\Repositories\\server\\docs\\superpowers\\plans\\2026-09-30-wallet-p1.md": { + "mtime": 1790809389.8345032, + "ast_hash": "5bdfad20f1fff5e0b9064fab31f91d14", + "semantic_hash": "" + }, + "D:\\Repositories\\server\\docs\\superpowers\\plans\\2026-10-01-wallet-p3.md": { + "mtime": 1790819692.9904158, + "ast_hash": "712c9020cdf419cfb288a3090f9a698f", + "semantic_hash": "" + }, "D:\\Repositories\\server\\docs\\superpowers\\specs\\2026-09-04-wallet-design.md": { "mtime": 1789266824.564381, "ast_hash": "3ad505fd6016388f87bd14fa8da4f40e", @@ -704,6 +784,11 @@ "ast_hash": "7bbc5e5a7693a5828d34f9f4d7eb8125", "semantic_hash": "" }, + "D:\\Repositories\\server\\frontend\\mock-wallet.html": { + "mtime": 1790826015.8223977, + "ast_hash": "b855d9b9d7adb55abf60a4228763ad2a", + "semantic_hash": "" + }, "D:\\Repositories\\server\\frontend\\pnpm-workspace.yaml": { "mtime": 1788633933.7987409, "ast_hash": "b742abf2d03aa9d79c3290767176eb41", diff --git a/main/app/scraper_b3/scraper.py b/main/app/scraper_b3/scraper.py index f0b2e9dd..8dedd4fc 100644 --- a/main/app/scraper_b3/scraper.py +++ b/main/app/scraper_b3/scraper.py @@ -26,9 +26,12 @@ warnings.filterwarnings("ignore", category=RuntimeWarning) + def getCurrentSelic(): - selic = pd.DataFrame(requests.get("https://api.bcb.gov.br/dados/serie/bcdata.sgs.4189/dados?formato=json", timeout=30).json()) - + selic = pd.DataFrame( + requests.get("https://api.bcb.gov.br/dados/serie/bcdata.sgs.4189/dados?formato=json", timeout=30).json() + ) + selic["valor"] = selic["valor"].astype(float) selic["valor medio 10y"] = selic["valor"].rolling(120, min_periods=120).mean().round(2) @@ -608,7 +611,9 @@ def exportMysql(self, df): for col in existingCols if any(pattern in col for pattern in historicalPatterns) and col not in JSON_COLUMNS ] - historicalCols = [col for col in historicalCols if re.compile(r"^[A-Za-z0-9][A-Za-z0-9 _]*$").match(col) is not None] + historicalCols = [ + col for col in historicalCols if re.compile(r"^[A-Za-z0-9][A-Za-z0-9 _]*$").match(col) is not None + ] if historicalCols: conn.execute( diff --git a/main/app/stocks_api/sync_cache.py b/main/app/stocks_api/sync_cache.py index 1c5d4f8c..c996d331 100644 --- a/main/app/stocks_api/sync_cache.py +++ b/main/app/stocks_api/sync_cache.py @@ -28,8 +28,9 @@ async def cachedCall() -> Any: return result return asyncio.run(cachedCall()) - + return wrapper # type: ignore[return-value] + return decorator diff --git a/main/app/wallet/market_data.py b/main/app/wallet/market_data.py index b17b4b10..bfe107d9 100644 --- a/main/app/wallet/market_data.py +++ b/main/app/wallet/market_data.py @@ -10,8 +10,6 @@ logger = logging.getLogger(__name__) -STOCKS_TIMEOUT = 3 - def fetchLivePrices(tickers: list[str]) -> dict[str, float | None]: if not tickers: @@ -24,7 +22,7 @@ def one(ticker: str) -> tuple[str, float | None]: f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/cotations/live", params={"search": ticker, "compact": False}, # type: ignore[arg-type] headers={"X-API-Key": key} if key else {}, - timeout=STOCKS_TIMEOUT, + timeout=3, ) if resp.status_code == 429: logger.warning("Live price quota exhausted for %s", ticker) @@ -46,7 +44,7 @@ def fetchCachedClose(ticker: str) -> float | None: f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/cotations", params={"search": ticker}, headers={"X-API-Key": key} if key else {}, - timeout=STOCKS_TIMEOUT, + timeout=3, ) if resp.status_code == 429: logger.warning("Cached close quota exhausted for %s", ticker) @@ -67,7 +65,7 @@ def fetchMarketDividends(ticker: str) -> list[dict]: f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/fundamental", params={"search": ticker, "fields": "HISTORICO DIVIDENDOS"}, # type: ignore[arg-type] headers={"X-API-Key": key} if key else {}, - timeout=STOCKS_TIMEOUT, + timeout=3, ) if resp.status_code != 200: return [] @@ -86,7 +84,7 @@ def fetchPadraoCloses(ticker: str) -> list[tuple[dateType, float]]: f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/cotations", params={"search": ticker}, headers={"X-API-Key": key} if key else {}, - timeout=STOCKS_TIMEOUT, + timeout=3, ) if resp.status_code != 200: return [] diff --git a/main/app/wallet/wallet_service.py b/main/app/wallet/wallet_service.py deleted file mode 100644 index a75169f1..00000000 --- a/main/app/wallet/wallet_service.py +++ /dev/null @@ -1,78 +0,0 @@ -import logging -from datetime import date as dateType - -from main.app.wallet.earnings import IR_RATE, TIPO_MAP, listEarnings, syncEarnings -from main.app.wallet.entries import ( - EntryCreate, - EntryUpdate, - addEntry, - applyEntries, - deleteEntry, - listEntries, - positionAtDate, - recalcHolding, - updateEntry, -) -from main.app.wallet.market_data import ( - STOCKS_TIMEOUT, - fetchCachedClose, - fetchLivePrices, - fetchMarketDividends, - fetchPadraoCloses, - stocksApiBase, - stocksApiHeaders, -) -from main.app.wallet.performance import PERFORMANCE_EPOCH, cachedPerformance, getPerformance -from main.app.wallet.positions import BUY_THRESHOLD, XANGO_WEIGHTS, fetchXangoScores, getPositions, scoreBuyFlag -from main.app.wallet.summary import ( - RatingUpsert, - TargetUpsert, - getAllocation, - getSummary, - set_rating, - upsertTarget, -) -from main.app.wallet.wallets import createWallet, getOwnedWallet, listWallets - -logger = logging.getLogger(__name__) - -__all__ = [ - "BUY_THRESHOLD", - "EntryCreate", - "EntryUpdate", - "IR_RATE", - "PERFORMANCE_EPOCH", - "RatingUpsert", - "STOCKS_TIMEOUT", - "TIPO_MAP", - "TargetUpsert", - "XANGO_WEIGHTS", - "addEntry", - "applyEntries", - "cachedPerformance", - "createWallet", - "dateType", - "deleteEntry", - "fetchCachedClose", - "fetchLivePrices", - "fetchMarketDividends", - "fetchPadraoCloses", - "fetchXangoScores", - "getAllocation", - "getOwnedWallet", - "getPerformance", - "getPositions", - "getSummary", - "listEarnings", - "listEntries", - "listWallets", - "positionAtDate", - "recalcHolding", - "scoreBuyFlag", - "set_rating", - "stocksApiBase", - "stocksApiHeaders", - "syncEarnings", - "updateEntry", - "upsertTarget", -] diff --git a/main/app/wallet/wallets.py b/main/app/wallet/wallets.py index fc90828d..58d7fbf5 100644 --- a/main/app/wallet/wallets.py +++ b/main/app/wallet/wallets.py @@ -9,7 +9,6 @@ def getWallet(db: Session, walletId: int, userId: int): - wallet = db.query(Wallet).filter(Wallet.walletId == walletId, Wallet.userId == userId).first() if wallet is None: raise HTTPException(status_code=404, detail="wallet not found") @@ -21,7 +20,6 @@ def createWallet(db: Session, userId: int, name: str) -> Wallet: db.add(wallet) db.commit() db.refresh(wallet) - return wallet From 3c0e843cfe867371105e3177c24fb251e2fc1a91 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 01:17:52 -0300 Subject: [PATCH 22/34] split narrate_positions into six granular wallet tools --- main/app/orunmila/tools.py | 260 +++++++++++++++++++++++++--- tests/test_orunmila_wallet_tools.py | 191 +++++++++++++++++--- 2 files changed, 406 insertions(+), 45 deletions(-) diff --git a/main/app/orunmila/tools.py b/main/app/orunmila/tools.py index 9549d30b..f8186a80 100644 --- a/main/app/orunmila/tools.py +++ b/main/app/orunmila/tools.py @@ -1,7 +1,8 @@ from config import SessionLocal import asyncio import logging -from typing import Any +from datetime import date as dateType +from typing import Any, Optional from urllib.parse import quote from fastapi import HTTPException @@ -178,21 +179,57 @@ async def serve_file(path: str, **_) -> dict: # -# wallet narration (read-only) +# wallet # -async def narrate_positions(wallet_id: int, **_) -> dict: - """Narrate the user's wallet positions in plain language. +async def get_wallet_positions(wallet_id: int, **_) -> dict: + """List wallet holdings with live prices, equity, allocation, and buy signals. - Read-only summary of holdings, allocation vs targets, buy signals, - and pending earnings. Never mutates wallet state. + Read-only: never mutates wallet state. Args: - wallet_id: Wallet to narrate (must belong to the caller) + wallet_id: Wallet to inspect (must belong to the caller) """ - from main.app.wallet.wallets import getWallet from main.app.wallet.positions import getPositions + from main.app.wallet.wallets import getWallet + + user = _.get("user") + if not user: + return {"error": "Authentication required"} + + db: Session | None = _.get("db") + ownSession = not db + if ownSession: + db = SessionLocal() + try: + userId = user["userId"] + try: + getWallet( + db, # type: ignore[arg-type] + wallet_id, + userId, + ) + except HTTPException: + return {"error": "not-owner"} + return getPositions( + db, # type: ignore[arg-type] + wallet_id, + userId, + ) + finally: + if ownSession: + db.close() # type: ignore[union-attr] + + +async def get_wallet_summary(wallet_id: int, **_) -> dict: + """Summarize applied capital, equity, and variation for a wallet. + + Read-only: never mutates wallet state. + + Args: + wallet_id: Wallet to summarize (must belong to the caller) + """ from main.app.wallet.summary import getSummary - from main.app.wallet.earnings import listEarnings + from main.app.wallet.wallets import getWallet user = _.get("user") if not user: @@ -212,39 +249,207 @@ async def narrate_positions(wallet_id: int, **_) -> dict: ) except HTTPException: return {"error": "not-owner"} - positionsView = getPositions( + return getSummary( db, # type: ignore[arg-type] wallet_id, userId, ) - summaryView = getSummary( + finally: + if ownSession: + db.close() # type: ignore[union-attr] + + +async def get_wallet_allocation(wallet_id: int, group_by: str = "ticker", **_) -> dict: + """Break wallet equity down by ticker or asset type. + + Read-only: never mutates wallet state. + + Args: + wallet_id: Wallet to inspect (must belong to the caller) + group_by: Grouping key — "ticker" or "assetType" (default "ticker") + """ + from main.app.wallet.summary import getAllocation + from main.app.wallet.wallets import getWallet + + user = _.get("user") + if not user: + return {"error": "Authentication required"} + + db: Session | None = _.get("db") + ownSession = not db + if ownSession: + db = SessionLocal() + try: + userId = user["userId"] + try: + getWallet( + db, # type: ignore[arg-type] + wallet_id, + userId, + ) + except HTTPException: + return {"error": "not-owner"} + return getAllocation( db, # type: ignore[arg-type] wallet_id, userId, + group_by, ) + finally: + if ownSession: + db.close() # type: ignore[union-attr] + + +async def list_wallet_earnings(wallet_id: int, status: Optional[str] = "A Receber", **_) -> dict: + """List accrued earnings (dividends, JSCP) for a wallet. + + Read-only: never mutates wallet state. + + Args: + wallet_id: Wallet to inspect (must belong to the caller) + status: Filter by status — "A Receber", "Recebido", or None for all (default "A Receber") + """ + from main.app.wallet.earnings import listEarnings + from main.app.wallet.wallets import getWallet + + user = _.get("user") + if not user: + return {"error": "Authentication required"} + + db: Session | None = _.get("db") + ownSession = not db + if ownSession: + db = SessionLocal() + try: + userId = user["userId"] try: - pendingCount = len( - listEarnings( - db, # type: ignore[arg-type] - wallet_id, - userId, - status="A Receber", - ) + getWallet( + db, # type: ignore[arg-type] + wallet_id, + userId, ) - except Exception: - pendingCount = 0 + except HTTPException: + return {"error": "not-owner"} + rows = listEarnings( + db, # type: ignore[arg-type] + wallet_id, + userId, + status=status, + ) return { "wallet_id": wallet_id, - "language": user.get("language", "pt-BR"), - "positions": positionsView.get("items", []), - "summary": summaryView, - "pending_earnings": pendingCount, + "status": status, + "earnings": [ + { + "earning_id": int(row.earningId), + "ticker": str(row.ticker), + "kind": str(row.kind), + "ex_date": str(row.exDate), + "pay_date": str(row.payDate), + "gross": float(row.gross), + "net": float(row.netIrAdjusted), + "status": str(row.status), + } + for row in rows + ], } finally: if ownSession: db.close() # type: ignore[union-attr] +async def get_wallet_performance( + wallet_id: int, from_date: str, to_date: str, ticker: Optional[str] = None, **_ +) -> dict: + """Compute time-weighted return, volatility, and dividends for a wallet or ticker. + + Read-only: never mutates wallet state. + + Args: + wallet_id: Wallet to inspect (must belong to the caller) + from_date: Window start as YYYY-MM-DD + to_date: Window end as YYYY-MM-DD + ticker: Optional single ticker; omit for the whole wallet + """ + from main.app.wallet.performance import getPerformance + from main.app.wallet.wallets import getWallet + + user = _.get("user") + if not user: + return {"error": "Authentication required"} + + try: + startDate = dateType.fromisoformat(from_date) + endDate = dateType.fromisoformat(to_date) + except ValueError: + return {"error": "invalid date, use YYYY-MM-DD"} + + db: Session | None = _.get("db") + ownSession = not db + if ownSession: + db = SessionLocal() + try: + userId = user["userId"] + try: + getWallet( + db, # type: ignore[arg-type] + wallet_id, + userId, + ) + except HTTPException: + return {"error": "not-owner"} + return getPerformance( + db, # type: ignore[arg-type] + wallet_id, + userId, + ticker, + startDate, + endDate, + ) + finally: + if ownSession: + db.close() # type: ignore[union-attr] + + +async def get_wallet_rebalance(wallet_id: int, **_) -> dict: + """Show weight-share rebalance deltas per ticker (buy/sell/hold). + + Read-only: never mutates wallet state. + + Args: + wallet_id: Wallet to inspect (must belong to the caller) + """ + from main.app.wallet.positions import getRebalance + from main.app.wallet.wallets import getWallet + + user = _.get("user") + if not user: + return {"error": "Authentication required"} + + db: Session | None = _.get("db") + ownSession = not db + if ownSession: + db = SessionLocal() + try: + userId = user["userId"] + try: + getWallet( + db, # type: ignore[arg-type] + wallet_id, + userId, + ) + except HTTPException: + return {"error": "not-owner"} + return getRebalance( + db, # type: ignore[arg-type] + wallet_id, + userId, + ) + finally: + if ownSession: + db.close() # type: ignore[union-attr] + + TOOL_REGISTRY: dict[str, Any] = { "search_memory": search_memory, "save_memory": save_memory, @@ -253,7 +458,12 @@ async def narrate_positions(wallet_id: int, **_) -> dict: "write_file": write_file, "list_files": list_files, "serve_file": serve_file, - "narrate_positions": narrate_positions, + "get_wallet_positions": get_wallet_positions, + "get_wallet_summary": get_wallet_summary, + "get_wallet_allocation": get_wallet_allocation, + "list_wallet_earnings": list_wallet_earnings, + "get_wallet_performance": get_wallet_performance, + "get_wallet_rebalance": get_wallet_rebalance, } diff --git a/tests/test_orunmila_wallet_tools.py b/tests/test_orunmila_wallet_tools.py index 7a98296e..2e0fb62d 100644 --- a/tests/test_orunmila_wallet_tools.py +++ b/tests/test_orunmila_wallet_tools.py @@ -1,18 +1,35 @@ +from datetime import date + import asyncio import inspect +import pytest import requests -from tests.conftest import make_wallet_client +import main.models.wallet # noqa: F401 from main.app.orunmila.tools import TOOL_REGISTRY +from main.models.wallet import Earning +from tests.conftest import make_wallet_client +WALLET_TOOLS = [ + "get_wallet_positions", + "get_wallet_summary", + "get_wallet_allocation", + "list_wallet_earnings", + "get_wallet_performance", + "get_wallet_rebalance", +] -def test_narrate_positions_registered_and_read_only(dbSession): - assert len(TOOL_REGISTRY) == 8 - assert "narrate_positions" in TOOL_REGISTRY - source = inspect.getsource(TOOL_REGISTRY["narrate_positions"]) - for writer in ("addEntry", "updateEntry", "deleteEntry", "upsertTarget", "setRating", "syncEarnings"): - assert writer not in source + +def test_wallet_tools_registered_and_read_only(dbSession): + assert len(TOOL_REGISTRY) == 13 + for name in WALLET_TOOLS: + assert name in TOOL_REGISTRY + assert "narrate_positions" not in TOOL_REGISTRY + for name in WALLET_TOOLS: + source = inspect.getsource(TOOL_REGISTRY[name]) + for writer in ("addEntry", "updateEntry", "deleteEntry", "upsertTarget", "setRating", "syncEarnings"): + assert writer not in source def _seed_wallet(dbSession): @@ -25,7 +42,7 @@ def _seed_wallet(dbSession): "side": "Compra", "asset_type": "Stock", "ticker": "PETR4", - "date": "2026-01-10", + "date": "2026-01-02", "quantity": 10, "price": 10.0, }, @@ -44,26 +61,160 @@ def json(): return Resp() -def test_narrate_positions_returns_read_view(dbSession, monkeypatch): +def _flat_series(url, params=None, headers=None, timeout=None): + class Resp: + status_code = 200 + + @staticmethod + def json(): + rows = [{"DATA": f"{day:02d}-01-2026", "PRECO": 10.0} for day in range(1, 10)] + rows += [{"DATA": "10-01-2026", "PRECO": 10.0}, {"DATA": "11-01-2026", "PRECO": 11.0}] + return {"data": rows} + + return Resp() + + +def _seed_earnings(dbSession, walletId): + dbSession.add( + Earning( + walletId=walletId, + ticker="PETR4", + kind="Div", + exDate=date(2026, 3, 1), + payDate=date(2026, 4, 1), + gross=10.0, + netIrAdjusted=10.0, + status="A Receber", + ) + ) + dbSession.add( + Earning( + walletId=walletId, + ticker="PETR4", + kind="JSCP", + exDate=date(2026, 3, 1), + payDate=date(2026, 4, 1), + gross=5.0, + netIrAdjusted=4.25, + status="Recebido", + ) + ) + dbSession.commit() + + +def test_get_wallet_positions_returns_read_view(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_ok) + walletId = _seed_wallet(dbSession) + result = asyncio.run( + TOOL_REGISTRY["get_wallet_positions"](wallet_id=walletId, user={"userId": 1, "language": "pt-BR"}, db=dbSession) + ) + assert result["items"][0]["ticker"] == "PETR4" + assert result["equity_total"] == 300.0 + + +def test_get_wallet_summary_returns_totals(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_ok) + walletId = _seed_wallet(dbSession) + result = asyncio.run(TOOL_REGISTRY["get_wallet_summary"](wallet_id=walletId, user={"userId": 1}, db=dbSession)) + assert result["applied"] == 100.0 + assert result["equity"] == 300.0 + assert result["variation"] == 200.0 + + +def test_get_wallet_allocation_groups_by_ticker_and_asset(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _live_ok) walletId = _seed_wallet(dbSession) + byTicker = asyncio.run(TOOL_REGISTRY["get_wallet_allocation"](wallet_id=walletId, user={"userId": 1}, db=dbSession)) + assert byTicker["items"][0]["key"] == "PETR4" + assert byTicker["equity_total"] == 300.0 + byAsset = asyncio.run( + TOOL_REGISTRY["get_wallet_allocation"]( + wallet_id=walletId, group_by="assetType", user={"userId": 1}, db=dbSession + ) + ) + assert byAsset["items"][0]["key"] == "Stock" + + +def test_list_wallet_earnings_filters_by_status(dbSession): + walletId = _seed_wallet(dbSession) + _seed_earnings(dbSession, walletId) + pending = asyncio.run(TOOL_REGISTRY["list_wallet_earnings"](wallet_id=walletId, user={"userId": 1}, db=dbSession)) + assert [row["kind"] for row in pending["earnings"]] == ["Div"] + assert pending["earnings"][0]["gross"] == 10.0 + received = asyncio.run( + TOOL_REGISTRY["list_wallet_earnings"](wallet_id=walletId, status="Recebido", user={"userId": 1}, db=dbSession) + ) + assert [row["kind"] for row in received["earnings"]] == ["JSCP"] + allRows = asyncio.run( + TOOL_REGISTRY["list_wallet_earnings"](wallet_id=walletId, status=None, user={"userId": 1}, db=dbSession) + ) + assert len(allRows["earnings"]) == 2 + + +def test_get_wallet_performance_returns_metrics(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _flat_series) + walletId = _seed_wallet(dbSession) + dbSession.add( + Earning( + walletId=walletId, + ticker="PETR4", + kind="Div", + exDate=date(2026, 1, 5), + payDate=date(2026, 2, 1), + gross=10.0, + netIrAdjusted=10.0, + status="Recebido", + ) + ) + dbSession.commit() result = asyncio.run( - TOOL_REGISTRY["narrate_positions"](wallet_id=walletId, user={"userId": 1, "language": "pt-BR"}, db=dbSession) + TOOL_REGISTRY["get_wallet_performance"]( + wallet_id=walletId, + from_date="2026-01-01", + to_date="2026-01-11", + ticker="PETR4", + user={"userId": 1}, + db=dbSession, + ) ) - assert result["wallet_id"] == walletId - assert result["language"] == "pt-BR" - assert result["positions"][0]["ticker"] == "PETR4" - assert "summary" in result and "pending_earnings" in result + assert result["twr"] == pytest.approx(0.21) + assert result["dividends_received"] == 10.0 -def test_narrate_positions_cross_user_denied(dbSession): +def test_get_wallet_performance_rejects_bad_date(dbSession): walletId = _seed_wallet(dbSession) result = asyncio.run( - TOOL_REGISTRY["narrate_positions"](wallet_id=walletId, user={"userId": 2, "language": "pt-BR"}, db=dbSession) + TOOL_REGISTRY["get_wallet_performance"]( + wallet_id=walletId, from_date="01/01/2026", to_date="2026-01-11", user={"userId": 1}, db=dbSession + ) ) - assert result == {"error": "not-owner"} + assert result == {"error": "invalid date, use YYYY-MM-DD"} -def test_narrate_positions_no_auth_no_data(): - result = asyncio.run(TOOL_REGISTRY["narrate_positions"](wallet_id=1)) - assert result == {"error": "Authentication required"} +def test_get_wallet_rebalance_single_holding_holds(dbSession, monkeypatch): + monkeypatch.setattr(requests, "get", _live_ok) + walletId = _seed_wallet(dbSession) + result = asyncio.run(TOOL_REGISTRY["get_wallet_rebalance"](wallet_id=walletId, user={"userId": 1}, db=dbSession)) + assert result["items"][0]["side"] == "hold" + assert result["items"][0]["target_pct"] == 1.0 + + +def test_wallet_tools_cross_user_denied(dbSession): + walletId = _seed_wallet(dbSession) + baseArgs = {"wallet_id": walletId, "user": {"userId": 2, "language": "pt-BR"}, "db": dbSession} + for name in WALLET_TOOLS: + args = dict(baseArgs) + if name == "get_wallet_performance": + args.update({"from_date": "2026-01-01", "to_date": "2026-01-11"}) + result = asyncio.run(TOOL_REGISTRY[name](**args)) + assert result == {"error": "not-owner"} + + +def test_wallet_tools_no_auth_no_data(): + baseArgs = {"wallet_id": 1} + for name in WALLET_TOOLS: + args = dict(baseArgs) + if name == "get_wallet_performance": + args.update({"from_date": "2026-01-01", "to_date": "2026-01-11"}) + result = asyncio.run(TOOL_REGISTRY[name](**args)) + assert result == {"error": "Authentication required"} From 2904fd0a637dd952696fcfee0ede7e5ba490e068 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 01:29:44 -0300 Subject: [PATCH 23/34] refactor wallet domains into manager classes --- main/app/orunmila/tools.py | 48 ++-- main/app/wallet/earnings.py | 158 ++++++------- main/app/wallet/entries.py | 264 +++++++++++----------- main/app/wallet/market_data.py | 148 +++++++------ main/app/wallet/performance.py | 313 +++++++++++++------------- main/app/wallet/positions.py | 318 +++++++++++++-------------- main/app/wallet/summary.py | 248 +++++++++++---------- main/app/wallet/wallet_service.py | 25 +++ main/app/wallet/wallets.py | 36 +-- main/controller/wallet_controller.py | 32 +-- tests/test_wallet_buy_flag.py | 24 +- 11 files changed, 834 insertions(+), 780 deletions(-) create mode 100644 main/app/wallet/wallet_service.py diff --git a/main/app/orunmila/tools.py b/main/app/orunmila/tools.py index f8186a80..aa32e807 100644 --- a/main/app/orunmila/tools.py +++ b/main/app/orunmila/tools.py @@ -189,8 +189,8 @@ async def get_wallet_positions(wallet_id: int, **_) -> dict: Args: wallet_id: Wallet to inspect (must belong to the caller) """ - from main.app.wallet.positions import getPositions - from main.app.wallet.wallets import getWallet + from main.app.wallet.positions import PositionsManager + from main.app.wallet.wallets import WalletsManager user = _.get("user") if not user: @@ -203,14 +203,14 @@ async def get_wallet_positions(wallet_id: int, **_) -> dict: try: userId = user["userId"] try: - getWallet( + WalletsManager.getWallet( db, # type: ignore[arg-type] wallet_id, userId, ) except HTTPException: return {"error": "not-owner"} - return getPositions( + return PositionsManager.getPositions( db, # type: ignore[arg-type] wallet_id, userId, @@ -228,8 +228,8 @@ async def get_wallet_summary(wallet_id: int, **_) -> dict: Args: wallet_id: Wallet to summarize (must belong to the caller) """ - from main.app.wallet.summary import getSummary - from main.app.wallet.wallets import getWallet + from main.app.wallet.summary import SummaryManager + from main.app.wallet.wallets import WalletsManager user = _.get("user") if not user: @@ -242,14 +242,14 @@ async def get_wallet_summary(wallet_id: int, **_) -> dict: try: userId = user["userId"] try: - getWallet( + WalletsManager.getWallet( db, # type: ignore[arg-type] wallet_id, userId, ) except HTTPException: return {"error": "not-owner"} - return getSummary( + return SummaryManager.getSummary( db, # type: ignore[arg-type] wallet_id, userId, @@ -268,8 +268,8 @@ async def get_wallet_allocation(wallet_id: int, group_by: str = "ticker", **_) - wallet_id: Wallet to inspect (must belong to the caller) group_by: Grouping key — "ticker" or "assetType" (default "ticker") """ - from main.app.wallet.summary import getAllocation - from main.app.wallet.wallets import getWallet + from main.app.wallet.summary import SummaryManager + from main.app.wallet.wallets import WalletsManager user = _.get("user") if not user: @@ -282,14 +282,14 @@ async def get_wallet_allocation(wallet_id: int, group_by: str = "ticker", **_) - try: userId = user["userId"] try: - getWallet( + WalletsManager.getWallet( db, # type: ignore[arg-type] wallet_id, userId, ) except HTTPException: return {"error": "not-owner"} - return getAllocation( + return SummaryManager.getAllocation( db, # type: ignore[arg-type] wallet_id, userId, @@ -309,8 +309,8 @@ async def list_wallet_earnings(wallet_id: int, status: Optional[str] = "A Recebe wallet_id: Wallet to inspect (must belong to the caller) status: Filter by status — "A Receber", "Recebido", or None for all (default "A Receber") """ - from main.app.wallet.earnings import listEarnings - from main.app.wallet.wallets import getWallet + from main.app.wallet.earnings import EarningsManager + from main.app.wallet.wallets import WalletsManager user = _.get("user") if not user: @@ -323,14 +323,14 @@ async def list_wallet_earnings(wallet_id: int, status: Optional[str] = "A Recebe try: userId = user["userId"] try: - getWallet( + WalletsManager.getWallet( db, # type: ignore[arg-type] wallet_id, userId, ) except HTTPException: return {"error": "not-owner"} - rows = listEarnings( + rows = EarningsManager.listEarnings( db, # type: ignore[arg-type] wallet_id, userId, @@ -371,8 +371,8 @@ async def get_wallet_performance( to_date: Window end as YYYY-MM-DD ticker: Optional single ticker; omit for the whole wallet """ - from main.app.wallet.performance import getPerformance - from main.app.wallet.wallets import getWallet + from main.app.wallet.performance import PerformanceManager + from main.app.wallet.wallets import WalletsManager user = _.get("user") if not user: @@ -391,14 +391,14 @@ async def get_wallet_performance( try: userId = user["userId"] try: - getWallet( + WalletsManager.getWallet( db, # type: ignore[arg-type] wallet_id, userId, ) except HTTPException: return {"error": "not-owner"} - return getPerformance( + return PerformanceManager.getPerformance( db, # type: ignore[arg-type] wallet_id, userId, @@ -419,8 +419,8 @@ async def get_wallet_rebalance(wallet_id: int, **_) -> dict: Args: wallet_id: Wallet to inspect (must belong to the caller) """ - from main.app.wallet.positions import getRebalance - from main.app.wallet.wallets import getWallet + from main.app.wallet.positions import PositionsManager + from main.app.wallet.wallets import WalletsManager user = _.get("user") if not user: @@ -433,14 +433,14 @@ async def get_wallet_rebalance(wallet_id: int, **_) -> dict: try: userId = user["userId"] try: - getWallet( + WalletsManager.getWallet( db, # type: ignore[arg-type] wallet_id, userId, ) except HTTPException: return {"error": "not-owner"} - return getRebalance( + return PositionsManager.getRebalance( db, # type: ignore[arg-type] wallet_id, userId, diff --git a/main/app/wallet/earnings.py b/main/app/wallet/earnings.py index 77aae943..c14223fa 100644 --- a/main/app/wallet/earnings.py +++ b/main/app/wallet/earnings.py @@ -4,9 +4,9 @@ from sqlalchemy.orm import Session -from main.app.wallet.entries import positionAtDate -from main.app.wallet.market_data import fetchMarketDividends -from main.app.wallet.wallets import getWallet +from main.app.wallet.entries import EntriesManager +from main.app.wallet.market_data import MarketDataManager +from main.app.wallet.wallets import WalletsManager from main.models.wallet import Earning, Holding, Transaction logger = logging.getLogger(__name__) @@ -21,94 +21,96 @@ } -def syncEarnings(db: Session, walletId: int, userId: int) -> dict: - getWallet(db, walletId, userId) +class EarningsManager: + @classmethod + def syncEarnings(cls, db: Session, walletId: int, userId: int) -> dict: + WalletsManager.getWallet(db, walletId, userId) - today = dateType.today() - accrued = 0 - skippedUnknown: list[str] = [] + today = dateType.today() + accrued = 0 + skippedUnknown: list[str] = [] - holdings = db.query(Holding).filter(Holding.walletId == walletId).all() - for holding in holdings: - if float(holding.quantity) <= 0: - continue - - holdingTicker = str(holding.ticker) - - ledgerEntries = ( - db.query(Transaction) - .filter(Transaction.walletId == walletId, Transaction.ticker == holdingTicker) - .order_by(Transaction.date, Transaction.entryId) - .all() - ) - - for record in fetchMarketDividends(holdingTicker): - label = str(record.get("TIPO PROVENTO")) - kind = TIPO_MAP.get(label) - - if kind is None: - if label not in skippedUnknown: - skippedUnknown.append(label) + holdings = db.query(Holding).filter(Holding.walletId == walletId).all() + for holding in holdings: + if float(holding.quantity) <= 0: continue - try: - exDate = datetime.strptime(record["DATA COM"], "%d-%m-%Y").date() - payDate = datetime.strptime(record["DATA PAGAMENTO"], "%d-%m-%Y").date() - perShare = float(record["VALOR AJUSTADO"]) - except Exception: - continue - - quantityAtEx = positionAtDate(ledgerEntries, exDate) - if quantityAtEx <= 0: - continue + holdingTicker = str(holding.ticker) - existing = ( - db.query(Earning) - .filter( - Earning.walletId == walletId, - Earning.ticker == holdingTicker, - Earning.exDate == exDate, - Earning.kind == kind, - ) - .first() + ledgerEntries = ( + db.query(Transaction) + .filter(Transaction.walletId == walletId, Transaction.ticker == holdingTicker) + .order_by(Transaction.date, Transaction.entryId) + .all() ) - if existing is not None: - continue - - gross = perShare * quantityAtEx - earning = Earning( - walletId=walletId, - ticker=holdingTicker, - kind=kind, - exDate=exDate, - payDate=payDate, - gross=gross, - netIrAdjusted=gross * (1 - IR_RATE[kind]), - status="Recebido" if payDate <= today else "A Receber", - ) + for record in MarketDataManager.fetchMarketDividends(holdingTicker): + label = str(record.get("TIPO PROVENTO")) + kind = TIPO_MAP.get(label) + + if kind is None: + if label not in skippedUnknown: + skippedUnknown.append(label) + continue + + try: + exDate = datetime.strptime(record["DATA COM"], "%d-%m-%Y").date() + payDate = datetime.strptime(record["DATA PAGAMENTO"], "%d-%m-%Y").date() + perShare = float(record["VALOR AJUSTADO"]) + except Exception: + continue + + quantityAtEx = EntriesManager.positionAtDate(ledgerEntries, exDate) + if quantityAtEx <= 0: + continue + + existing = ( + db.query(Earning) + .filter( + Earning.walletId == walletId, + Earning.ticker == holdingTicker, + Earning.exDate == exDate, + Earning.kind == kind, + ) + .first() + ) - db.add(earning) + if existing is not None: + continue + + gross = perShare * quantityAtEx + earning = Earning( + walletId=walletId, + ticker=holdingTicker, + kind=kind, + exDate=exDate, + payDate=payDate, + gross=gross, + netIrAdjusted=gross * (1 - IR_RATE[kind]), + status="Recebido" if payDate <= today else "A Receber", + ) - accrued += 1 - transitioned = 0 + db.add(earning) - pending = db.query(Earning).filter(Earning.walletId == walletId, Earning.status == "A Receber").all() - for earning in pending: - if str(earning.payDate) <= today.isoformat(): - earning.status = "Recebido" # type: ignore[assignment] - transitioned += 1 + accrued += 1 + transitioned = 0 - db.commit() + pending = db.query(Earning).filter(Earning.walletId == walletId, Earning.status == "A Receber").all() + for earning in pending: + if str(earning.payDate) <= today.isoformat(): + earning.status = "Recebido" # type: ignore[assignment] + transitioned += 1 - return {"accrued": accrued, "transitioned": transitioned, "skipped_unknown": skippedUnknown} + db.commit() + return {"accrued": accrued, "transitioned": transitioned, "skipped_unknown": skippedUnknown} -def listEarnings(db: Session, walletId: int, userId: int, status: str | None = None) -> list[Earning]: - getWallet(db, walletId, userId) - query = db.query(Earning).filter(Earning.walletId == walletId) + @classmethod + def listEarnings(cls, db: Session, walletId: int, userId: int, status: str | None = None) -> list[Earning]: + WalletsManager.getWallet(db, walletId, userId) + query = db.query(Earning).filter(Earning.walletId == walletId) - if status is not None: - query = query.filter(Earning.status == status) + if status is not None: + query = query.filter(Earning.status == status) - return query.order_by(Earning.exDate, Earning.earningId).all() + return query.order_by(Earning.exDate, Earning.earningId).all() diff --git a/main/app/wallet/entries.py b/main/app/wallet/entries.py index b007cdd5..73b9a2dc 100644 --- a/main/app/wallet/entries.py +++ b/main/app/wallet/entries.py @@ -6,7 +6,7 @@ from pydantic import BaseModel, Field from sqlalchemy.orm import Session -from main.app.wallet.wallets import getWallet +from main.app.wallet.wallets import WalletsManager from main.models.wallet import Holding, Transaction logger = logging.getLogger(__name__) @@ -30,166 +30,172 @@ class EntryUpdate(BaseModel): costs: float | None = Field(default=None, ge=0) -def applyEntries(quantity: float, avg: float, entries: list[Transaction]) -> tuple[float, float]: - for entry in entries: - entryQuantity = float(entry.quantity) - entryPrice = float(entry.price) - entryCosts = float(entry.costs) - - if entry.side == "Compra": - total = quantity * avg + entryQuantity * entryPrice + entryCosts - quantity += entryQuantity - avg = total / quantity - - else: - if entryQuantity > quantity: - raise HTTPException(status_code=422, detail="sell exceeds holding") - quantity -= entryQuantity - - return quantity, avg - - -def recalcHolding(db: Session, walletId: int, ticker: str) -> Holding | None: - entries = ( - db.query(Transaction) - .filter(Transaction.walletId == walletId, Transaction.ticker == ticker) - .order_by(Transaction.date, Transaction.entryId) - .all() - ) - - holding = db.query(Holding).filter(Holding.walletId == walletId, Holding.ticker == ticker).first() - - if not entries: - if holding is not None: - db.delete(holding) - return None - - quantity, avg = applyEntries(0.0, 0.0, entries) - if holding is None: - from main.app.wallet import positions as positionsModule - - xangoScore = positionsModule.fetchXangoScores((ticker,)).get(ticker) - holding = Holding( - walletId=walletId, - assetType=entries[0].assetType, - ticker=ticker, - quantity=quantity, - avgPrice=avg, - rating=xangoScore if xangoScore is not None else 10.0, # type: ignore[assignment] +class EntriesManager: + @classmethod + def applyEntries(cls, quantity: float, avg: float, entries: list[Transaction]) -> tuple[float, float]: + for entry in entries: + entryQuantity = float(entry.quantity) + entryPrice = float(entry.price) + entryCosts = float(entry.costs) + + if entry.side == "Compra": + total = quantity * avg + entryQuantity * entryPrice + entryCosts + quantity += entryQuantity + avg = total / quantity + + else: + if entryQuantity > quantity: + raise HTTPException(status_code=422, detail="sell exceeds holding") + quantity -= entryQuantity + + return quantity, avg + + @classmethod + def recalcHolding(cls, db: Session, walletId: int, ticker: str) -> Holding | None: + entries = ( + db.query(Transaction) + .filter(Transaction.walletId == walletId, Transaction.ticker == ticker) + .order_by(Transaction.date, Transaction.entryId) + .all() ) - db.add(holding) - else: - holding.quantity = quantity # type: ignore[assignment] - holding.avgPrice = avg # type: ignore[assignment] - - return holding - + holding = db.query(Holding).filter(Holding.walletId == walletId, Holding.ticker == ticker).first() -def addEntry(db: Session, userId: int, data: EntryCreate) -> tuple[Transaction, Holding | None]: - getWallet(db, data.wallet_id, userId) - if data.side == "Venda": - holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() - if holding is None or data.quantity > float(holding.quantity): - raise HTTPException(status_code=422, detail="sell exceeds holding") + if not entries: + if holding is not None: + db.delete(holding) + return None - entry = Transaction( - walletId=data.wallet_id, - side=data.side, - assetType=data.asset_type, - ticker=data.ticker, - date=data.date, - quantity=data.quantity, - price=data.price, - costs=data.costs, - ) + quantity, avg = cls.applyEntries(0.0, 0.0, entries) + if holding is None: + from main.app.wallet import positions as positionsModule - db.add(entry) - db.flush() + xangoScore = positionsModule.PositionsManager.fetchXangoScores((ticker,)).get(ticker) + holding = Holding( + walletId=walletId, + assetType=entries[0].assetType, + ticker=ticker, + quantity=quantity, + avgPrice=avg, + rating=xangoScore if xangoScore is not None else 10.0, # type: ignore[assignment] + ) - holding = recalcHolding(db, data.wallet_id, data.ticker) - - db.commit() - db.refresh(entry) + db.add(holding) + else: + holding.quantity = quantity # type: ignore[assignment] + holding.avgPrice = avg # type: ignore[assignment] + + return holding + + @classmethod + def addEntry(cls, db: Session, userId: int, data: EntryCreate) -> tuple[Transaction, Holding | None]: + WalletsManager.getWallet(db, data.wallet_id, userId) + if data.side == "Venda": + holding = ( + db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() + ) + if holding is None or data.quantity > float(holding.quantity): + raise HTTPException(status_code=422, detail="sell exceeds holding") - if holding is not None: - db.refresh(holding) + entry = Transaction( + walletId=data.wallet_id, + side=data.side, + assetType=data.asset_type, + ticker=data.ticker, + date=data.date, + quantity=data.quantity, + price=data.price, + costs=data.costs, + ) - return entry, holding + db.add(entry) + db.flush() + holding = cls.recalcHolding(db, data.wallet_id, data.ticker) -def listEntries( - db: Session, userId: int, walletId: int, ticker: str | None = None, limit: int = 20, offset: int = 0 -) -> tuple[int, list[Transaction]]: - getWallet(db, walletId, userId) - query = db.query(Transaction).filter(Transaction.walletId == walletId) + db.commit() + db.refresh(entry) - if ticker is not None: - query = query.filter(Transaction.ticker == ticker) + if holding is not None: + db.refresh(holding) - total = query.count() - items = query.order_by(Transaction.date, Transaction.entryId).offset(offset).limit(limit).all() + return entry, holding - return total, items + @classmethod + def listEntries( + cls, db: Session, userId: int, walletId: int, ticker: str | None = None, limit: int = 20, offset: int = 0 + ) -> tuple[int, list[Transaction]]: + WalletsManager.getWallet(db, walletId, userId) + query = db.query(Transaction).filter(Transaction.walletId == walletId) + if ticker is not None: + query = query.filter(Transaction.ticker == ticker) -def updateEntry(db: Session, userId: int, entryId: int, patch: EntryUpdate) -> tuple[Transaction, Holding | None]: - entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() + total = query.count() + items = query.order_by(Transaction.date, Transaction.entryId).offset(offset).limit(limit).all() - if entry is None: - raise HTTPException(status_code=404, detail="entry not found") + return total, items - getWallet(db, int(entry.walletId), userId) + @classmethod + def updateEntry( + cls, db: Session, userId: int, entryId: int, patch: EntryUpdate + ) -> tuple[Transaction, Holding | None]: + entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() - changes = patch.model_dump(exclude_unset=True) - for fieldName, fieldValue in changes.items(): - if fieldValue is not None: - setattr(entry, fieldName, fieldValue) + if entry is None: + raise HTTPException(status_code=404, detail="entry not found") - db.flush() + WalletsManager.getWallet(db, int(entry.walletId), userId) - try: - holding = recalcHolding(db, int(entry.walletId), str(entry.ticker)) - except HTTPException: - db.rollback() - raise + changes = patch.model_dump(exclude_unset=True) + for fieldName, fieldValue in changes.items(): + if fieldValue is not None: + setattr(entry, fieldName, fieldValue) - db.commit() - db.refresh(entry) + db.flush() - if holding is not None: - db.refresh(holding) + try: + holding = cls.recalcHolding(db, int(entry.walletId), str(entry.ticker)) + except HTTPException: + db.rollback() + raise - return entry, holding + db.commit() + db.refresh(entry) + if holding is not None: + db.refresh(holding) -def deleteEntry(db: Session, userId: int, entryId: int) -> tuple[int, Holding | None]: - entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() + return entry, holding - if entry is None: - raise HTTPException(status_code=404, detail="entry not found") + @classmethod + def deleteEntry(cls, db: Session, userId: int, entryId: int) -> tuple[int, Holding | None]: + entry = db.query(Transaction).filter(Transaction.entryId == entryId).first() - getWallet(db, int(entry.walletId), userId) + if entry is None: + raise HTTPException(status_code=404, detail="entry not found") - walletId = entry.walletId - ticker = entry.ticker + WalletsManager.getWallet(db, int(entry.walletId), userId) - db.delete(entry) - db.flush() + walletId = entry.walletId + ticker = entry.ticker - try: - holding = recalcHolding(db, int(walletId), str(ticker)) - except HTTPException: - db.rollback() - raise + db.delete(entry) + db.flush() - db.commit() + try: + holding = cls.recalcHolding(db, int(walletId), str(ticker)) + except HTTPException: + db.rollback() + raise - return entryId, holding + db.commit() + return entryId, holding -def positionAtDate(entries: list[Transaction], exDate: dateType) -> float: - datedEntries = [entry for entry in entries if str(entry.date) <= exDate.isoformat()] - quantity, _ = applyEntries(0.0, 0.0, datedEntries) + @classmethod + def positionAtDate(cls, entries: list[Transaction], exDate: dateType) -> float: + datedEntries = [entry for entry in entries if str(entry.date) <= exDate.isoformat()] + quantity, _ = cls.applyEntries(0.0, 0.0, datedEntries) - return quantity + return quantity diff --git a/main/app/wallet/market_data.py b/main/app/wallet/market_data.py index bfe107d9..cfb7b048 100644 --- a/main/app/wallet/market_data.py +++ b/main/app/wallet/market_data.py @@ -11,90 +11,94 @@ logger = logging.getLogger(__name__) -def fetchLivePrices(tickers: list[str]) -> dict[str, float | None]: - if not tickers: - return {} +class MarketDataManager: + @classmethod + def fetchLivePrices(cls, tickers: list[str]) -> dict[str, float | None]: + if not tickers: + return {} - def one(ticker: str) -> tuple[str, float | None]: + def one(ticker: str) -> tuple[str, float | None]: + try: + key = os.getenv("STOCKS_API_KEY", "") + resp = requests.get( + f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/cotations/live", + params={"search": ticker, "compact": False}, # type: ignore[arg-type] + headers={"X-API-Key": key} if key else {}, + timeout=3, + ) + if resp.status_code == 429: + logger.warning("Live price quota exhausted for %s", ticker) + return ticker, None + if resp.status_code != 200: + return ticker, None + return ticker, float(resp.json()["data"][0]["PRECO ATUAL"]) + except Exception: + return ticker, None + + with ThreadPoolExecutor(max_workers=min(8, max(1, len(tickers)))) as pool: + return dict(pool.map(one, tickers)) + + @classmethod + def fetchCachedClose(cls, ticker: str) -> float | None: try: key = os.getenv("STOCKS_API_KEY", "") resp = requests.get( - f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/cotations/live", - params={"search": ticker, "compact": False}, # type: ignore[arg-type] + f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/cotations", + params={"search": ticker}, headers={"X-API-Key": key} if key else {}, timeout=3, ) if resp.status_code == 429: - logger.warning("Live price quota exhausted for %s", ticker) - return ticker, None + logger.warning("Cached close quota exhausted for %s", ticker) + return None if resp.status_code != 200: - return ticker, None - return ticker, float(resp.json()["data"][0]["PRECO ATUAL"]) + return None + rows = resp.json()["data"] + latest = max(rows, key=lambda row: datetime.strptime(row["DATA"], "%d-%m-%Y")) + return float(latest["PRECO"]) except Exception: - return ticker, None - - with ThreadPoolExecutor(max_workers=min(8, max(1, len(tickers)))) as pool: - return dict(pool.map(one, tickers)) - - -def fetchCachedClose(ticker: str) -> float | None: - try: - key = os.getenv("STOCKS_API_KEY", "") - resp = requests.get( - f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/cotations", - params={"search": ticker}, - headers={"X-API-Key": key} if key else {}, - timeout=3, - ) - if resp.status_code == 429: - logger.warning("Cached close quota exhausted for %s", ticker) return None - if resp.status_code != 200: - return None - rows = resp.json()["data"] - latest = max(rows, key=lambda row: datetime.strptime(row["DATA"], "%d-%m-%Y")) - return float(latest["PRECO"]) - except Exception: - return None - -def fetchMarketDividends(ticker: str) -> list[dict]: - try: - key = os.getenv("STOCKS_API_KEY", "") - resp = requests.get( - f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/fundamental", - params={"search": ticker, "fields": "HISTORICO DIVIDENDOS"}, # type: ignore[arg-type] - headers={"X-API-Key": key} if key else {}, - timeout=3, - ) - if resp.status_code != 200: + @classmethod + def fetchMarketDividends(cls, ticker: str) -> list[dict]: + try: + key = os.getenv("STOCKS_API_KEY", "") + resp = requests.get( + f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/fundamental", + params={"search": ticker, "fields": "HISTORICO DIVIDENDOS"}, # type: ignore[arg-type] + headers={"X-API-Key": key} if key else {}, + timeout=3, + ) + if resp.status_code != 200: + return [] + payload = resp.json()["data"] + if payload and isinstance(payload[0], dict) and "HISTORICO DIVIDENDOS" in payload[0]: + return payload[0]["HISTORICO DIVIDENDOS"] + return payload + except Exception: return [] - payload = resp.json()["data"] - if payload and isinstance(payload[0], dict) and "HISTORICO DIVIDENDOS" in payload[0]: - return payload[0]["HISTORICO DIVIDENDOS"] - return payload - except Exception: - return [] - -def fetchPadraoCloses(ticker: str) -> list[tuple[dateType, float]]: - try: - key = os.getenv("STOCKS_API_KEY", "") - resp = requests.get( - f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/cotations", - params={"search": ticker}, - headers={"X-API-Key": key} if key else {}, - timeout=3, - ) - if resp.status_code != 200: + @classmethod + def fetchPadraoCloses(cls, ticker: str) -> list[tuple[dateType, float]]: + try: + key = os.getenv("STOCKS_API_KEY", "") + resp = requests.get( + f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/cotations", + params={"search": ticker}, + headers={"X-API-Key": key} if key else {}, + timeout=3, + ) + if resp.status_code != 200: + return [] + parsedCloses: list[tuple[dateType, float]] = [] + for closeRow in resp.json()["data"]: + try: + parsedCloses.append( + (datetime.strptime(closeRow["DATA"], "%d-%m-%Y").date(), float(closeRow["PRECO"])) + ) + except Exception: + continue + parsedCloses.sort(key=lambda closeItem: closeItem[0]) + return parsedCloses + except Exception: return [] - parsedCloses: list[tuple[dateType, float]] = [] - for closeRow in resp.json()["data"]: - try: - parsedCloses.append((datetime.strptime(closeRow["DATA"], "%d-%m-%Y").date(), float(closeRow["PRECO"]))) - except Exception: - continue - parsedCloses.sort(key=lambda closeItem: closeItem[0]) - return parsedCloses - except Exception: - return [] diff --git a/main/app/wallet/performance.py b/main/app/wallet/performance.py index 0bc78cd6..645ed607 100644 --- a/main/app/wallet/performance.py +++ b/main/app/wallet/performance.py @@ -7,9 +7,9 @@ from sqlalchemy.orm import Session -from main.app.wallet.entries import applyEntries -from main.app.wallet.market_data import fetchPadraoCloses -from main.app.wallet.wallets import getWallet +from main.app.wallet.entries import EntriesManager +from main.app.wallet.market_data import MarketDataManager +from main.app.wallet.wallets import WalletsManager from main.models.wallet import Earning, Transaction logger = logging.getLogger(__name__) @@ -17,161 +17,164 @@ PERFORMANCE_EPOCH = "1970-01-01T00:00:00" -@lru_cache(maxsize=1024) -def cachedPerformance( - walletId: int, - tickerKey: str, - fromIso: str, - toIso: str, - recalcKey: str, - entriesSnap: tuple[tuple[str, str, str, float, float, float, int], ...], - earningsSnap: tuple[tuple[str, str, float, float], ...], -) -> dict: - del recalcKey - - if tickerKey: - tickers = [tickerKey] - else: - universe = {entryTicker for entryTicker, _, _, _, _, _, _ in entriesSnap} - universe.update(earnTicker for earnTicker, _, _, _ in earningsSnap) - tickers = sorted(universe) - - perTickerDays: dict[str, dict[str, tuple[float, float, float]]] = {} - - dividendsReceived = 0.0 - for ticker in tickers: - for earnTicker, exIso, _, netValue in earningsSnap: - if earnTicker == ticker and fromIso <= exIso <= toIso: - dividendsReceived += netValue - - series = fetchPadraoCloses(ticker) - - tickerEntries = [ - (entryIso, entrySide, entryQty, entryPrice, entryCosts) - for entryTicker, entryIso, entrySide, entryQty, entryPrice, entryCosts, _ in entriesSnap - if entryTicker == ticker - ] - - baselineRows = [ - SimpleNamespace(side=entrySide, quantity=entryQty, price=entryPrice, costs=entryCosts) - for entryIso, entrySide, entryQty, entryPrice, entryCosts in tickerEntries - if entryIso < fromIso - ] - - positionQty, positionAvg = applyEntries(0.0, 0.0, baselineRows) # type: ignore[arg-type] - - entriesByDay: dict[str, list] = {} - for entryIso, entrySide, entryQty, entryPrice, entryCosts in tickerEntries: - if fromIso <= entryIso <= toIso: - entriesByDay.setdefault(entryIso, []).append( - SimpleNamespace(side=entrySide, quantity=entryQty, price=entryPrice, costs=entryCosts) +class PerformanceManager: + @classmethod + @lru_cache(maxsize=1024) + def cachedPerformance( + cls, + walletId: int, + tickerKey: str, + fromIso: str, + toIso: str, + recalcKey: str, + entriesSnap: tuple[tuple[str, str, str, float, float, float, int], ...], + earningsSnap: tuple[tuple[str, str, float, float], ...], + ) -> dict: + del recalcKey + + if tickerKey: + tickers = [tickerKey] + else: + universe = {entryTicker for entryTicker, _, _, _, _, _, _ in entriesSnap} + universe.update(earnTicker for earnTicker, _, _, _ in earningsSnap) + tickers = sorted(universe) + + perTickerDays: dict[str, dict[str, tuple[float, float, float]]] = {} + + dividendsReceived = 0.0 + for ticker in tickers: + for earnTicker, exIso, _, netValue in earningsSnap: + if earnTicker == ticker and fromIso <= exIso <= toIso: + dividendsReceived += netValue + + series = MarketDataManager.fetchPadraoCloses(ticker) + + tickerEntries = [ + (entryIso, entrySide, entryQty, entryPrice, entryCosts) + for entryTicker, entryIso, entrySide, entryQty, entryPrice, entryCosts, _ in entriesSnap + if entryTicker == ticker + ] + + baselineRows = [ + SimpleNamespace(side=entrySide, quantity=entryQty, price=entryPrice, costs=entryCosts) + for entryIso, entrySide, entryQty, entryPrice, entryCosts in tickerEntries + if entryIso < fromIso + ] + + positionQty, positionAvg = EntriesManager.applyEntries(0.0, 0.0, baselineRows) # type: ignore[arg-type] + + entriesByDay: dict[str, list] = {} + for entryIso, entrySide, entryQty, entryPrice, entryCosts in tickerEntries: + if fromIso <= entryIso <= toIso: + entriesByDay.setdefault(entryIso, []).append( + SimpleNamespace(side=entrySide, quantity=entryQty, price=entryPrice, costs=entryCosts) + ) + + closeByIso = { + closeDay.isoformat(): closePrice + for closeDay, closePrice in series + if fromIso <= closeDay.isoformat() <= toIso + } + + windowDays = sorted(closeByIso) + prevClose = None + for seriesDay, seriesClose in series: + if seriesDay.isoformat() < fromIso: + prevClose = seriesClose + else: + break + + dayMap: dict[str, tuple[float, float, float]] = {} + for dayIso in windowDays: + for datedRow in entriesByDay.get(dayIso, []): + positionQty, positionAvg = EntriesManager.applyEntries(positionQty, positionAvg, [datedRow]) # type: ignore[arg-type] + dayClose = closeByIso[dayIso] + + if positionQty > 0 and prevClose: + priceDay = (dayClose - prevClose) / prevClose + dividendYield = 0.0 + + for earnTicker, exIso, grossValue, _ in earningsSnap: + if earnTicker == ticker and exIso == dayIso: + dividendYield += (grossValue / positionQty) / prevClose + dayMap[dayIso] = (priceDay + dividendYield, priceDay, positionQty * prevClose) + + prevClose = dayClose + perTickerDays[ticker] = dayMap + + allDays = sorted({dayIso for dayMap in perTickerDays.values() for dayIso in dayMap}) + + dailyTotal: list[float] = [] + dailyPrice: list[float] = [] + for dayIso in allDays: + weightTotal = sum(dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) + if weightTotal > 0: + dailyTotal.append( + sum(dayMap[dayIso][0] * dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) + / weightTotal + ) + dailyPrice.append( + sum(dayMap[dayIso][1] * dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) + / weightTotal ) - closeByIso = { - closeDay.isoformat(): closePrice - for closeDay, closePrice in series - if fromIso <= closeDay.isoformat() <= toIso + twrValue = 1.0 + for dayReturn in dailyTotal: + twrValue *= 1 + dayReturn + + twrValue -= 1 + priceValue = 1.0 + for priceDay in dailyPrice: + priceValue *= 1 + priceDay + + priceValue -= 1 + spanDays = (dateType.fromisoformat(toIso) - dateType.fromisoformat(fromIso)).days + if spanDays <= 0: + annualizedValue = 0.0 + else: + annualizedValue = (1 + twrValue) ** (365 / spanDays) - 1 + + volatilityValue = stdev(dailyTotal) * sqrt(252) if len(dailyTotal) >= 2 else 0.0 + + return { + "twr": twrValue, + "twr_annualized": annualizedValue, + "volatility": volatilityValue, + "dividends_received": dividendsReceived, + "price_return": priceValue, } - windowDays = sorted(closeByIso) - prevClose = None - for seriesDay, seriesClose in series: - if seriesDay.isoformat() < fromIso: - prevClose = seriesClose - else: - break - - dayMap: dict[str, tuple[float, float, float]] = {} - for dayIso in windowDays: - for datedRow in entriesByDay.get(dayIso, []): - positionQty, positionAvg = applyEntries(positionQty, positionAvg, [datedRow]) # type: ignore[arg-type] - dayClose = closeByIso[dayIso] - - if positionQty > 0 and prevClose: - priceDay = (dayClose - prevClose) / prevClose - dividendYield = 0.0 - - for earnTicker, exIso, grossValue, _ in earningsSnap: - if earnTicker == ticker and exIso == dayIso: - dividendYield += (grossValue / positionQty) / prevClose - dayMap[dayIso] = (priceDay + dividendYield, priceDay, positionQty * prevClose) - - prevClose = dayClose - perTickerDays[ticker] = dayMap - - allDays = sorted({dayIso for dayMap in perTickerDays.values() for dayIso in dayMap}) - - dailyTotal: list[float] = [] - dailyPrice: list[float] = [] - for dayIso in allDays: - weightTotal = sum(dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) - if weightTotal > 0: - dailyTotal.append( - sum(dayMap[dayIso][0] * dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) - / weightTotal - ) - dailyPrice.append( - sum(dayMap[dayIso][1] * dayMap[dayIso][2] for dayMap in perTickerDays.values() if dayIso in dayMap) - / weightTotal + @classmethod + def getPerformance( + cls, db: Session, walletId: int, userId: int, ticker: str | None, startDate: dateType, endDate: dateType + ) -> dict: + wallet = WalletsManager.getWallet(db, walletId, userId) + recalcStamp = wallet.lastRecalc + recalcKey = str(recalcStamp) if recalcStamp is not None else PERFORMANCE_EPOCH + ledgerQuery = db.query(Transaction).filter(Transaction.walletId == walletId) + if ticker: + ledgerQuery = ledgerQuery.filter(Transaction.ticker == ticker) + ledgerRows = ledgerQuery.order_by(Transaction.date, Transaction.entryId).all() + entriesSnap = tuple( + ( + str(ledgerRow.ticker), + str(ledgerRow.date), + str(ledgerRow.side), + float(ledgerRow.quantity), + float(ledgerRow.price), + float(ledgerRow.costs), + int(ledgerRow.entryId), ) - - twrValue = 1.0 - for dayReturn in dailyTotal: - twrValue *= 1 + dayReturn - - twrValue -= 1 - priceValue = 1.0 - for priceDay in dailyPrice: - priceValue *= 1 + priceDay - - priceValue -= 1 - spanDays = (dateType.fromisoformat(toIso) - dateType.fromisoformat(fromIso)).days - if spanDays <= 0: - annualizedValue = 0.0 - else: - annualizedValue = (1 + twrValue) ** (365 / spanDays) - 1 - - volatilityValue = stdev(dailyTotal) * sqrt(252) if len(dailyTotal) >= 2 else 0.0 - - return { - "twr": twrValue, - "twr_annualized": annualizedValue, - "volatility": volatilityValue, - "dividends_received": dividendsReceived, - "price_return": priceValue, - } - - -def getPerformance( - db: Session, walletId: int, userId: int, ticker: str | None, startDate: dateType, endDate: dateType -) -> dict: - wallet = getWallet(db, walletId, userId) - recalcStamp = wallet.lastRecalc - recalcKey = str(recalcStamp) if recalcStamp is not None else PERFORMANCE_EPOCH - ledgerQuery = db.query(Transaction).filter(Transaction.walletId == walletId) - if ticker: - ledgerQuery = ledgerQuery.filter(Transaction.ticker == ticker) - ledgerRows = ledgerQuery.order_by(Transaction.date, Transaction.entryId).all() - entriesSnap = tuple( - ( - str(ledgerRow.ticker), - str(ledgerRow.date), - str(ledgerRow.side), - float(ledgerRow.quantity), - float(ledgerRow.price), - float(ledgerRow.costs), - int(ledgerRow.entryId), + for ledgerRow in ledgerRows + ) + earningQuery = db.query(Earning).filter(Earning.walletId == walletId) + if ticker: + earningQuery = earningQuery.filter(Earning.ticker == ticker) + earningRows = earningQuery.all() + earningsSnap = tuple( + (str(earningRow.ticker), str(earningRow.exDate), float(earningRow.gross), float(earningRow.netIrAdjusted)) + for earningRow in earningRows + ) + return cls.cachedPerformance( + walletId, ticker or "", startDate.isoformat(), endDate.isoformat(), recalcKey, entriesSnap, earningsSnap ) - for ledgerRow in ledgerRows - ) - earningQuery = db.query(Earning).filter(Earning.walletId == walletId) - if ticker: - earningQuery = earningQuery.filter(Earning.ticker == ticker) - earningRows = earningQuery.all() - earningsSnap = tuple( - (str(earningRow.ticker), str(earningRow.exDate), float(earningRow.gross), float(earningRow.netIrAdjusted)) - for earningRow in earningRows - ) - return cachedPerformance( - walletId, ticker or "", startDate.isoformat(), endDate.isoformat(), recalcKey, entriesSnap, earningsSnap - ) diff --git a/main/app/wallet/positions.py b/main/app/wallet/positions.py index 1aeb7acd..36b2f5a9 100644 --- a/main/app/wallet/positions.py +++ b/main/app/wallet/positions.py @@ -6,168 +6,168 @@ from sqlalchemy.orm import Session from config import Config -from main.app.wallet.market_data import fetchCachedClose, fetchLivePrices -from main.app.wallet.wallets import getWallet -from main.models.wallet import Holding +from main.app.wallet.market_data import MarketDataManager +from main.app.wallet.wallets import WalletsManager +from main.models.wallet import Holding, Target logger = logging.getLogger(__name__) -@lru_cache(maxsize=1024) -def fetchXangoScores(tickers: tuple[str, ...]) -> dict[str, float | None]: - """XANGO quality score per ticker (0-100 scale). - - One fundamental read per ticker; any per-ticker failure degrades to - None and scoreBuyFlag redistributes the xango weight over the other - inputs (flag degrades, never fails). Shared lru_cache is the - freshness story; no staleness gate beyond it, YAGNI. - """ - scores: dict[str, float | None] = {} - for ticker in tickers: - try: - key = os.getenv("STOCKS_API_KEY", "") - resp = requests.get( - f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/fundamental", - params={"search": ticker, "fields": "XANGO INVESTING SCORE", "compact": False}, # type: ignore[arg-type] - headers={"X-API-Key": key} if key else {}, - timeout=3, - ) - if resp.status_code != 200: +class PositionsManager: + @classmethod + @lru_cache(maxsize=1024) + def fetchXangoScores(cls, tickers: tuple[str, ...]) -> dict[str, float | None]: + """XANGO quality score per ticker (0-100 scale). + + One fundamental read per ticker; any per-ticker failure degrades to + None and scoreBuyFlag redistributes the xango weight over the other + inputs (flag degrades, never fails). Shared lru_cache is the + freshness story; no staleness gate beyond it, YAGNI. + """ + scores: dict[str, float | None] = {} + for ticker in tickers: + try: + key = os.getenv("STOCKS_API_KEY", "") + resp = requests.get( + f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/fundamental", + params={"search": ticker, "fields": "XANGO INVESTING SCORE", "compact": False}, # type: ignore[arg-type] + headers={"X-API-Key": key} if key else {}, + timeout=3, + ) + if resp.status_code != 200: + scores[ticker] = None + continue + payload = resp.json()["data"] + row = payload[0] if payload else None + if isinstance(row, dict) and "XANGO INVESTING SCORE" in row: + scores[ticker] = float(row["XANGO INVESTING SCORE"]) + else: + scores[ticker] = None + except Exception: scores[ticker] = None - continue - payload = resp.json()["data"] - row = payload[0] if payload else None - if isinstance(row, dict) and "XANGO INVESTING SCORE" in row: - scores[ticker] = float(row["XANGO INVESTING SCORE"]) + return scores + + @classmethod + def weightOf(cls, holding: Holding) -> float: + return float(holding.rating) if holding.rating is not None else 0.0 + + @classmethod + def pricePass( + cls, db: Session, walletId: int, userId: int + ) -> tuple[list[Holding], dict[str, float | None], dict[str, float | None], float]: + """Shared live-price/equity pass for positions + rebalance (single source, no duplication).""" + WalletsManager.getWallet(db, walletId, userId) + holdings = db.query(Holding).filter(Holding.walletId == walletId).all() + + tickers = [str(holding.ticker) for holding in holdings] + prices = MarketDataManager.fetchLivePrices(tickers) + for ticker, price in list(prices.items()): + if price is None: + prices[ticker] = MarketDataManager.fetchCachedClose(ticker) + + equities: dict[str, float | None] = {} + for holding in holdings: + price = prices.get(str(holding.ticker)) + equities[str(holding.ticker)] = float(holding.quantity) * price if price is not None else None + + equityTotal = sum(equity for equity in equities.values() if equity is not None) + return holdings, prices, equities, equityTotal + + @classmethod + def rebalanceDeltas( + cls, holdings: list[Holding], equities: dict[str, float | None], equityTotal: float + ) -> dict[str, float | None]: + """Weight-share deltas on backend floats: target_i = w_i/Σw, targetEquity = target_i × equityTotal, delta = targetEquity − equity. Σw=0 → all deltas null.""" + weightTotal = sum(cls.weightOf(holding) for holding in holdings) + deltas: dict[str, float | None] = {} + for holding in holdings: + ticker = str(holding.ticker) + equity = equities.get(ticker) + if not weightTotal or equity is None: + deltas[ticker] = None else: - scores[ticker] = None - except Exception: - scores[ticker] = None - return scores - - -def weightOf(holding: Holding) -> float: - return float(holding.rating) if holding.rating is not None else 0.0 - - -def pricePass( - db: Session, walletId: int, userId: int -) -> tuple[list[Holding], dict[str, float | None], dict[str, float | None], float]: - """Shared live-price/equity pass for positions + rebalance (single source, no duplication).""" - getWallet(db, walletId, userId) - holdings = db.query(Holding).filter(Holding.walletId == walletId).all() - - tickers = [str(holding.ticker) for holding in holdings] - prices = fetchLivePrices(tickers) - for ticker, price in list(prices.items()): - if price is None: - prices[ticker] = fetchCachedClose(ticker) - - equities: dict[str, float | None] = {} - for holding in holdings: - price = prices.get(str(holding.ticker)) - equities[str(holding.ticker)] = float(holding.quantity) * price if price is not None else None - - equityTotal = sum(equity for equity in equities.values() if equity is not None) - return holdings, prices, equities, equityTotal - - -def rebalanceDeltas( - holdings: list[Holding], equities: dict[str, float | None], equityTotal: float -) -> dict[str, float | None]: - """Weight-share deltas on backend floats: target_i = w_i/Σw, targetEquity = target_i × equityTotal, delta = targetEquity − equity. Σw=0 → all deltas null.""" - weightTotal = sum(weightOf(holding) for holding in holdings) - deltas: dict[str, float | None] = {} - for holding in holdings: - ticker = str(holding.ticker) - equity = equities.get(ticker) - if not weightTotal or equity is None: - deltas[ticker] = None - else: - deltas[ticker] = weightOf(holding) / weightTotal * equityTotal - equity - return deltas - - -def getPositions(db: Session, walletId: int, userId: int) -> dict: - from main.models.wallet import Target - - holdings, prices, equities, equityTotal = pricePass(db, walletId, userId) - deltas = rebalanceDeltas(holdings, equities, equityTotal) - - items = [] - for holding in holdings: - holdingQuantity = float(holding.quantity) - holdingAvg = float(holding.avgPrice) - price = prices.get(str(holding.ticker)) - equity = equities[str(holding.ticker)] - - if price is None or equity is None: - currentPrice = None - equityValue = None - appreciation = None - else: - currentPrice = price - equityValue = equity - appreciation = equity - holdingQuantity * holdingAvg - - percentWallet = (equity / equityTotal) if equity is not None and equityTotal else 0 - target = ( - db.query(Target) - .filter(Target.walletId == walletId, Target.keyKind == "ticker", Target.keyValue == holding.ticker) - .first() - ) - percentIdeal = float(target.percentIdeal) if target is not None else None - delta = deltas[str(holding.ticker)] - buyFlag = delta is not None and delta > 0 - items.append( - { - "ticker": holding.ticker, - "quantity": holdingQuantity, - "avgPrice": holdingAvg, - "current_price": currentPrice, - "equity": equityValue, - "appreciation": appreciation, - "percent_wallet": percentWallet, - "percent_ideal": percentIdeal, - "buy_flag": buyFlag, - } - ) - return {"items": items, "equity_total": equityTotal} - - -def getRebalance(db: Session, walletId: int, userId: int) -> dict: - holdings, prices, equities, equityTotal = pricePass(db, walletId, userId) - deltas = rebalanceDeltas(holdings, equities, equityTotal) - weightTotal = sum(weightOf(holding) for holding in holdings) - - items = [] - for holding in holdings: - ticker = str(holding.ticker) - weightFloat = weightOf(holding) - # Display rounds to int; all math above stays on backend floats. - weight = int(round(weightFloat)) - targetPct = (weightFloat / weightTotal) if weightTotal else 0.0 - equity = equities[ticker] - currentPct = (equity / equityTotal) if equity is not None and equityTotal else 0.0 - delta = deltas[ticker] - price = prices.get(ticker) - if delta is None or price is None: - deltaEquity = None - deltaQty = None - side = "hold" - else: - deltaEquity = delta - deltaQty = delta / price - side = "buy" if delta > 0 else "sell" if delta < 0 else "hold" - items.append( - { - "ticker": holding.ticker, - "weight": weight, - "target_pct": targetPct, - "current_pct": currentPct, - "delta_equity": deltaEquity, - "delta_qty": deltaQty, - "side": side, - } - ) - return {"items": items, "equity_total": equityTotal} + deltas[ticker] = cls.weightOf(holding) / weightTotal * equityTotal - equity + return deltas + + @classmethod + def getPositions(cls, db: Session, walletId: int, userId: int) -> dict: + holdings, prices, equities, equityTotal = cls.pricePass(db, walletId, userId) + deltas = cls.rebalanceDeltas(holdings, equities, equityTotal) + + items = [] + for holding in holdings: + holdingQuantity = float(holding.quantity) + holdingAvg = float(holding.avgPrice) + price = prices.get(str(holding.ticker)) + equity = equities[str(holding.ticker)] + + if price is None or equity is None: + currentPrice = None + equityValue = None + appreciation = None + else: + currentPrice = price + equityValue = equity + appreciation = equity - holdingQuantity * holdingAvg + + percentWallet = (equity / equityTotal) if equity is not None and equityTotal else 0 + target = ( + db.query(Target) + .filter(Target.walletId == walletId, Target.keyKind == "ticker", Target.keyValue == holding.ticker) + .first() + ) + percentIdeal = float(target.percentIdeal) if target is not None else None + delta = deltas[str(holding.ticker)] + buyFlag = delta is not None and delta > 0 + items.append( + { + "ticker": holding.ticker, + "quantity": holdingQuantity, + "avgPrice": holdingAvg, + "current_price": currentPrice, + "equity": equityValue, + "appreciation": appreciation, + "percent_wallet": percentWallet, + "percent_ideal": percentIdeal, + "buy_flag": buyFlag, + } + ) + return {"items": items, "equity_total": equityTotal} + + @classmethod + def getRebalance(cls, db: Session, walletId: int, userId: int) -> dict: + holdings, prices, equities, equityTotal = cls.pricePass(db, walletId, userId) + deltas = cls.rebalanceDeltas(holdings, equities, equityTotal) + weightTotal = sum(cls.weightOf(holding) for holding in holdings) + + items = [] + for holding in holdings: + ticker = str(holding.ticker) + weightFloat = cls.weightOf(holding) + # Display rounds to int; all math above stays on backend floats. + weight = int(round(weightFloat)) + targetPct = (weightFloat / weightTotal) if weightTotal else 0.0 + equity = equities[ticker] + currentPct = (equity / equityTotal) if equity is not None and equityTotal else 0.0 + delta = deltas[ticker] + price = prices.get(ticker) + if delta is None or price is None: + deltaEquity = None + deltaQty = None + side = "hold" + else: + deltaEquity = delta + deltaQty = delta / price + side = "buy" if delta > 0 else "sell" if delta < 0 else "hold" + items.append( + { + "ticker": holding.ticker, + "weight": weight, + "target_pct": targetPct, + "current_pct": currentPct, + "delta_equity": deltaEquity, + "delta_qty": deltaQty, + "side": side, + } + ) + return {"items": items, "equity_total": equityTotal} diff --git a/main/app/wallet/summary.py b/main/app/wallet/summary.py index 974bf30a..d74f661b 100644 --- a/main/app/wallet/summary.py +++ b/main/app/wallet/summary.py @@ -7,8 +7,8 @@ from pydantic import BaseModel, Field from sqlalchemy.orm import Session -from main.app.wallet.market_data import fetchCachedClose, fetchLivePrices -from main.app.wallet.wallets import getWallet +from main.app.wallet.market_data import MarketDataManager +from main.app.wallet.wallets import WalletsManager from main.models.wallet import Holding, Snapshot, Target logger = logging.getLogger(__name__) @@ -27,133 +27,141 @@ class RatingUpsert(BaseModel): rating: float = Field(ge=0, le=100) -def getSummary(db: Session, walletId: int, userId: int) -> dict: - wallet = getWallet(db, walletId, userId) - holdings = db.query(Holding).filter(Holding.walletId == walletId).all() - applied = sum(float(holding.quantity) * float(holding.avgPrice) for holding in holdings) - tickers = [str(holding.ticker) for holding in holdings] - prices = fetchLivePrices(tickers) - - for ticker, price in list(prices.items()): - if price is None: - prices[ticker] = fetchCachedClose(ticker) - - equity = 0.0 - for holding in holdings: - price = prices.get(str(holding.ticker)) - if price is not None: - equity += float(holding.quantity) * price - variation = equity - applied - - today = dateType.today() - - snapshot = db.query(Snapshot).filter(Snapshot.walletId == walletId, Snapshot.date == today).first() - if snapshot is None: - snapshot = Snapshot( - walletId=walletId, - date=today, - applied=applied, - equity=equity, - variation=variation, - profitTwr=None, - profitAmount=variation, - profitTwr12m=None, - profitTwr12mAmount=variation, - ) - db.add(snapshot) - else: - snapshot.applied = applied # type: ignore[assignment] - snapshot.equity = equity # type: ignore[assignment] - snapshot.variation = variation # type: ignore[assignment] - snapshot.profitTwr = None # type: ignore[assignment] - snapshot.profitAmount = variation # type: ignore[assignment] - snapshot.profitTwr12m = None # type: ignore[assignment] - snapshot.profitTwr12mAmount = variation # type: ignore[assignment] - - wallet.lastRecalc = datetime.now() - - db.commit() - - return { - "applied": applied, - "equity": equity, - "variation": variation, - "profit_twr": None, - "profit_amount": variation, - "profit_twr_12m": None, - "profit_twr_12m_amount": variation, - } - - -def getAllocation(db: Session, walletId: int, userId: int, groupBy: str) -> dict: - getWallet(db, walletId, userId) - holdings = db.query(Holding).filter(Holding.walletId == walletId).all() - - tickers = [str(holding.ticker) for holding in holdings] - prices = fetchLivePrices(tickers) - for ticker, price in list(prices.items()): - if price is None: - prices[ticker] = fetchCachedClose(ticker) - - groupEquity: dict[str, float] = {} - for holding in holdings: - price = prices.get(str(holding.ticker)) - holdingEquity = float(holding.quantity) * price if price is not None else 0.0 - groupKey = str(holding.ticker) if groupBy == "ticker" else str(holding.assetType) - groupEquity[groupKey] = groupEquity.get(groupKey, 0.0) + holdingEquity - - equityTotal = sum(groupEquity.values()) - items = [ - { - "key": groupKey, - "equity": groupValue, - "pct": (groupValue / equityTotal) if equityTotal else 0, +class SummaryManager: + @classmethod + def getSummary(cls, db: Session, walletId: int, userId: int) -> dict: + wallet = WalletsManager.getWallet(db, walletId, userId) + holdings = db.query(Holding).filter(Holding.walletId == walletId).all() + applied = sum(float(holding.quantity) * float(holding.avgPrice) for holding in holdings) + tickers = [str(holding.ticker) for holding in holdings] + prices = MarketDataManager.fetchLivePrices(tickers) + + for ticker, price in list(prices.items()): + if price is None: + prices[ticker] = MarketDataManager.fetchCachedClose(ticker) + + equity = 0.0 + for holding in holdings: + price = prices.get(str(holding.ticker)) + if price is not None: + equity += float(holding.quantity) * price + variation = equity - applied + + today = dateType.today() + + snapshot = db.query(Snapshot).filter(Snapshot.walletId == walletId, Snapshot.date == today).first() + if snapshot is None: + snapshot = Snapshot( + walletId=walletId, + date=today, + applied=applied, + equity=equity, + variation=variation, + profitTwr=None, + profitAmount=variation, + profitTwr12m=None, + profitTwr12mAmount=variation, + ) + db.add(snapshot) + else: + snapshot.applied = applied # type: ignore[assignment] + snapshot.equity = equity # type: ignore[assignment] + snapshot.variation = variation # type: ignore[assignment] + snapshot.profitTwr = None # type: ignore[assignment] + snapshot.profitAmount = variation # type: ignore[assignment] + snapshot.profitTwr12m = None # type: ignore[assignment] + snapshot.profitTwr12mAmount = variation # type: ignore[assignment] + + wallet.lastRecalc = datetime.now() + + db.commit() + + return { + "applied": applied, + "equity": equity, + "variation": variation, + "profit_twr": None, + "profit_amount": variation, + "profit_twr_12m": None, + "profit_twr_12m_amount": variation, } - for groupKey, groupValue in groupEquity.items() - ] - return {"items": items, "equity_total": equityTotal} + @classmethod + def getAllocation(cls, db: Session, walletId: int, userId: int, groupBy: str) -> dict: + WalletsManager.getWallet(db, walletId, userId) + holdings = db.query(Holding).filter(Holding.walletId == walletId).all() + + tickers = [str(holding.ticker) for holding in holdings] + prices = MarketDataManager.fetchLivePrices(tickers) + for ticker, price in list(prices.items()): + if price is None: + prices[ticker] = MarketDataManager.fetchCachedClose(ticker) + + groupEquity: dict[str, float] = {} + for holding in holdings: + price = prices.get(str(holding.ticker)) + holdingEquity = float(holding.quantity) * price if price is not None else 0.0 + groupKey = str(holding.ticker) if groupBy == "ticker" else str(holding.assetType) + groupEquity[groupKey] = groupEquity.get(groupKey, 0.0) + holdingEquity + + equityTotal = sum(groupEquity.values()) + items = [ + { + "key": groupKey, + "equity": groupValue, + "pct": (groupValue / equityTotal) if equityTotal else 0, + } + for groupKey, groupValue in groupEquity.items() + ] + + return {"items": items, "equity_total": equityTotal} + + @classmethod + def upsertTarget(cls, db: Session, userId: int, data: TargetUpsert) -> Target: + WalletsManager.getWallet(db, data.wallet_id, userId) + target = ( + db.query(Target) + .filter( + Target.walletId == data.wallet_id, + Target.keyKind == data.key_kind, + Target.keyValue == data.key_value, + ) + .first() + ) + if target is None: + target = Target( + walletId=data.wallet_id, + keyKind=data.key_kind, + keyValue=data.key_value, + percentIdeal=data.percent_ideal, + ) + db.add(target) + else: + target.percentIdeal = data.percent_ideal # type: ignore[assignment] -def upsertTarget(db: Session, userId: int, data: TargetUpsert) -> Target: - getWallet(db, data.wallet_id, userId) - target = ( - db.query(Target) - .filter( - Target.walletId == data.wallet_id, - Target.keyKind == data.key_kind, - Target.keyValue == data.key_value, - ) - .first() - ) - - if target is None: - target = Target( - walletId=data.wallet_id, - keyKind=data.key_kind, - keyValue=data.key_value, - percentIdeal=data.percent_ideal, - ) - db.add(target) - else: - target.percentIdeal = data.percent_ideal # type: ignore[assignment] + db.commit() + db.refresh(target) - db.commit() - db.refresh(target) + return target - return target + @classmethod + def set_rating(cls, db: Session, userId: int, data: RatingUpsert) -> Holding: + WalletsManager.getWallet(db, data.wallet_id, userId) + holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() + if holding is None: + raise HTTPException(status_code=404, detail="holding not found") -def set_rating(db: Session, userId: int, data: RatingUpsert) -> Holding: - getWallet(db, data.wallet_id, userId) - holding = db.query(Holding).filter(Holding.walletId == data.wallet_id, Holding.ticker == data.ticker).first() + holding.rating = data.rating # type: ignore[assignment] - if holding is None: - raise HTTPException(status_code=404, detail="holding not found") + db.commit() + db.refresh(holding) - holding.rating = data.rating # type: ignore[assignment] + return holding - db.commit() - db.refresh(holding) - return holding +# Digest-pinned alias: wallet_controller.py set_rating_route handler bytes are +# hashed by test_ratings_route_untouched, so the controller keeps calling +# summary.set_rating — this alias keeps that path resolving to the class. +set_rating = SummaryManager.set_rating diff --git a/main/app/wallet/wallet_service.py b/main/app/wallet/wallet_service.py new file mode 100644 index 00000000..399f30f2 --- /dev/null +++ b/main/app/wallet/wallet_service.py @@ -0,0 +1,25 @@ +import logging + +from main.app.wallet.earnings import EarningsManager +from main.app.wallet.entries import EntriesManager, EntryCreate, EntryUpdate +from main.app.wallet.market_data import MarketDataManager +from main.app.wallet.performance import PerformanceManager +from main.app.wallet.positions import PositionsManager +from main.app.wallet.summary import RatingUpsert, SummaryManager, TargetUpsert +from main.app.wallet.wallets import WalletsManager + +logger = logging.getLogger(__name__) + +__all__ = [ + "EarningsManager", + "EntriesManager", + "EntryCreate", + "EntryUpdate", + "MarketDataManager", + "PerformanceManager", + "PositionsManager", + "RatingUpsert", + "SummaryManager", + "TargetUpsert", + "WalletsManager", +] diff --git a/main/app/wallet/wallets.py b/main/app/wallet/wallets.py index 58d7fbf5..7f5eb312 100644 --- a/main/app/wallet/wallets.py +++ b/main/app/wallet/wallets.py @@ -8,20 +8,22 @@ logger = logging.getLogger(__name__) -def getWallet(db: Session, walletId: int, userId: int): - wallet = db.query(Wallet).filter(Wallet.walletId == walletId, Wallet.userId == userId).first() - if wallet is None: - raise HTTPException(status_code=404, detail="wallet not found") - return wallet - - -def createWallet(db: Session, userId: int, name: str) -> Wallet: - wallet = Wallet(userId=userId, name=name) - db.add(wallet) - db.commit() - db.refresh(wallet) - return wallet - - -def listWallets(db: Session, userId: int) -> list[Wallet]: - return db.query(Wallet).filter(Wallet.userId == userId).all() +class WalletsManager: + @classmethod + def getWallet(cls, db: Session, walletId: int, userId: int): + wallet = db.query(Wallet).filter(Wallet.walletId == walletId, Wallet.userId == userId).first() + if wallet is None: + raise HTTPException(status_code=404, detail="wallet not found") + return wallet + + @classmethod + def createWallet(cls, db: Session, userId: int, name: str) -> Wallet: + wallet = Wallet(userId=userId, name=name) + db.add(wallet) + db.commit() + db.refresh(wallet) + return wallet + + @classmethod + def listWallets(cls, db: Session, userId: int) -> list[Wallet]: + return db.query(Wallet).filter(Wallet.userId == userId).all() diff --git a/main/controller/wallet_controller.py b/main/controller/wallet_controller.py index b43b0372..c7cef447 100644 --- a/main/controller/wallet_controller.py +++ b/main/controller/wallet_controller.py @@ -27,7 +27,7 @@ def create_wallet_route( userId: int, db: Session = Depends(getSession), ): - wallet = wallets.createWallet(db, userId, payload.name) + wallet = wallets.WalletsManager.createWallet(db, userId, payload.name) return {"walletId": wallet.walletId, "name": wallet.name} @@ -38,7 +38,7 @@ def list_wallets_route( ): return [ {"walletId": walletItem.walletId, "name": walletItem.name, "lastRecalc": walletItem.lastRecalc} - for walletItem in wallets.listWallets(db, userId) + for walletItem in wallets.WalletsManager.listWallets(db, userId) ] @@ -68,7 +68,7 @@ def create_entry_route( userId: int, db: Session = Depends(getSession), ): - entry, holding = entries.addEntry(db, userId, payload) + entry, holding = entries.EntriesManager.addEntry(db, userId, payload) return {"entryId": entry.entryId, "holding": serialize_holding(holding)} @@ -81,7 +81,7 @@ def list_entries_route( userId: int = Query(), db: Session = Depends(getSession), ): - total, items = entries.listEntries(db, userId, wallet_id, ticker, limit, offset) + total, items = entries.EntriesManager.listEntries(db, userId, wallet_id, ticker, limit, offset) return {"total": total, "items": [serialize_entry(item) for item in items]} @@ -92,7 +92,7 @@ def update_entry_route( userId: int, db: Session = Depends(getSession), ): - entry, holding = entries.updateEntry(db, userId, entryId, payload) + entry, holding = entries.EntriesManager.updateEntry(db, userId, entryId, payload) return {"entryId": entry.entryId, "holding": serialize_holding(holding)} @@ -102,7 +102,7 @@ def delete_entry_route( userId: int, db: Session = Depends(getSession), ): - deletedId, holding = entries.deleteEntry(db, userId, entryId) + deletedId, holding = entries.EntriesManager.deleteEntry(db, userId, entryId) return {"entryId": deletedId, "holding": serialize_holding(holding)} @@ -112,7 +112,7 @@ def list_positions_route( userId: int, db: Session = Depends(getSession), ): - return positions.getPositions(db, wallet_id, userId) + return positions.PositionsManager.getPositions(db, wallet_id, userId) @router.get("/rebalance", response_class=ORJSONResponse) @@ -121,7 +121,7 @@ def get_rebalance_route( userId: int, db: Session = Depends(getSession), ): - return positions.getRebalance(db, wallet_id, userId) + return positions.PositionsManager.getRebalance(db, wallet_id, userId) @router.get("/summary", response_class=ORJSONResponse) @@ -130,7 +130,7 @@ def get_summary_route( userId: int, db: Session = Depends(getSession), ): - return summary.getSummary(db, wallet_id, userId) + return summary.SummaryManager.getSummary(db, wallet_id, userId) @router.get("/allocation", response_class=ORJSONResponse) @@ -140,7 +140,7 @@ def get_allocation_route( userId: int = Query(), db: Session = Depends(getSession), ): - return summary.getAllocation(db, wallet_id, userId, group_by) + return summary.SummaryManager.getAllocation(db, wallet_id, userId, group_by) @router.put("/targets", response_class=ORJSONResponse) @@ -149,7 +149,7 @@ def upsert_target_route( userId: int, db: Session = Depends(getSession), ): - target = summary.upsertTarget(db, userId, payload) + target = summary.SummaryManager.upsertTarget(db, userId, payload) return { "wallet_id": target.walletId, "key_kind": target.keyKind, @@ -189,7 +189,11 @@ def list_earnings_route( userId: int = Query(), db: Session = Depends(getSession), ): - return {"items": [serialize_earning(item) for item in earnings.listEarnings(db, wallet_id, userId, status)]} + return { + "items": [ + serialize_earning(item) for item in earnings.EarningsManager.listEarnings(db, wallet_id, userId, status) + ] + } @router.post("/earnings/sync", response_class=ORJSONResponse) @@ -198,7 +202,7 @@ def sync_earnings_route( userId: int, db: Session = Depends(getSession), ): - return earnings.syncEarnings(db, payload.wallet_id, userId) + return earnings.EarningsManager.syncEarnings(db, payload.wallet_id, userId) @router.get("/performance", response_class=ORJSONResponse) @@ -215,4 +219,4 @@ def get_performance_route( endDate = dateType.fromisoformat(toIso) except ValueError: raise HTTPException(status_code=422, detail="invalid date, expected YYYY-MM-DD") - return performance.getPerformance(db, wallet_id, userId, ticker, startDate, endDate) + return performance.PerformanceManager.getPerformance(db, wallet_id, userId, ticker, startDate, endDate) diff --git a/tests/test_wallet_buy_flag.py b/tests/test_wallet_buy_flag.py index e9136660..40ffd4e7 100644 --- a/tests/test_wallet_buy_flag.py +++ b/tests/test_wallet_buy_flag.py @@ -4,7 +4,7 @@ import requests import main.models.wallet # noqa: F401 -import main.app.wallet.positions as positions +from main.app.wallet.positions import PositionsManager from main.models.wallet import Holding from tests.conftest import make_wallet_client from tests.test_wallet_positions import _live_ok @@ -44,7 +44,7 @@ def _seed_two(client, walletId): def test_buy_flag_follows_delta_sign(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _live_two) - monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {ticker: 50.0 for ticker in tickers}) + monkeypatch.setattr(PositionsManager, "fetchXangoScores", lambda tickers: {ticker: 50.0 for ticker in tickers}) client, _, _ = make_wallet_client(db=dbSession) walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] _seed_two(client, walletId) @@ -63,7 +63,7 @@ def test_buy_flag_follows_delta_sign(dbSession, monkeypatch): def test_zero_weights_all_hold(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _live_two) - monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {ticker: None for ticker in tickers}) + monkeypatch.setattr(PositionsManager, "fetchXangoScores", lambda tickers: {ticker: None for ticker in tickers}) client, _, _ = make_wallet_client(db=dbSession) walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] _seed_two(client, walletId) @@ -80,7 +80,7 @@ def test_zero_weights_all_hold(dbSession, monkeypatch): def test_rebalance_weight_share_math(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _live_two) - monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {ticker: 50.0 for ticker in tickers}) + monkeypatch.setattr(PositionsManager, "fetchXangoScores", lambda tickers: {ticker: 50.0 for ticker in tickers}) client, _, _ = make_wallet_client(db=dbSession) walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] _seed_two(client, walletId) @@ -106,7 +106,7 @@ def test_rebalance_weight_share_math(dbSession, monkeypatch): def test_rebalance_deterministic(dbSession, monkeypatch): # Weight-share is a pure function of ratings + prices: same inputs → same outputs. monkeypatch.setattr(requests, "get", _live_two) - monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {ticker: 50.0 for ticker in tickers}) + monkeypatch.setattr(PositionsManager, "fetchXangoScores", lambda tickers: {ticker: 50.0 for ticker in tickers}) client, _, _ = make_wallet_client(db=dbSession) walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] _seed_two(client, walletId) @@ -123,7 +123,7 @@ def test_rebalance_deterministic(dbSession, monkeypatch): def test_new_holding_seeds_xango_score(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _live_ok) - monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {"PETR4": 80.0}) + monkeypatch.setattr(PositionsManager, "fetchXangoScores", lambda tickers: {"PETR4": 80.0}) client, _, _ = make_wallet_client(db=dbSession) walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] client.post( @@ -161,7 +161,7 @@ def test_new_holding_seeds_xango_score(dbSession, monkeypatch): def test_new_holding_defaults_ten_without_xango(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _live_ok) - monkeypatch.setattr(positions, "fetchXangoScores", lambda tickers: {"PETR4": None}) + monkeypatch.setattr(PositionsManager, "fetchXangoScores", lambda tickers: {"PETR4": None}) client, _, _ = make_wallet_client(db=dbSession) walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] client.post( @@ -209,7 +209,7 @@ def test_ratings_accept_zero_to_hundred(dbSession, monkeypatch): def test_fetch_xango_scores_parses_fundamental(monkeypatch): - positions.fetchXangoScores.cache_clear() + PositionsManager.fetchXangoScores.cache_clear() def fundamental_ok(url, params=None, headers=None, timeout=None): assert url.endswith("/stocks/fundamental") @@ -229,11 +229,11 @@ def boom(url, params=None, headers=None, timeout=None): raise requests.Timeout() monkeypatch.setattr(requests, "get", fundamental_ok) - assert positions.fetchXangoScores(("PETR4",)) == {"PETR4": 80.0} - positions.fetchXangoScores.cache_clear() + assert PositionsManager.fetchXangoScores(("PETR4",)) == {"PETR4": 80.0} + PositionsManager.fetchXangoScores.cache_clear() monkeypatch.setattr(requests, "get", boom) - assert positions.fetchXangoScores(("PETR4",)) == {"PETR4": None} - positions.fetchXangoScores.cache_clear() + assert PositionsManager.fetchXangoScores(("PETR4",)) == {"PETR4": None} + PositionsManager.fetchXangoScores.cache_clear() def test_ratings_route_untouched(): From f181ce48c762fc0e7e5fe335eaa6d0103e2e075e Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 01:42:35 -0300 Subject: [PATCH 24/34] use explicit wallet submodule imports --- main/app/wallet/entries.py | 4 +-- main/controller/wallet_controller.py | 42 ++++++++++++++-------------- tests/test_wallet_buy_flag.py | 2 +- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/main/app/wallet/entries.py b/main/app/wallet/entries.py index 73b9a2dc..9492a7dc 100644 --- a/main/app/wallet/entries.py +++ b/main/app/wallet/entries.py @@ -68,9 +68,9 @@ def recalcHolding(cls, db: Session, walletId: int, ticker: str) -> Holding | Non quantity, avg = cls.applyEntries(0.0, 0.0, entries) if holding is None: - from main.app.wallet import positions as positionsModule + from main.app.wallet.positions import PositionsManager - xangoScore = positionsModule.PositionsManager.fetchXangoScores((ticker,)).get(ticker) + xangoScore = PositionsManager.fetchXangoScores((ticker,)).get(ticker) holding = Holding( walletId=walletId, assetType=entries[0].assetType, diff --git a/main/controller/wallet_controller.py b/main/controller/wallet_controller.py index c7cef447..a56c9447 100644 --- a/main/controller/wallet_controller.py +++ b/main/controller/wallet_controller.py @@ -8,9 +8,13 @@ from typing import Literal from config import getSession -from main.app.wallet import earnings, entries, performance, positions, summary, wallets -from main.app.wallet.entries import EntryCreate, EntryUpdate -from main.app.wallet.summary import RatingUpsert, TargetUpsert +from main.app.wallet import summary # pinned: set_rating_route handler calls summary.set_rating (digest test) +from main.app.wallet.earnings import EarningsManager +from main.app.wallet.entries import EntriesManager, EntryCreate, EntryUpdate +from main.app.wallet.performance import PerformanceManager +from main.app.wallet.positions import PositionsManager +from main.app.wallet.summary import RatingUpsert, SummaryManager, TargetUpsert +from main.app.wallet.wallets import WalletsManager logger = logging.getLogger(__name__) @@ -27,7 +31,7 @@ def create_wallet_route( userId: int, db: Session = Depends(getSession), ): - wallet = wallets.WalletsManager.createWallet(db, userId, payload.name) + wallet = WalletsManager.createWallet(db, userId, payload.name) return {"walletId": wallet.walletId, "name": wallet.name} @@ -38,7 +42,7 @@ def list_wallets_route( ): return [ {"walletId": walletItem.walletId, "name": walletItem.name, "lastRecalc": walletItem.lastRecalc} - for walletItem in wallets.WalletsManager.listWallets(db, userId) + for walletItem in WalletsManager.listWallets(db, userId) ] @@ -68,7 +72,7 @@ def create_entry_route( userId: int, db: Session = Depends(getSession), ): - entry, holding = entries.EntriesManager.addEntry(db, userId, payload) + entry, holding = EntriesManager.addEntry(db, userId, payload) return {"entryId": entry.entryId, "holding": serialize_holding(holding)} @@ -81,7 +85,7 @@ def list_entries_route( userId: int = Query(), db: Session = Depends(getSession), ): - total, items = entries.EntriesManager.listEntries(db, userId, wallet_id, ticker, limit, offset) + total, items = EntriesManager.listEntries(db, userId, wallet_id, ticker, limit, offset) return {"total": total, "items": [serialize_entry(item) for item in items]} @@ -92,7 +96,7 @@ def update_entry_route( userId: int, db: Session = Depends(getSession), ): - entry, holding = entries.EntriesManager.updateEntry(db, userId, entryId, payload) + entry, holding = EntriesManager.updateEntry(db, userId, entryId, payload) return {"entryId": entry.entryId, "holding": serialize_holding(holding)} @@ -102,7 +106,7 @@ def delete_entry_route( userId: int, db: Session = Depends(getSession), ): - deletedId, holding = entries.EntriesManager.deleteEntry(db, userId, entryId) + deletedId, holding = EntriesManager.deleteEntry(db, userId, entryId) return {"entryId": deletedId, "holding": serialize_holding(holding)} @@ -112,7 +116,7 @@ def list_positions_route( userId: int, db: Session = Depends(getSession), ): - return positions.PositionsManager.getPositions(db, wallet_id, userId) + return PositionsManager.getPositions(db, wallet_id, userId) @router.get("/rebalance", response_class=ORJSONResponse) @@ -121,7 +125,7 @@ def get_rebalance_route( userId: int, db: Session = Depends(getSession), ): - return positions.PositionsManager.getRebalance(db, wallet_id, userId) + return PositionsManager.getRebalance(db, wallet_id, userId) @router.get("/summary", response_class=ORJSONResponse) @@ -130,7 +134,7 @@ def get_summary_route( userId: int, db: Session = Depends(getSession), ): - return summary.SummaryManager.getSummary(db, wallet_id, userId) + return SummaryManager.getSummary(db, wallet_id, userId) @router.get("/allocation", response_class=ORJSONResponse) @@ -140,7 +144,7 @@ def get_allocation_route( userId: int = Query(), db: Session = Depends(getSession), ): - return summary.SummaryManager.getAllocation(db, wallet_id, userId, group_by) + return SummaryManager.getAllocation(db, wallet_id, userId, group_by) @router.put("/targets", response_class=ORJSONResponse) @@ -149,7 +153,7 @@ def upsert_target_route( userId: int, db: Session = Depends(getSession), ): - target = summary.SummaryManager.upsertTarget(db, userId, payload) + target = SummaryManager.upsertTarget(db, userId, payload) return { "wallet_id": target.walletId, "key_kind": target.keyKind, @@ -189,11 +193,7 @@ def list_earnings_route( userId: int = Query(), db: Session = Depends(getSession), ): - return { - "items": [ - serialize_earning(item) for item in earnings.EarningsManager.listEarnings(db, wallet_id, userId, status) - ] - } + return {"items": [serialize_earning(item) for item in EarningsManager.listEarnings(db, wallet_id, userId, status)]} @router.post("/earnings/sync", response_class=ORJSONResponse) @@ -202,7 +202,7 @@ def sync_earnings_route( userId: int, db: Session = Depends(getSession), ): - return earnings.EarningsManager.syncEarnings(db, payload.wallet_id, userId) + return EarningsManager.syncEarnings(db, payload.wallet_id, userId) @router.get("/performance", response_class=ORJSONResponse) @@ -219,4 +219,4 @@ def get_performance_route( endDate = dateType.fromisoformat(toIso) except ValueError: raise HTTPException(status_code=422, detail="invalid date, expected YYYY-MM-DD") - return performance.PerformanceManager.getPerformance(db, wallet_id, userId, ticker, startDate, endDate) + return PerformanceManager.getPerformance(db, wallet_id, userId, ticker, startDate, endDate) diff --git a/tests/test_wallet_buy_flag.py b/tests/test_wallet_buy_flag.py index 40ffd4e7..6053a0f5 100644 --- a/tests/test_wallet_buy_flag.py +++ b/tests/test_wallet_buy_flag.py @@ -237,6 +237,6 @@ def boom(url, params=None, headers=None, timeout=None): def test_ratings_route_untouched(): - raw = open("main/controller/wallet_controller.py", "rb").read().splitlines(keepends=True)[161:169] + raw = open("main/controller/wallet_controller.py", "rb").read().splitlines(keepends=True)[165:173] digest = hashlib.sha256(b"".join(raw)).hexdigest() assert digest == RATINGS_ROUTE_DIGEST # any edit to set_rating_route fails loudly From 9ee747e4c9e5e27f0fe48bcf3ae31beff9a7ec90 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 01:52:09 -0300 Subject: [PATCH 25/34] hoist wallet inline imports to module top --- main/app/orunmila/tools.py | 23 +++++------------------ main/app/wallet/entries.py | 3 +-- 2 files changed, 6 insertions(+), 20 deletions(-) diff --git a/main/app/orunmila/tools.py b/main/app/orunmila/tools.py index aa32e807..980e822f 100644 --- a/main/app/orunmila/tools.py +++ b/main/app/orunmila/tools.py @@ -12,6 +12,11 @@ from main.app.orunmila.memory import OrunmilaMemory from main.app.orunmila.sandbox import SandboxManager, hostPath from main.app.orunmila.vector import embed +from main.app.wallet.earnings import EarningsManager +from main.app.wallet.performance import PerformanceManager +from main.app.wallet.positions import PositionsManager +from main.app.wallet.summary import SummaryManager +from main.app.wallet.wallets import WalletsManager logger = logging.getLogger(__name__) @@ -189,9 +194,6 @@ async def get_wallet_positions(wallet_id: int, **_) -> dict: Args: wallet_id: Wallet to inspect (must belong to the caller) """ - from main.app.wallet.positions import PositionsManager - from main.app.wallet.wallets import WalletsManager - user = _.get("user") if not user: return {"error": "Authentication required"} @@ -228,9 +230,6 @@ async def get_wallet_summary(wallet_id: int, **_) -> dict: Args: wallet_id: Wallet to summarize (must belong to the caller) """ - from main.app.wallet.summary import SummaryManager - from main.app.wallet.wallets import WalletsManager - user = _.get("user") if not user: return {"error": "Authentication required"} @@ -268,9 +267,6 @@ async def get_wallet_allocation(wallet_id: int, group_by: str = "ticker", **_) - wallet_id: Wallet to inspect (must belong to the caller) group_by: Grouping key — "ticker" or "assetType" (default "ticker") """ - from main.app.wallet.summary import SummaryManager - from main.app.wallet.wallets import WalletsManager - user = _.get("user") if not user: return {"error": "Authentication required"} @@ -309,9 +305,6 @@ async def list_wallet_earnings(wallet_id: int, status: Optional[str] = "A Recebe wallet_id: Wallet to inspect (must belong to the caller) status: Filter by status — "A Receber", "Recebido", or None for all (default "A Receber") """ - from main.app.wallet.earnings import EarningsManager - from main.app.wallet.wallets import WalletsManager - user = _.get("user") if not user: return {"error": "Authentication required"} @@ -371,9 +364,6 @@ async def get_wallet_performance( to_date: Window end as YYYY-MM-DD ticker: Optional single ticker; omit for the whole wallet """ - from main.app.wallet.performance import PerformanceManager - from main.app.wallet.wallets import WalletsManager - user = _.get("user") if not user: return {"error": "Authentication required"} @@ -419,9 +409,6 @@ async def get_wallet_rebalance(wallet_id: int, **_) -> dict: Args: wallet_id: Wallet to inspect (must belong to the caller) """ - from main.app.wallet.positions import PositionsManager - from main.app.wallet.wallets import WalletsManager - user = _.get("user") if not user: return {"error": "Authentication required"} diff --git a/main/app/wallet/entries.py b/main/app/wallet/entries.py index 9492a7dc..e1b97304 100644 --- a/main/app/wallet/entries.py +++ b/main/app/wallet/entries.py @@ -6,6 +6,7 @@ from pydantic import BaseModel, Field from sqlalchemy.orm import Session +from main.app.wallet.positions import PositionsManager from main.app.wallet.wallets import WalletsManager from main.models.wallet import Holding, Transaction @@ -68,8 +69,6 @@ def recalcHolding(cls, db: Session, walletId: int, ticker: str) -> Holding | Non quantity, avg = cls.applyEntries(0.0, 0.0, entries) if holding is None: - from main.app.wallet.positions import PositionsManager - xangoScore = PositionsManager.fetchXangoScores((ticker,)).get(ticker) holding = Holding( walletId=walletId, From f20ca167f4742499bd6a794ecc3c0ca1ce6f0ca7 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 02:01:15 -0300 Subject: [PATCH 26/34] replace wallet lru_cache with cashews memoization --- main/app/stocks_api/sync_cache.py | 8 +++++++- main/app/wallet/market_data.py | 28 +++++++--------------------- main/app/wallet/performance.py | 10 ++++++++-- main/app/wallet/positions.py | 13 ++++++++----- main/app/wallet/summary.py | 6 ++++-- tests/test_orunmila_wallet_tools.py | 10 ++++++++++ tests/test_wallet_buy_flag.py | 14 +++++++++++--- tests/test_wallet_earnings.py | 11 +++++++++++ tests/test_wallet_entries.py | 12 ++++++++++++ tests/test_wallet_performance.py | 10 ++++++++++ tests/test_wallet_positions.py | 11 +++++++++++ tests/test_wallet_summary.py | 11 +++++++++++ 12 files changed, 110 insertions(+), 34 deletions(-) diff --git a/main/app/stocks_api/sync_cache.py b/main/app/stocks_api/sync_cache.py index c996d331..67c8718d 100644 --- a/main/app/stocks_api/sync_cache.py +++ b/main/app/stocks_api/sync_cache.py @@ -1,4 +1,5 @@ import asyncio +import concurrent.futures import inspect from functools import wraps from typing import Any, Callable, TypeVar @@ -27,7 +28,12 @@ async def cachedCall() -> Any: await cashews.cache.set(cache_key, result, expire=ttl) return result - return asyncio.run(cachedCall()) + try: + asyncio.get_running_loop() + except RuntimeError: + return asyncio.run(cachedCall()) + with concurrent.futures.ThreadPoolExecutor(max_workers=1) as pool: + return pool.submit(lambda: asyncio.run(cachedCall())).result() return wrapper # type: ignore[return-value] diff --git a/main/app/wallet/market_data.py b/main/app/wallet/market_data.py index cfb7b048..6f781995 100644 --- a/main/app/wallet/market_data.py +++ b/main/app/wallet/market_data.py @@ -6,13 +6,19 @@ import requests +from cashews import cache as cashewsCache + from config import Config +from main.app.stocks_api.sync_cache import cache as walletCache logger = logging.getLogger(__name__) +cashewsCache.setup("mem://") + class MarketDataManager: @classmethod + @walletCache(ttl="15s", key="wallet:live:{tickers}") def fetchLivePrices(cls, tickers: list[str]) -> dict[str, float | None]: if not tickers: return {} @@ -38,27 +44,6 @@ def one(ticker: str) -> tuple[str, float | None]: with ThreadPoolExecutor(max_workers=min(8, max(1, len(tickers)))) as pool: return dict(pool.map(one, tickers)) - @classmethod - def fetchCachedClose(cls, ticker: str) -> float | None: - try: - key = os.getenv("STOCKS_API_KEY", "") - resp = requests.get( - f"http://{Config.STOCKS_API.HOST}:{Config.STOCKS_API.PORT}/stocks/cotations", - params={"search": ticker}, - headers={"X-API-Key": key} if key else {}, - timeout=3, - ) - if resp.status_code == 429: - logger.warning("Cached close quota exhausted for %s", ticker) - return None - if resp.status_code != 200: - return None - rows = resp.json()["data"] - latest = max(rows, key=lambda row: datetime.strptime(row["DATA"], "%d-%m-%Y")) - return float(latest["PRECO"]) - except Exception: - return None - @classmethod def fetchMarketDividends(cls, ticker: str) -> list[dict]: try: @@ -79,6 +64,7 @@ def fetchMarketDividends(cls, ticker: str) -> list[dict]: return [] @classmethod + @walletCache(ttl="6h", key="wallet:closes:{ticker}") def fetchPadraoCloses(cls, ticker: str) -> list[tuple[dateType, float]]: try: key = os.getenv("STOCKS_API_KEY", "") diff --git a/main/app/wallet/performance.py b/main/app/wallet/performance.py index 645ed607..20c91e9c 100644 --- a/main/app/wallet/performance.py +++ b/main/app/wallet/performance.py @@ -1,12 +1,13 @@ import logging from datetime import date as dateType -from functools import lru_cache from math import sqrt from statistics import stdev from types import SimpleNamespace +from cashews import cache as cashewsCache from sqlalchemy.orm import Session +from main.app.stocks_api.sync_cache import cache as walletCache from main.app.wallet.entries import EntriesManager from main.app.wallet.market_data import MarketDataManager from main.app.wallet.wallets import WalletsManager @@ -14,12 +15,17 @@ logger = logging.getLogger(__name__) +cashewsCache.setup("mem://") + PERFORMANCE_EPOCH = "1970-01-01T00:00:00" class PerformanceManager: @classmethod - @lru_cache(maxsize=1024) + @walletCache( + ttl="6h", + key="wallet:performance:{walletId}:{tickerKey}:{fromIso}:{toIso}:{recalcKey}:{entriesSnap}:{earningsSnap}", + ) def cachedPerformance( cls, walletId: int, diff --git a/main/app/wallet/positions.py b/main/app/wallet/positions.py index 36b2f5a9..78b1f635 100644 --- a/main/app/wallet/positions.py +++ b/main/app/wallet/positions.py @@ -1,27 +1,30 @@ import logging import os -from functools import lru_cache import requests +from cashews import cache as cashewsCache from sqlalchemy.orm import Session from config import Config +from main.app.stocks_api.sync_cache import cache as walletCache from main.app.wallet.market_data import MarketDataManager from main.app.wallet.wallets import WalletsManager from main.models.wallet import Holding, Target logger = logging.getLogger(__name__) +cashewsCache.setup("mem://") + class PositionsManager: @classmethod - @lru_cache(maxsize=1024) + @walletCache(ttl="6h", key="wallet:xango:{tickers}") def fetchXangoScores(cls, tickers: tuple[str, ...]) -> dict[str, float | None]: """XANGO quality score per ticker (0-100 scale). One fundamental read per ticker; any per-ticker failure degrades to None and scoreBuyFlag redistributes the xango weight over the other - inputs (flag degrades, never fails). Shared lru_cache is the + inputs (flag degrades, never fails). Shared cashews entry is the freshness story; no staleness gate beyond it, YAGNI. """ scores: dict[str, float | None] = {} @@ -55,7 +58,6 @@ def weightOf(cls, holding: Holding) -> float: def pricePass( cls, db: Session, walletId: int, userId: int ) -> tuple[list[Holding], dict[str, float | None], dict[str, float | None], float]: - """Shared live-price/equity pass for positions + rebalance (single source, no duplication).""" WalletsManager.getWallet(db, walletId, userId) holdings = db.query(Holding).filter(Holding.walletId == walletId).all() @@ -63,7 +65,8 @@ def pricePass( prices = MarketDataManager.fetchLivePrices(tickers) for ticker, price in list(prices.items()): if price is None: - prices[ticker] = MarketDataManager.fetchCachedClose(ticker) + closes = MarketDataManager.fetchPadraoCloses(ticker) + prices[ticker] = closes[-1][1] if closes else None equities: dict[str, float | None] = {} for holding in holdings: diff --git a/main/app/wallet/summary.py b/main/app/wallet/summary.py index d74f661b..e990ff9d 100644 --- a/main/app/wallet/summary.py +++ b/main/app/wallet/summary.py @@ -38,7 +38,8 @@ def getSummary(cls, db: Session, walletId: int, userId: int) -> dict: for ticker, price in list(prices.items()): if price is None: - prices[ticker] = MarketDataManager.fetchCachedClose(ticker) + closes = MarketDataManager.fetchPadraoCloses(ticker) + prices[ticker] = closes[-1][1] if closes else None equity = 0.0 for holding in holdings: @@ -95,7 +96,8 @@ def getAllocation(cls, db: Session, walletId: int, userId: int, groupBy: str) -> prices = MarketDataManager.fetchLivePrices(tickers) for ticker, price in list(prices.items()): if price is None: - prices[ticker] = MarketDataManager.fetchCachedClose(ticker) + closes = MarketDataManager.fetchPadraoCloses(ticker) + prices[ticker] = closes[-1][1] if closes else None groupEquity: dict[str, float] = {} for holding in holdings: diff --git a/tests/test_orunmila_wallet_tools.py b/tests/test_orunmila_wallet_tools.py index 2e0fb62d..c1cc66b6 100644 --- a/tests/test_orunmila_wallet_tools.py +++ b/tests/test_orunmila_wallet_tools.py @@ -21,6 +21,16 @@ ] +@pytest.fixture(autouse=True) +async def clear_cashews_cache(): + from cashews import cache as cashewsCache + + cashewsCache.setup("mem://") + await cashewsCache.clear() + yield + await cashewsCache.clear() + + def test_wallet_tools_registered_and_read_only(dbSession): assert len(TOOL_REGISTRY) == 13 for name in WALLET_TOOLS: diff --git a/tests/test_wallet_buy_flag.py b/tests/test_wallet_buy_flag.py index 6053a0f5..2910943f 100644 --- a/tests/test_wallet_buy_flag.py +++ b/tests/test_wallet_buy_flag.py @@ -1,7 +1,9 @@ +import asyncio import hashlib import pytest import requests +from cashews import cache as cashewsCache import main.models.wallet # noqa: F401 from main.app.wallet.positions import PositionsManager @@ -12,6 +14,14 @@ RATINGS_ROUTE_DIGEST = "3a050b055866190a8142ddaca2ce916efd864d31496d90b959043c4ba484e334" +@pytest.fixture(autouse=True) +async def clear_cashews_cache(): + cashewsCache.setup("mem://") + await cashewsCache.clear() + yield + await cashewsCache.clear() + + def _live_two(url, params=None, headers=None, timeout=None): quotes = {"PETR4": 30.0, "VALE3": 10.0} @@ -209,7 +219,6 @@ def test_ratings_accept_zero_to_hundred(dbSession, monkeypatch): def test_fetch_xango_scores_parses_fundamental(monkeypatch): - PositionsManager.fetchXangoScores.cache_clear() def fundamental_ok(url, params=None, headers=None, timeout=None): assert url.endswith("/stocks/fundamental") @@ -230,10 +239,9 @@ def boom(url, params=None, headers=None, timeout=None): monkeypatch.setattr(requests, "get", fundamental_ok) assert PositionsManager.fetchXangoScores(("PETR4",)) == {"PETR4": 80.0} - PositionsManager.fetchXangoScores.cache_clear() + asyncio.run(cashewsCache.clear()) monkeypatch.setattr(requests, "get", boom) assert PositionsManager.fetchXangoScores(("PETR4",)) == {"PETR4": None} - PositionsManager.fetchXangoScores.cache_clear() def test_ratings_route_untouched(): diff --git a/tests/test_wallet_earnings.py b/tests/test_wallet_earnings.py index e4f7043e..015e4b46 100644 --- a/tests/test_wallet_earnings.py +++ b/tests/test_wallet_earnings.py @@ -1,3 +1,4 @@ +import pytest import requests from freezegun import freeze_time @@ -5,6 +6,16 @@ from tests.conftest import make_wallet_client +@pytest.fixture(autouse=True) +async def clear_cashews_cache(): + from cashews import cache as cashewsCache + + cashewsCache.setup("mem://") + await cashewsCache.clear() + yield + await cashewsCache.clear() + + def _div_fundamental(url, params=None, headers=None, timeout=None): class Resp: status_code = 200 diff --git a/tests/test_wallet_entries.py b/tests/test_wallet_entries.py index e37d0076..4c9eb8a0 100644 --- a/tests/test_wallet_entries.py +++ b/tests/test_wallet_entries.py @@ -1,7 +1,19 @@ +import pytest + import main.models.wallet # noqa: F401 from tests.conftest import make_wallet_client +@pytest.fixture(autouse=True) +async def clear_cashews_cache(): + from cashews import cache as cashewsCache + + cashewsCache.setup("mem://") + await cashewsCache.clear() + yield + await cashewsCache.clear() + + def test_compra_average_includes_costs(dbSession): client, _, _ = make_wallet_client(db=dbSession) walletId = client.post("/wallet/wallets", json={"name": "W"}).json()["walletId"] diff --git a/tests/test_wallet_performance.py b/tests/test_wallet_performance.py index d7ff3363..fc71d17a 100644 --- a/tests/test_wallet_performance.py +++ b/tests/test_wallet_performance.py @@ -8,6 +8,16 @@ from tests.conftest import make_wallet_client +@pytest.fixture(autouse=True) +async def clear_cashews_cache(): + from cashews import cache as cashewsCache + + cashewsCache.setup("mem://") + await cashewsCache.clear() + yield + await cashewsCache.clear() + + def _flat_series_with_one_div(url, params=None, headers=None, timeout=None): class Resp: status_code = 200 diff --git a/tests/test_wallet_positions.py b/tests/test_wallet_positions.py index 74dd6afc..394f9a23 100644 --- a/tests/test_wallet_positions.py +++ b/tests/test_wallet_positions.py @@ -1,9 +1,20 @@ +import pytest import requests import main.models.wallet # noqa: F401 from tests.conftest import make_wallet_client +@pytest.fixture(autouse=True) +async def clear_cashews_cache(): + from cashews import cache as cashewsCache + + cashewsCache.setup("mem://") + await cashewsCache.clear() + yield + await cashewsCache.clear() + + def _live_ok(url, params=None, headers=None, timeout=None): class Resp: status_code = 200 diff --git a/tests/test_wallet_summary.py b/tests/test_wallet_summary.py index 8da8abc0..e1e7fb6c 100644 --- a/tests/test_wallet_summary.py +++ b/tests/test_wallet_summary.py @@ -1,9 +1,20 @@ +import pytest import requests import main.models.wallet # noqa: F401 from tests.conftest import make_wallet_client +@pytest.fixture(autouse=True) +async def clear_cashews_cache(): + from cashews import cache as cashewsCache + + cashewsCache.setup("mem://") + await cashewsCache.clear() + yield + await cashewsCache.clear() + + def _live_ok(url, params=None, headers=None, timeout=None): class Resp: status_code = 200 From 638e52b716b1186d9bce437f5bd20779731f6217 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 02:39:35 -0300 Subject: [PATCH 27/34] split orunmila tools module into tools package --- main/app/orunmila/tools.py | 490 ---------------------------- main/app/orunmila/tools/__init__.py | 72 ++++ main/app/orunmila/tools/context.py | 26 ++ main/app/orunmila/tools/memory.py | 62 ++++ main/app/orunmila/tools/sandbox.py | 94 ++++++ main/app/orunmila/tools/wallet.py | 209 ++++++++++++ 6 files changed, 463 insertions(+), 490 deletions(-) delete mode 100644 main/app/orunmila/tools.py create mode 100644 main/app/orunmila/tools/__init__.py create mode 100644 main/app/orunmila/tools/context.py create mode 100644 main/app/orunmila/tools/memory.py create mode 100644 main/app/orunmila/tools/sandbox.py create mode 100644 main/app/orunmila/tools/wallet.py diff --git a/main/app/orunmila/tools.py b/main/app/orunmila/tools.py deleted file mode 100644 index 980e822f..00000000 --- a/main/app/orunmila/tools.py +++ /dev/null @@ -1,490 +0,0 @@ -from config import SessionLocal -import asyncio -import logging -from datetime import date as dateType -from typing import Any, Optional -from urllib.parse import quote - -from fastapi import HTTPException -from forgevm.exceptions import SandboxNotFound -from sqlalchemy.orm import Session - -from main.app.orunmila.memory import OrunmilaMemory -from main.app.orunmila.sandbox import SandboxManager, hostPath -from main.app.orunmila.vector import embed -from main.app.wallet.earnings import EarningsManager -from main.app.wallet.performance import PerformanceManager -from main.app.wallet.positions import PositionsManager -from main.app.wallet.summary import SummaryManager -from main.app.wallet.wallets import WalletsManager - -logger = logging.getLogger(__name__) - - -# -# memory -# -async def search_memory(query: str, limit: int = 10, **_) -> dict: - """Search user's saved memories, preferences, and past analysis context. - - Use this to recall what the user has previously discussed, their preferences, or past analysis results before starting a new analysis. - - Args: - query: Search query — keywords or phrase to find in saved memories - limit: Maximum number of memories to return (default 10) - """ - user = _.get("user") - if not user: - return {"error": "Authentication required"} - - db: Session | None = _.get("db") - ownSession = not db - if ownSession: - db = SessionLocal() - try: - results = await asyncio.to_thread( - OrunmilaMemory.search, - db, # type: ignore[arg-type] - user["userId"], - query, - limit=limit, - ) - return {"memories": results} - finally: - if ownSession: - db.close() # type: ignore[union-attr] - - -async def save_memory(key: str, value: str, type: str, **_) -> dict: - """Store a memory about the user's preferences, analysis results, or feedback. - - Use this to remember important findings, user preferences, or analysis conclusions across sessions. - - Args: - key: Short label for the memory (e.g., "PETR4 valuation") - value: Full memory content with details - type: Type of memory — one of: preference, analysis, feedback, context - """ - user = _.get("user") - if not user: - return {"error": "Authentication required"} - - db: Session | None = _.get("db") - ownSession = not db - if ownSession: - db = SessionLocal() - try: - embedding = embed([value])[0] - result = await asyncio.to_thread( - OrunmilaMemory.upsertMemory, - db, # type: ignore[arg-type] - user["userId"], - key=key, - value=value, - memoryType=type, - source="explicit", - embedding=embedding, - userRoles=user.get("roles", []), - ) - if result["status"] == "limit_reached": - return {"error": f"Memory limit reached ({result['limit']}). Upgrade to premium for more memories."} - return {"status": result["status"], "memoryId": result["memory"].id} - finally: - if ownSession: - db.close() # type: ignore[union-attr] - - -# -# sandbox -# -async def execute_code(code: str, timeout: int = 30, **_) -> dict: - """Execute Python code in an isolated sandbox. Use for quantitative analysis, - statistical models, custom charts, and data transformations. - - Args: - code: Python code to execute - timeout: Maximum execution time in seconds (default 30) - """ - userId = _.get("userId", 0) - sandboxId = _.get("sandbox_id") - if not sandboxId: - return {"error": "No sandbox available"} - try: - return await SandboxManager.execute(userId, code, sandboxId, timeout=timeout) - except SandboxNotFound: - return {"error": "Sandbox could not be respawned. Try again."} - except Exception as e: - logger.error("Sandbox execution failed: %s", e) - return {"error": f"Sandbox execution failed: {e}"} - - -async def read_file(path: str, **_) -> dict: - """Read a file from the workspace. - - Args: - path: Path to the file (e.g., /workspace/results.json or results.json) - """ - userId = _.get("userId", 0) - try: - content = SandboxManager.read_file(userId, path) - except ValueError: - return {"error": "Invalid workspace path"} - return {"content": content} - - -async def write_file(path: str, content: str, **_) -> dict: - """Write a file to the workspace. Use this to save data files - (CSV, JSON, scripts) for analysis. - - Args: - path: Path where the file will be written (e.g., /workspace/analyze.py) - content: File content as a string - """ - userId = _.get("userId", 0) - try: - ok = SandboxManager.write_file(userId, path, content) - except ValueError: - return {"error": "Invalid workspace path"} - return {"success": ok} - - -async def list_files(path: str = "/workspace", **_) -> dict: - """List files in the workspace directory. - - Args: - path: Directory path to list (default: /workspace) - """ - userId = _.get("userId", 0) - try: - return SandboxManager.list_files(userId, path) - except ValueError: - return {"error": "Invalid workspace path"} - - -async def serve_file(path: str, **_) -> dict: - """Get a download link for a workspace file to share with the user. - - Use this when the user should be able to download or view a file you - created (reports, CSVs, charts). Returns a markdown link the user can - click; embed the markdown value in your reply. - - Args: - path: Path to the file (e.g., /workspace/report.csv) - """ - userId = _.get("userId", 0) - try: - host = hostPath(userId, path) - except ValueError: - return {"error": "Invalid workspace path"} - if not host.exists() or not host.is_file(): - return {"error": f"File not found: {path}"} - - url = f"/orunmila/workspace/download?path={quote(path, safe='/')}" - return {"url": url, "markdown": f"[{host.name}]({url})"} - - -# -# wallet -# -async def get_wallet_positions(wallet_id: int, **_) -> dict: - """List wallet holdings with live prices, equity, allocation, and buy signals. - - Read-only: never mutates wallet state. - - Args: - wallet_id: Wallet to inspect (must belong to the caller) - """ - user = _.get("user") - if not user: - return {"error": "Authentication required"} - - db: Session | None = _.get("db") - ownSession = not db - if ownSession: - db = SessionLocal() - try: - userId = user["userId"] - try: - WalletsManager.getWallet( - db, # type: ignore[arg-type] - wallet_id, - userId, - ) - except HTTPException: - return {"error": "not-owner"} - return PositionsManager.getPositions( - db, # type: ignore[arg-type] - wallet_id, - userId, - ) - finally: - if ownSession: - db.close() # type: ignore[union-attr] - - -async def get_wallet_summary(wallet_id: int, **_) -> dict: - """Summarize applied capital, equity, and variation for a wallet. - - Read-only: never mutates wallet state. - - Args: - wallet_id: Wallet to summarize (must belong to the caller) - """ - user = _.get("user") - if not user: - return {"error": "Authentication required"} - - db: Session | None = _.get("db") - ownSession = not db - if ownSession: - db = SessionLocal() - try: - userId = user["userId"] - try: - WalletsManager.getWallet( - db, # type: ignore[arg-type] - wallet_id, - userId, - ) - except HTTPException: - return {"error": "not-owner"} - return SummaryManager.getSummary( - db, # type: ignore[arg-type] - wallet_id, - userId, - ) - finally: - if ownSession: - db.close() # type: ignore[union-attr] - - -async def get_wallet_allocation(wallet_id: int, group_by: str = "ticker", **_) -> dict: - """Break wallet equity down by ticker or asset type. - - Read-only: never mutates wallet state. - - Args: - wallet_id: Wallet to inspect (must belong to the caller) - group_by: Grouping key — "ticker" or "assetType" (default "ticker") - """ - user = _.get("user") - if not user: - return {"error": "Authentication required"} - - db: Session | None = _.get("db") - ownSession = not db - if ownSession: - db = SessionLocal() - try: - userId = user["userId"] - try: - WalletsManager.getWallet( - db, # type: ignore[arg-type] - wallet_id, - userId, - ) - except HTTPException: - return {"error": "not-owner"} - return SummaryManager.getAllocation( - db, # type: ignore[arg-type] - wallet_id, - userId, - group_by, - ) - finally: - if ownSession: - db.close() # type: ignore[union-attr] - - -async def list_wallet_earnings(wallet_id: int, status: Optional[str] = "A Receber", **_) -> dict: - """List accrued earnings (dividends, JSCP) for a wallet. - - Read-only: never mutates wallet state. - - Args: - wallet_id: Wallet to inspect (must belong to the caller) - status: Filter by status — "A Receber", "Recebido", or None for all (default "A Receber") - """ - user = _.get("user") - if not user: - return {"error": "Authentication required"} - - db: Session | None = _.get("db") - ownSession = not db - if ownSession: - db = SessionLocal() - try: - userId = user["userId"] - try: - WalletsManager.getWallet( - db, # type: ignore[arg-type] - wallet_id, - userId, - ) - except HTTPException: - return {"error": "not-owner"} - rows = EarningsManager.listEarnings( - db, # type: ignore[arg-type] - wallet_id, - userId, - status=status, - ) - return { - "wallet_id": wallet_id, - "status": status, - "earnings": [ - { - "earning_id": int(row.earningId), - "ticker": str(row.ticker), - "kind": str(row.kind), - "ex_date": str(row.exDate), - "pay_date": str(row.payDate), - "gross": float(row.gross), - "net": float(row.netIrAdjusted), - "status": str(row.status), - } - for row in rows - ], - } - finally: - if ownSession: - db.close() # type: ignore[union-attr] - - -async def get_wallet_performance( - wallet_id: int, from_date: str, to_date: str, ticker: Optional[str] = None, **_ -) -> dict: - """Compute time-weighted return, volatility, and dividends for a wallet or ticker. - - Read-only: never mutates wallet state. - - Args: - wallet_id: Wallet to inspect (must belong to the caller) - from_date: Window start as YYYY-MM-DD - to_date: Window end as YYYY-MM-DD - ticker: Optional single ticker; omit for the whole wallet - """ - user = _.get("user") - if not user: - return {"error": "Authentication required"} - - try: - startDate = dateType.fromisoformat(from_date) - endDate = dateType.fromisoformat(to_date) - except ValueError: - return {"error": "invalid date, use YYYY-MM-DD"} - - db: Session | None = _.get("db") - ownSession = not db - if ownSession: - db = SessionLocal() - try: - userId = user["userId"] - try: - WalletsManager.getWallet( - db, # type: ignore[arg-type] - wallet_id, - userId, - ) - except HTTPException: - return {"error": "not-owner"} - return PerformanceManager.getPerformance( - db, # type: ignore[arg-type] - wallet_id, - userId, - ticker, - startDate, - endDate, - ) - finally: - if ownSession: - db.close() # type: ignore[union-attr] - - -async def get_wallet_rebalance(wallet_id: int, **_) -> dict: - """Show weight-share rebalance deltas per ticker (buy/sell/hold). - - Read-only: never mutates wallet state. - - Args: - wallet_id: Wallet to inspect (must belong to the caller) - """ - user = _.get("user") - if not user: - return {"error": "Authentication required"} - - db: Session | None = _.get("db") - ownSession = not db - if ownSession: - db = SessionLocal() - try: - userId = user["userId"] - try: - WalletsManager.getWallet( - db, # type: ignore[arg-type] - wallet_id, - userId, - ) - except HTTPException: - return {"error": "not-owner"} - return PositionsManager.getRebalance( - db, # type: ignore[arg-type] - wallet_id, - userId, - ) - finally: - if ownSession: - db.close() # type: ignore[union-attr] - - -TOOL_REGISTRY: dict[str, Any] = { - "search_memory": search_memory, - "save_memory": save_memory, - "execute_code": execute_code, - "read_file": read_file, - "write_file": write_file, - "list_files": list_files, - "serve_file": serve_file, - "get_wallet_positions": get_wallet_positions, - "get_wallet_summary": get_wallet_summary, - "get_wallet_allocation": get_wallet_allocation, - "list_wallet_earnings": list_wallet_earnings, - "get_wallet_performance": get_wallet_performance, - "get_wallet_rebalance": get_wallet_rebalance, -} - - -async def dispatchToolCall( - functionCall, - mcpClients, - user=None, - db=None, - sandbox_id: str | None = None, -) -> dict: - name = functionCall.name - args = dict(functionCall.args or {}) - logger.info(f"Executing tool call: {name}({args})") - - if name in TOOL_REGISTRY: - fn = TOOL_REGISTRY[name] - args["user"] = user - args["db"] = db - args["sandbox_id"] = sandbox_id - args["userId"] = user.get("userId", 0) if user else 0 - return await fn(**args) - - for client in mcpClients.values(): - try: - mcpResult = await client.session.call_tool(name, args) - if getattr(mcpResult, "isError", False): - continue - textParts = [] - if hasattr(mcpResult, "content") and mcpResult.content: - for block in mcpResult.content: - textParts.append(block.text if hasattr(block, "text") else str(block)) - return {"result": "\n".join(textParts) if textParts else str(mcpResult)} - except Exception as e: - logger.debug(f"MCP client failed for {name}: {e}") - continue - - return {"error": f"Tool '{name}' not available"} diff --git a/main/app/orunmila/tools/__init__.py b/main/app/orunmila/tools/__init__.py new file mode 100644 index 00000000..cefabf80 --- /dev/null +++ b/main/app/orunmila/tools/__init__.py @@ -0,0 +1,72 @@ +import logging +from typing import Any + +from main.app.orunmila.memory import OrunmilaMemory +from main.app.orunmila.sandbox import SandboxManager, hostPath +from main.app.orunmila.tools.context import closeOwnSession, popAuthSession +from main.app.orunmila.tools.memory import save_memory, search_memory +from main.app.orunmila.tools.sandbox import execute_code, list_files, read_file, serve_file, write_file +from main.app.orunmila.tools.wallet import ( + get_wallet_allocation, + get_wallet_performance, + get_wallet_positions, + get_wallet_rebalance, + get_wallet_summary, + list_wallet_earnings, +) +from main.app.orunmila.vector import embed + +logger = logging.getLogger(__name__) + + +TOOL_REGISTRY: dict[str, Any] = { + "search_memory": search_memory, + "save_memory": save_memory, + "execute_code": execute_code, + "read_file": read_file, + "write_file": write_file, + "list_files": list_files, + "serve_file": serve_file, + "get_wallet_positions": get_wallet_positions, + "get_wallet_summary": get_wallet_summary, + "get_wallet_allocation": get_wallet_allocation, + "list_wallet_earnings": list_wallet_earnings, + "get_wallet_performance": get_wallet_performance, + "get_wallet_rebalance": get_wallet_rebalance, +} + + +async def dispatchToolCall( + functionCall, + mcpClients, + user=None, + db=None, + sandbox_id: str | None = None, +) -> dict: + name = functionCall.name + args = dict(functionCall.args or {}) + logger.info(f"Executing tool call: {name}({args})") + + if name in TOOL_REGISTRY: + fn = TOOL_REGISTRY[name] + args["user"] = user + args["db"] = db + args["sandbox_id"] = sandbox_id + args["userId"] = user.get("userId", 0) if user else 0 + return await fn(**args) + + for client in mcpClients.values(): + try: + mcpResult = await client.session.call_tool(name, args) + if getattr(mcpResult, "isError", False): + continue + textParts = [] + if hasattr(mcpResult, "content") and mcpResult.content: + for block in mcpResult.content: + textParts.append(block.text if hasattr(block, "text") else str(block)) + return {"result": "\n".join(textParts) if textParts else str(mcpResult)} + except Exception as e: + logger.debug(f"MCP client failed for {name}: {e}") + continue + + return {"error": f"Tool '{name}' not available"} diff --git a/main/app/orunmila/tools/context.py b/main/app/orunmila/tools/context.py new file mode 100644 index 00000000..420169f3 --- /dev/null +++ b/main/app/orunmila/tools/context.py @@ -0,0 +1,26 @@ +from typing import Any + +from config import SessionLocal +from sqlalchemy.orm import Session + + +def popAuthSession(args: dict) -> tuple[Any, Session | None, bool, dict | None]: + """Shared auth-guard + own-SessionLocal convention every tool repeats. + + Returns (user, db, ownSession, error). When error is not None the caller + must return it immediately. Otherwise the caller must release db via + closeOwnSession when ownSession is True. + """ + user = args.get("user") + if not user: + return None, None, False, {"error": "Authentication required"} + db: Session | None = args.get("db") + ownSession = not db + if ownSession: + db = SessionLocal() + return user, db, ownSession, None + + +def closeOwnSession(db: Session | None, ownSession: bool) -> None: + if ownSession: + db.close() # type: ignore[union-attr] diff --git a/main/app/orunmila/tools/memory.py b/main/app/orunmila/tools/memory.py new file mode 100644 index 00000000..c69e510c --- /dev/null +++ b/main/app/orunmila/tools/memory.py @@ -0,0 +1,62 @@ +import asyncio + +import main.app.orunmila.tools as toolsPkg +from main.app.orunmila.tools.context import closeOwnSession, popAuthSession + + +async def search_memory(query: str, limit: int = 10, **_) -> dict: + """Search user's saved memories, preferences, and past analysis context. + + Use this to recall what the user has previously discussed, their preferences, or past analysis results before starting a new analysis. + + Args: + query: Search query — keywords or phrase to find in saved memories + limit: Maximum number of memories to return (default 10) + """ + user, db, ownSession, authError = popAuthSession(_) + if authError is not None: + return authError + try: + results = await asyncio.to_thread( + toolsPkg.OrunmilaMemory.search, + db, # type: ignore[arg-type] + user["userId"], + query, + limit=limit, + ) + return {"memories": results} + finally: + closeOwnSession(db, ownSession) + + +async def save_memory(key: str, value: str, type: str, **_) -> dict: + """Store a memory about the user's preferences, analysis results, or feedback. + + Use this to remember important findings, user preferences, or analysis conclusions across sessions. + + Args: + key: Short label for the memory (e.g., "PETR4 valuation") + value: Full memory content with details + type: Type of memory — one of: preference, analysis, feedback, context + """ + user, db, ownSession, authError = popAuthSession(_) + if authError is not None: + return authError + try: + embedding = toolsPkg.embed([value])[0] + result = await asyncio.to_thread( + toolsPkg.OrunmilaMemory.upsertMemory, + db, # type: ignore[arg-type] + user["userId"], + key=key, + value=value, + memoryType=type, + source="explicit", + embedding=embedding, + userRoles=user.get("roles", []), + ) + if result["status"] == "limit_reached": + return {"error": f"Memory limit reached ({result['limit']}). Upgrade to premium for more memories."} + return {"status": result["status"], "memoryId": result["memory"].id} + finally: + closeOwnSession(db, ownSession) diff --git a/main/app/orunmila/tools/sandbox.py b/main/app/orunmila/tools/sandbox.py new file mode 100644 index 00000000..dffbd048 --- /dev/null +++ b/main/app/orunmila/tools/sandbox.py @@ -0,0 +1,94 @@ +import logging +from urllib.parse import quote + +from forgevm.exceptions import SandboxNotFound + +import main.app.orunmila.tools as toolsPkg + +logger = logging.getLogger(__name__) + + +async def execute_code(code: str, timeout: int = 30, **_) -> dict: + """Execute Python code in an isolated sandbox. Use for quantitative analysis, + statistical models, custom charts, and data transformations. + + Args: + code: Python code to execute + timeout: Maximum execution time in seconds (default 30) + """ + userId = _.get("userId", 0) + sandboxId = _.get("sandbox_id") + if not sandboxId: + return {"error": "No sandbox available"} + try: + return await toolsPkg.SandboxManager.execute(userId, code, sandboxId, timeout=timeout) + except SandboxNotFound: + return {"error": "Sandbox could not be respawned. Try again."} + except Exception as e: + logger.error("Sandbox execution failed: %s", e) + return {"error": f"Sandbox execution failed: {e}"} + + +async def read_file(path: str, **_) -> dict: + """Read a file from the workspace. + + Args: + path: Path to the file (e.g., /workspace/results.json or results.json) + """ + userId = _.get("userId", 0) + try: + content = toolsPkg.SandboxManager.read_file(userId, path) + except ValueError: + return {"error": "Invalid workspace path"} + return {"content": content} + + +async def write_file(path: str, content: str, **_) -> dict: + """Write a file to the workspace. Use this to save data files + (CSV, JSON, scripts) for analysis. + + Args: + path: Path where the file will be written (e.g., /workspace/analyze.py) + content: File content as a string + """ + userId = _.get("userId", 0) + try: + ok = toolsPkg.SandboxManager.write_file(userId, path, content) + except ValueError: + return {"error": "Invalid workspace path"} + return {"success": ok} + + +async def list_files(path: str = "/workspace", **_) -> dict: + """List files in the workspace directory. + + Args: + path: Directory path to list (default: /workspace) + """ + userId = _.get("userId", 0) + try: + return toolsPkg.SandboxManager.list_files(userId, path) + except ValueError: + return {"error": "Invalid workspace path"} + + +async def serve_file(path: str, **_) -> dict: + """Get a download link for a workspace file to share with the user. + + Use this when the user should be able to download or view a file you + created (reports, CSVs, charts). Returns a markdown link the user can + click; embed the markdown value in your reply. + + Args: + path: Path to the file (e.g., /workspace/report.csv) + """ + userId = _.get("userId", 0) + try: + host = toolsPkg.hostPath(userId, path) + except ValueError: + return {"error": "Invalid workspace path"} + if not host.exists() or not host.is_file(): + return {"error": f"File not found: {path}"} + + url = f"/orunmila/workspace/download?path={quote(path, safe='/')}" + return {"url": url, "markdown": f"[{host.name}]({url})"} diff --git a/main/app/orunmila/tools/wallet.py b/main/app/orunmila/tools/wallet.py new file mode 100644 index 00000000..b957c2c9 --- /dev/null +++ b/main/app/orunmila/tools/wallet.py @@ -0,0 +1,209 @@ +from datetime import date as dateType +from typing import Optional + +from fastapi import HTTPException +from sqlalchemy.orm import Session + +from main.app.orunmila.tools.context import closeOwnSession, popAuthSession +from main.app.wallet.earnings import EarningsManager +from main.app.wallet.performance import PerformanceManager +from main.app.wallet.positions import PositionsManager +from main.app.wallet.summary import SummaryManager +from main.app.wallet.wallets import WalletsManager + + +def ensureOwnership(db: Session | None, walletId: int, userId: int) -> dict | None: + try: + WalletsManager.getWallet( + db, # type: ignore[arg-type] + walletId, + userId, + ) + except HTTPException: + return {"error": "not-owner"} + return None + + +async def get_wallet_positions(wallet_id: int, **_) -> dict: + """List wallet holdings with live prices, equity, allocation, and buy signals. + + Read-only: never mutates wallet state. + + Args: + wallet_id: Wallet to inspect (must belong to the caller) + """ + user, db, ownSession, authError = popAuthSession(_) + if authError is not None: + return authError + try: + userId = user["userId"] + ownerError = ensureOwnership(db, wallet_id, userId) + if ownerError is not None: + return ownerError + return PositionsManager.getPositions( + db, # type: ignore[arg-type] + wallet_id, + userId, + ) + finally: + closeOwnSession(db, ownSession) + + +async def get_wallet_summary(wallet_id: int, **_) -> dict: + """Summarize applied capital, equity, and variation for a wallet. + + Read-only: never mutates wallet state. + + Args: + wallet_id: Wallet to summarize (must belong to the caller) + """ + user, db, ownSession, authError = popAuthSession(_) + if authError is not None: + return authError + try: + userId = user["userId"] + ownerError = ensureOwnership(db, wallet_id, userId) + if ownerError is not None: + return ownerError + return SummaryManager.getSummary( + db, # type: ignore[arg-type] + wallet_id, + userId, + ) + finally: + closeOwnSession(db, ownSession) + + +async def get_wallet_allocation(wallet_id: int, group_by: str = "ticker", **_) -> dict: + """Break wallet equity down by ticker or asset type. + + Read-only: never mutates wallet state. + + Args: + wallet_id: Wallet to inspect (must belong to the caller) + group_by: Grouping key — "ticker" or "assetType" (default "ticker") + """ + user, db, ownSession, authError = popAuthSession(_) + if authError is not None: + return authError + try: + userId = user["userId"] + ownerError = ensureOwnership(db, wallet_id, userId) + if ownerError is not None: + return ownerError + return SummaryManager.getAllocation( + db, # type: ignore[arg-type] + wallet_id, + userId, + group_by, + ) + finally: + closeOwnSession(db, ownSession) + + +async def list_wallet_earnings(wallet_id: int, status: Optional[str] = "A Receber", **_) -> dict: + """List accrued earnings (dividends, JSCP) for a wallet. + + Read-only: never mutates wallet state. + + Args: + wallet_id: Wallet to inspect (must belong to the caller) + status: Filter by status — "A Receber", "Recebido", or None for all (default "A Receber") + """ + user, db, ownSession, authError = popAuthSession(_) + if authError is not None: + return authError + try: + userId = user["userId"] + ownerError = ensureOwnership(db, wallet_id, userId) + if ownerError is not None: + return ownerError + rows = EarningsManager.listEarnings( + db, # type: ignore[arg-type] + wallet_id, + userId, + status=status, + ) + return { + "wallet_id": wallet_id, + "status": status, + "earnings": [ + { + "earning_id": int(row.earningId), + "ticker": str(row.ticker), + "kind": str(row.kind), + "ex_date": str(row.exDate), + "pay_date": str(row.payDate), + "gross": float(row.gross), + "net": float(row.netIrAdjusted), + "status": str(row.status), + } + for row in rows + ], + } + finally: + closeOwnSession(db, ownSession) + + +async def get_wallet_performance( + wallet_id: int, from_date: str, to_date: str, ticker: Optional[str] = None, **_ +) -> dict: + """Compute time-weighted return, volatility, and dividends for a wallet or ticker. + + Read-only: never mutates wallet state. + + Args: + wallet_id: Wallet to inspect (must belong to the caller) + from_date: Window start as YYYY-MM-DD + to_date: Window end as YYYY-MM-DD + ticker: Optional single ticker; omit for the whole wallet + """ + user, db, ownSession, authError = popAuthSession(_) + if authError is not None: + return authError + try: + try: + startDate = dateType.fromisoformat(from_date) + endDate = dateType.fromisoformat(to_date) + except ValueError: + return {"error": "invalid date, use YYYY-MM-DD"} + + userId = user["userId"] + ownerError = ensureOwnership(db, wallet_id, userId) + if ownerError is not None: + return ownerError + return PerformanceManager.getPerformance( + db, # type: ignore[arg-type] + wallet_id, + userId, + ticker, + startDate, + endDate, + ) + finally: + closeOwnSession(db, ownSession) + + +async def get_wallet_rebalance(wallet_id: int, **_) -> dict: + """Show weight-share rebalance deltas per ticker (buy/sell/hold). + + Read-only: never mutates wallet state. + + Args: + wallet_id: Wallet to inspect (must belong to the caller) + """ + user, db, ownSession, authError = popAuthSession(_) + if authError is not None: + return authError + try: + userId = user["userId"] + ownerError = ensureOwnership(db, wallet_id, userId) + if ownerError is not None: + return ownerError + return PositionsManager.getRebalance( + db, # type: ignore[arg-type] + wallet_id, + userId, + ) + finally: + closeOwnSession(db, ownSession) From 81d7224b5a4be29c33eb5eb30ce425374bf20643 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 03:02:04 -0300 Subject: [PATCH 28/34] import --- graphify-out/.graphify_labels.json | 9 +- graphify-out/GRAPH_REPORT.md | 440 +- graphify-out/graph.json | 5861 +++++++++++++++++++-------- graphify-out/manifest.json | 75 +- main/app/orunmila/tools/__init__.py | 23 +- main/app/orunmila/tools/memory.py | 9 +- main/app/orunmila/tools/sandbox.py | 12 +- main/app/orunmila/tools/wallet.py | 10 +- 8 files changed, 4400 insertions(+), 2039 deletions(-) diff --git a/graphify-out/.graphify_labels.json b/graphify-out/.graphify_labels.json index 8839fa49..de158443 100644 --- a/graphify-out/.graphify_labels.json +++ b/graphify-out/.graphify_labels.json @@ -635,5 +635,12 @@ "633": "Community 633", "634": "Community 634", "635": "Community 635", - "636": "Community 636" + "636": "Community 636", + "637": "Community 637", + "638": "Community 638", + "639": "Community 639", + "643": "Community 643", + "648": "Community 648", + "649": "Community 649", + "650": "Community 650" } diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md index 877a9982..d6f44e99 100644 --- a/graphify-out/GRAPH_REPORT.md +++ b/graphify-out/GRAPH_REPORT.md @@ -1,16 +1,16 @@ # Graph Report - server (2026-10-01) ## Corpus Check -- 153 files · ~122,017 words +- 158 files · ~123,274 words - Verdict: corpus is large enough that graph structure adds value. ## Summary -- 6906 nodes · 9406 edges · 637 communities (400 shown, 237 thin omitted) -- Extraction: 84% EXTRACTED · 16% INFERRED · 0% AMBIGUOUS · INFERRED: 1475 edges (avg confidence: 0.68) +- 6991 nodes · 9562 edges · 644 communities (394 shown, 250 thin omitted) +- Extraction: 84% EXTRACTED · 16% INFERRED · 0% AMBIGUOUS · INFERRED: 1551 edges (avg confidence: 0.68) - Token cost: 0 input · 0 output ## Graph Freshness -- Built from commit: `5f6a9589` +- Built from commit: `638e52b7` - Run `git rev-parse HEAD` and compare to check if the graph is stale. - Run `graphify update .` after code changes (no API cost). @@ -140,7 +140,6 @@ - [[_COMMUNITY_Community 122|Community 122]] - [[_COMMUNITY_Community 123|Community 123]] - [[_COMMUNITY_Community 124|Community 124]] -- [[_COMMUNITY_Community 125|Community 125]] - [[_COMMUNITY_Community 126|Community 126]] - [[_COMMUNITY_Community 127|Community 127]] - [[_COMMUNITY_Community 128|Community 128]] @@ -638,6 +637,13 @@ - [[_COMMUNITY_Community 634|Community 634]] - [[_COMMUNITY_Community 635|Community 635]] - [[_COMMUNITY_Community 636|Community 636]] +- [[_COMMUNITY_Community 637|Community 637]] +- [[_COMMUNITY_Community 638|Community 638]] +- [[_COMMUNITY_Community 639|Community 639]] +- [[_COMMUNITY_Community 643|Community 643]] +- [[_COMMUNITY_Community 648|Community 648]] +- [[_COMMUNITY_Community 649|Community 649]] +- [[_COMMUNITY_Community 650|Community 650]] ## God Nodes (most connected - your core abstractions) 1. `vocab` - 456 edges @@ -658,10 +664,10 @@ main/app/stocks_api/cache.py → tests/test_stocks_api_coverage.py - `StocksCacheManager` --calls--> `test_cache_scheduler_starts_daemon_thread()` [INFERRED] main/app/stocks_api/cache.py → tests/test_stocks_api_coverage.py -- `DiscordHandler` --uses--> `TestSetupLogging` [INFERRED] - main/utils/logging_config.py → tests/test_logging_config_coverage.py - `HarnessState` --uses--> `TestGetState` [INFERRED] main/app/prometheus/state.py → tests/test_state_tools.py +- `HarnessState` --uses--> `TestSetState` [INFERRED] + main/app/prometheus/state.py → tests/test_state_tools.py ## Hyperedges (group relationships) - **Authentication Module** — AuthenticationManager, SessionManager, auth_util, auth_constants, getGoogleSSO [INFERRED] @@ -671,7 +677,7 @@ - **Configuration & Database Infrastructure** — config_Config, config_engine, config_stocksEngine [INFERRED] - **User Authentication & Authorization** — user_service, authentication, user_roles, permission_system [INFERRED] -## Communities (637 total, 237 thin omitted) +## Communities (644 total, 250 thin omitted) ### Community 0 - "Stocks API Endpoints" Cohesion: 0.0 @@ -706,8 +712,8 @@ Cohesion: 0.07 Nodes (29): Algorithmic Compression (`compact.py`) Implementation Plan, code:python (# main/app/prometheus/compact.py), code:python (# Before:), code:python (# Before:), code:python (# Before:), code:bash (pytest tests/ -k "prometheus" -v), code:bash (git add main/app/prometheus/agent.py), code:bash (git mv main/app/prometheus/summarizer.py main/app/prometheus) (+21 more) ### Community 8 - "Device Detection" -Cohesion: 0.08 -Nodes (9): HarnessState, Retrieve a value from state. Returns default if key not found., Return a copy of the current state., Format state as a string for injection into the LLM context., Check if state changed since last reset., Reset the changed flag. Returns the previous state., Clear all state data., In-memory state dict that persists across loop iterations within a single reques (+1 more) +Cohesion: 0.06 +Nodes (15): HarnessState, Retrieve a value from state. Returns default if key not found., Return a copy of the current state., Format state as a string for injection into the LLM context., Check if state changed since last reset., Reset the changed flag. Returns the previous state., Clear all state data., In-memory state dict that persists across loop iterations within a single reques (+7 more) ### Community 9 - "Server Configuration" Cohesion: 0.11 @@ -730,16 +736,16 @@ Cohesion: 0.06 Nodes (31): code:python ("""Measure whether the stocks query hot path is GIL-bound.), code:bash (git add main/utils/migrator.py tests/test_migrator_guard.py), code:python (import importlib), code:python (DB_POOL_SIZE = int(os.getenv("DB_POOL_SIZE", "20"))), code:bash (git add config.py tests/test_config_pools.py), code:python (import importlib), code:python (if __name__ == "__main__":), code:python (if len(instances) > 1 and fcntl is None: # pragma: no cover) (+23 more) ### Community 14 - "User Roles & Permissions" -Cohesion: 0.06 -Nodes (30): _make_stocksapi_client(), Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont, Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont, Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont (+22 more) +Cohesion: 0.05 +Nodes (36): _make_stocksapi_client(), Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental. (+28 more) ### Community 15 - "Community 15" Cohesion: 0.05 Nodes (38): code:block1 (User 123: "Analyze PETR4 vs VALE3 correlation"), code:python (from main.app.prometheus.sandbox import SandboxManager), code:python (TOOL_REGISTRY: dict[str, Any] = {), code:bash (git add main/app/prometheus/tools.py tests/test_sandbox_tool), code:python (import pytest), code:python (from main.app.prometheus.sandbox import SandboxManager), code:python (async def streamMessage(self, query=None, sessionId=None, db), code:python (## Code Sandbox (On-Demand)) (+30 more) ### Community 17 - "Community 17" -Cohesion: 0.07 -Nodes (26): Two dates in the range, both valid., Two dates in the range, both valid., Two dates in the range, both valid., Two dates in the range, both valid., Search with no index match falls back to string startswith., Search with no index match falls back to string startswith., search.strip() == '' should still dedup (line 181)., Search with no index match falls back to string startswith. (+18 more) +Cohesion: 0.11 +Nodes (17): Multiple search terms with tickerIndex., Multiple search terms with tickerIndex., Multiple search terms with tickerIndex., Search with no index match falls back to string startswith., Search with no index match falls back to string startswith., Search with no index match falls back to string startswith., Multiple search terms with tickerIndex., Multiple search terms with tickerIndex. (+9 more) ### Community 18 - "Community 18" Cohesion: 0.07 @@ -754,28 +760,28 @@ Cohesion: 0.06 Nodes (35): 1. Memory System (B+), 2. Summarizer/Episodes (B), 3. Loop Events (A-), 4. Core Architecture (B+), 5. Security (B+), 6. Performance (B), 7. Code Quality (B), After (B+) (+27 more) ### Community 21 - "Community 21" -Cohesion: 0.15 +Cohesion: 0.14 Nodes (13): benchOnce(), main(), batchCosineSimilarity(), decodeEmbeddings(), normalizeRows(), Empty matrix → empty array., Single row matches cosine_similarity., Multiple rows ranked correctly. (+5 more) ### Community 22 - "Community 22" -Cohesion: 0.07 -Nodes (19): filterCotationColumn(), Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., GET /stocks/realtime-cotation without search returns 422., GET /cotations without search returns 422. (+11 more) +Cohesion: 0.1 +Nodes (13): filterCotationColumn(), Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., GET /cotations without search returns 422., GET /cotations without search returns 422. (+5 more) ### Community 23 - "Community 23" Cohesion: 0.07 Nodes (35): Admin Access, API endpoints, API keys (Stocks API), code:bash (curl http://localhost:3200/user/health), code:mermaid (graph TD), code:bash (curl -X DELETE -H "Authorization: Bearer " http://loc), code:json ({), code:bash (curl -X POST -H "Authorization: Bearer " http://local) (+27 more) ### Community 24 - "Community 24" -Cohesion: 0.09 -Nodes (5): Tests for agent <-> persistent sandbox integration (Task 3)., Verify the agent uses getOrCreate + syncToSandbox/syncFromSandbox., Test the premium gating logic used in streamMessage., TestPersistentSandboxLifecycle, TestPremiumCheck +Cohesion: 0.06 +Nodes (6): Tests for agent <-> persistent sandbox integration (Task 3)., Verify the agent uses getOrCreate + syncToSandbox/syncFromSandbox., Test the premium gating logic used in streamMessage., TestAgentSandboxIntegration, TestPersistentSandboxLifecycle, TestPremiumCheck ### Community 25 - "Community 25" -Cohesion: 0.06 -Nodes (13): Tests for input validation via HTTP endpoints. Validation is now inline via Bod, PUT /prometheus/sessions/{sessionId} — validates title via Body(...), POST /prometheus/chat/stream — validates query via Body(...), POST /auth/register — validates username, email, password via Body(...), Test that endpoints reject requests with missing required fields., POST /auth/login — validates username, password via Body(...), POST /prometheus/sessions — validates title via Body(...), TestChatValidation (+5 more) +Cohesion: 0.1 +Nodes (9): Tests for input validation via HTTP endpoints. Validation is now inline via Bod, PUT /prometheus/sessions/{sessionId} — validates title via Body(...), POST /prometheus/chat/stream — validates query via Body(...), Test that endpoints reject requests with missing required fields., POST /prometheus/sessions — validates title via Body(...), TestChatValidation, TestMissingBody, TestPrometheusSessionValidation (+1 more) ### Community 26 - "Community 26" -Cohesion: 0.09 -Nodes (24): createKey(), _hash_key(), hashKey(), Return SHA-256 hex digest of the given key., Test that concurrent requests are properly serialized at DB level. Th, Test edge case: request exactly at quota limit., Test edge case: request exactly at quota limit., Test that invalid API key returns zero rows affected. (+16 more) +Cohesion: 0.12 +Nodes (20): createKey(), _hash_key(), hashKey(), Return SHA-256 hex digest of the given key., Test that concurrent requests are properly serialized at DB level. Th, Test edge case: request exactly at quota limit., Test edge case: request exactly at quota limit., Test that increment works from zero usage. (+12 more) ### Community 27 - "Community 27" Cohesion: 0.15 @@ -786,8 +792,8 @@ Cohesion: 0.05 Nodes (42): Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Pass field name WITHOUT year (how categorizeColumns returns them)., Pass field name WITHOUT year (how categorizeColumns returns them)., No historical data columns -> inner 400 caught by outer except -> 500., Pass field name WITHOUT year (how categorizeColumns returns them). (+34 more) ### Community 29 - "Community 29" -Cohesion: 0.08 -Nodes (17): PrometheusGenerator, Thread-safe proxy that delegates to per-thread sessions., SessionProxy, _make_generator(), Tests to increase coverage for: - main/app/prometheus/generation.py - main/a, test_execute_workflow_basic_no_history(), test_execute_workflow_global_request_api_error(), test_execute_workflow_global_request_status_not_200() (+9 more) +Cohesion: 0.09 +Nodes (15): PrometheusGenerator, _make_generator(), Tests to increase coverage for: - main/app/prometheus/generation.py - main/a, test_execute_workflow_basic_no_history(), test_execute_workflow_global_request_api_error(), test_execute_workflow_global_request_status_not_200(), test_execute_workflow_global_request_with_api_key(), test_execute_workflow_session_db_exception() (+7 more) ### Community 30 - "Community 30" Cohesion: 0.07 @@ -803,7 +809,7 @@ Nodes (12): ToolContext — bundles all dependencies for tool execution. Replac ### Community 33 - "Community 33" Cohesion: 0.12 -Nodes (13): BaseHTTPMiddleware, Tests for standardized error responses (errors.py)., SampleBody, TestErrorResponseModel, TestGenericExceptionHandler, TestHTTPExceptionHandler, TestRequestContextFilter, TestSuccessPassthrough (+5 more) +Nodes (14): BaseHTTPMiddleware, app(), Tests for standardized error responses (errors.py)., SampleBody, TestErrorResponseModel, TestGenericExceptionHandler, TestHTTPExceptionHandler, TestRequestContextFilter (+6 more) ### Community 34 - "Community 34" Cohesion: 0.11 @@ -826,8 +832,8 @@ Cohesion: 0.07 Nodes (27): code:json ([), code:javascript (const loadHistory = async (sid) => {), code:jsx (export default function MessageList({ messages, toolEvents, ), code:javascript (const loadHistory = async (sid) => {), code:jsx (export default function AgentLoop({ toolEvents, turnMetrics ), code:bash (git add frontend/src/App.jsx frontend/src/components/Message), code:bash (docker-compose up -d --build), code:sql (SELECT COUNT(*) FROM prometheus WHERE JSON_CONTAINS_PATH(his) (+19 more) ### Community 39 - "Community 39" -Cohesion: 0.06 -Nodes (31): Invalid date -> inner 400 passes through (not wrapped as 500)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., search.strip() == '' should still dedup (line 181)., search.strip() == '' should still dedup (line 181)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500. (+23 more) +Cohesion: 0.05 +Nodes (40): Invalid date -> inner 400 passes through (not wrapped as 500)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., search.strip() == '' should still dedup (line 181)., search.strip() == '' should still dedup (line 181)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500. (+32 more) ### Community 40 - "Community 40" Cohesion: 0.12 @@ -838,20 +844,20 @@ Cohesion: 0.07 Nodes (32): API endpoints, Authentication Management, code:bash (curl http://localhost:3200/auth/health), code:bash (curl -X POST "http://localhost:3200/auth/register" \), code:bash (curl -X POST "http://localhost:3200/auth/login" \), code:bash (curl -X POST "http://localhost:3200/auth/logout" \), code:bash (# Browser redirect; redirect_url optional, else Referer head), code:mermaid (graph TD) (+24 more) ### Community 42 - "Community 42" -Cohesion: 0.06 -Nodes (23): StocksCacheManager, Tests for dynamic ticker index feature, Ticker index should be built when cache is loaded, Ticker index should contain all tickers from cache, Ticker index should be case-insensitive, Looking up ticker should return valid row index, Ticker index should be rebuilt when cache refreshes, TestTickerIndex (+15 more) +Cohesion: 0.09 +Nodes (16): StocksCacheManager, Tests for dynamic ticker index feature, Ticker index should be built when cache is loaded, Ticker index should contain all tickers from cache, Ticker index should be case-insensitive, Looking up ticker should return valid row index, Ticker index should be rebuilt when cache refreshes, TestTickerIndex (+8 more) ### Community 43 - "Community 43" -Cohesion: 0.15 -Nodes (6): authenticateUser(), createUserAccount(), hashPassword(), verifyPassword(), TestAuthUtil, TestAuthUtilEdgeCases +Cohesion: 0.13 +Nodes (7): authenticateUser(), createUserAccount(), createAccessToken(), hashPassword(), verifyPassword(), TestAuthUtil, TestAuthUtilEdgeCases ### Community 44 - "Community 44" Cohesion: 0.14 Nodes (3): UserSession, TestSessionExpiration, TestUserSessionModel ### Community 45 - "Community 45" -Cohesion: 0.07 -Nodes (24): Covers line 28: GET /auth/health., Covers line 28: GET /auth/health., Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers line 13: UserManager.__init__., Covers line 13: UserManager.__init__. (+16 more) +Cohesion: 0.06 +Nodes (36): AuthenticationManager, IntFlag, Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 28: GET /auth/health. (+28 more) ### Community 46 - "Community 46" Cohesion: 0.09 @@ -866,8 +872,8 @@ Cohesion: 0.06 Nodes (34): Backend (COMMIT), code:bash (cd frontend && pnpm add @openuidev/react-lang), code:bash (rm frontend/src/components/MdocMessage.jsx), code:python ("""OpenUI Lang system prompt section for Prometheus agent.), code:block12, code:block13, code:block14, code:block15 (+26 more) ### Community 49 - "Community 49" -Cohesion: 0.13 -Nodes (18): dispatchToolCall(), TDD tests: verify memory tools are wired into the Prometheus agent. RED: Thes, test_memory_tool_skipped_without_user(), test_non_memory_tool_not_routed_to_executeMemoryTool(), test_non_registry_tool_not_routed(), test_save_memory_routed_to_executeMemoryTool(), test_save_memory_routed_via_registry(), test_search_memory_routed_to_executeMemoryTool() (+10 more) +Cohesion: 0.07 +Nodes (30): dispatchToolCall(), TDD tests: verify memory tools are wired into the Prometheus agent. RED: Thes, dispatchToolCall must route memory tool names via TOOL_REGISTRY., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., dispatchToolCall must route memory tool names to executeMemoryTool. (+22 more) ### Community 50 - "Community 50" Cohesion: 0.07 @@ -882,8 +888,8 @@ Cohesion: 0.08 Nodes (7): Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., TestPrometheusChatManager ### Community 53 - "Community 53" -Cohesion: 0.13 -Nodes (25): archiveDead(), clearAll(), clearAllAsync(), count_memories(), decayScores(), deleteMemory(), deleteMemoryAsync(), _fulltext_search() (+17 more) +Cohesion: 0.1 +Nodes (39): applyUpdate(), archiveDead(), clearAll(), clearAllAsync(), count_memories(), countMemories(), countTokensCached(), decayScores() (+31 more) ### Community 54 - "Community 54" Cohesion: 0.17 @@ -902,8 +908,8 @@ Cohesion: 0.09 Nodes (15): Performance benchmark tests for stocks API, Performance benchmark tests for stocks API, Ticker index lookup should be O(1) - very fast, Ticker index lookup should be O(1) - very fast, Prefix scan should be much slower than index lookup, Prefix scan should be much slower than index lookup, Index lookup should be significantly faster than scan, Index lookup should be significantly faster than scan (+7 more) ### Community 58 - "Community 58" -Cohesion: 0.22 -Nodes (13): createAccessToken(), googleCallback(), isSecureScheme(), issueSessionCookie(), login(), logout(), register(), requireServiceToken() (+5 more) +Cohesion: 0.21 +Nodes (12): googleCallback(), isSecureScheme(), issueSessionCookie(), login(), logout(), register(), requireServiceToken(), resolveCookieDomain() (+4 more) ### Community 59 - "Community 59" Cohesion: 0.17 @@ -918,8 +924,8 @@ Cohesion: 0.1 Nodes (20): architectures, attention_probs_dropout_prob, gradient_checkpointing, hidden_act, hidden_dropout_prob, hidden_size, initializer_range, intermediate_size (+12 more) ### Community 63 - "Community 63" -Cohesion: 0.19 -Nodes (7): Shared query pipeline for historical and fundamental endpoints., Fetch live prices for B3 tickers via yfinance. B3 tickers must match, sanitizeNanValues(), StocksQueryManager, Tests for lazy JSON deserialization, Query manager should have deserialize method, TestLazyDeserialization +Cohesion: 0.13 +Nodes (13): Covers lines 100-104, 106: GET /user/sessions/current., Covers lines 100-104, 106: GET /user/sessions/current., Covers lines 100-104, 106: session found., Covers lines 100-104, 106: session found., Covers lines 100-104, 106: GET /user/sessions/current., Covers lines 100-104, 106: session found., Covers line 104: session not found., Covers line 104: session not found. (+5 more) ### Community 64 - "Community 64" Cohesion: 0.06 @@ -934,16 +940,16 @@ Cohesion: 0.1 Nodes (19): 1. Explore Agent — Prometheus Architecture, 2. MySQL Vector Storage (Researcher), 3. Memory Patterns (Researcher), A. Vector Embedding Integration, B. Pandas-First Vector Cache, C. Search Upgrade, code:python (class MemoryCache:), code:python (def searchMemories(cls, db, userId, query, embedding=None, l) (+11 more) ### Community 67 - "Community 67" -Cohesion: 0.12 -Nodes (15): execute_code(), list_files(), Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, List files in the workspace directory. Args: path: Directory pat, List files in the workspace directory. Args: path: Directory pat (+7 more) +Cohesion: 0.06 +Nodes (34): execute_code(), get_wallet_positions(), get_wallet_rebalance(), get_wallet_summary(), list_files(), Execute Python code in an isolated sandbox. Use for quantitative analysis,, Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e. (+26 more) ### Community 68 - "Community 68" Cohesion: 0.14 Nodes (30): narrate_positions(), Narrate the user's wallet positions in plain language. Read-only summary, addEntry(), applyEntries(), cachedPerformance(), createWallet(), deleteEntry(), fetchCachedClose() (+22 more) ### Community 69 - "Community 69" -Cohesion: 0.22 -Nodes (25): _base_url(), baseUrl(), checkpoint(), create(), delete_file(), destroy(), execute(), executeWithWorkspace() (+17 more) +Cohesion: 0.2 +Nodes (26): downloadWorkspaceFile(), _base_url(), baseUrl(), checkpoint(), create(), delete_file(), destroy(), execute() (+18 more) ### Community 70 - "Community 70" Cohesion: 0.11 @@ -954,8 +960,8 @@ Cohesion: 0.11 Nodes (19): API Key System, B3 Scraper, Fundamental Data, Gemini Model, Historical Data, Ma'at Stock Algorithm, Mansa Server, MySQL Database (+11 more) ### Community 72 - "Community 72" -Cohesion: 0.24 -Nodes (5): lifespan(), status(), checkDatabaseConnection(), checkSingleDb(), runMigrations() +Cohesion: 0.17 +Nodes (4): POST /memories rejects missing key., POST /memories rejects missing value., Full integration tests using mocked MemoryManager., TestMemoryEndpointsIntegration ### Community 73 - "Community 73" Cohesion: 0.16 @@ -986,24 +992,24 @@ Cohesion: 0.05 Nodes (44): cn(), AlertDialogAction(), AlertDialogCancel(), AlertDialogContent(), AlertDialogDescription(), AlertDialogFooter(), AlertDialogHeader(), AlertDialogMedia() (+36 more) ### Community 80 - "Community 80" -Cohesion: 0.21 -Nodes (15): buildSummary(), dedup(), extractDecisions(), extractMetrics(), extractSnapshots(), extractTickers(), extractToolCalls(), fetchFieldsPayload() (+7 more) +Cohesion: 0.15 +Nodes (19): buildSummary(), charCount(), countTokens(), dedup(), extractDecisions(), extractMetrics(), extractSnapshots(), extractTickers() (+11 more) ### Community 81 - "Community 81" Cohesion: 0.14 Nodes (14): getLiveCotation(), Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th (+6 more) ### Community 82 - "Community 82" -Cohesion: 0.13 -Nodes (16): arrowTypeFor(), buildCotationDateIndex(), buildFeatherCache(), buildTickerIndex(), optimizeDtypes(), P1: establish the sorted-cache invariant once at load/refresh. Sorts by (, P1: first-occurrence index over a sortCacheFrame-sorted frame. The cache, Get cached stocks data with optional column filtering. (+8 more) +Cohesion: 0.08 +Nodes (27): buildFeatherCache(), Feather build / read helpers for the stocks cache. Owns the on-disk layout (CAC, Return (engine, featherPath, nestedPath), preferring live values on the cach, Return (engine, featherPath, nestedPath), preferring live values on the cach, readFeatherDataFrame(), _runtimeConf(), tryBuildLock(), arrowTypeFor() (+19 more) ### Community 83 - "Community 83" Cohesion: 0.1 Nodes (21): B3 Market Scraper, Brazilian Stocks Market Scraper, code:env (SCRAPER_ENABLED=FALSE # default False), code:json ({), Configuration Parameters, Constraint Engine ($\Lambda$), Engines, Fundamental Engine ($\Phi$) (+13 more) ### Community 84 - "Community 84" -Cohesion: 0.11 -Nodes (16): chat(), chat_stream(), create_memory(), createMemory(), createSession(), downloadWorkspaceFile(), _forward(), getHistory() (+8 more) +Cohesion: 0.15 +Nodes (11): chat(), chat_stream(), createSession(), _forward(), getHistory(), Verify the user owns the session, raise 403 otherwise., Verify the user owns the session, raise 403 otherwise., resumeChatStream() (+3 more) ### Community 85 - "Community 85" Cohesion: 0.21 @@ -1038,16 +1044,16 @@ Cohesion: 0.09 Nodes (21): aliases, components, hooks, lib, ui, utils, iconLibrary, menuAccent (+13 more) ### Community 93 - "Community 93" -Cohesion: 0.12 -Nodes (10): System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., TestSendMessageStateIntegration (+2 more) +Cohesion: 0.14 +Nodes (10): _get_client(), getClient(), Prometheus, Lazy module-level singleton so the genai client is created once, not per request, System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about harness state usage., TestSendMessageStateIntegration (+2 more) ### Community 94 - "Community 94" Cohesion: 0.12 Nodes (16): 10. Splits — served prices are RAW by default (verified verdict, encode as-is), 11. Dividends — no dedicated endpoint (verified verdict, encode as-is), 12. Corporate actions — splits and grupamentos via one read-time mechanism, 13. Dividend methodology — ex-date smoothing check (both branches, test decides), 1. Context, 2. Decision: Design A — pure event log, derive at read time, 3. Data model (user_db, alembic), 4. Derivations (all at read time, date order) (+8 more) ### Community 95 - "Community 95" -Cohesion: 0.15 -Nodes (9): memoryMaintenance(), Decay applies to ALL active memories, not just accessed ones., Decay applies to ALL active memories, not just accessed ones., baseScore should never reach exactly 0 from decay alone., baseScore should never reach exactly 0 from decay alone., TestDecay, _create(), After 10 cycles, preference (0.99^10) > context (0.90^10). (+1 more) +Cohesion: 0.17 +Nodes (5): Tests for StocksCacheManager queryCache LRU eviction., Create a StocksCacheManager with a mock DB engine., When columns is None, cache key should be None., TestCacheLRUEviction, TestCacheTTLLogic ### Community 96 - "Community 96" Cohesion: 0.2 @@ -1058,23 +1064,23 @@ Cohesion: 0.15 Nodes (16): AuthenticationManager, AuthenticationService, PrometheusChatManager, PrometheusGenerator, PrometheusService, SessionManager, UserManager, UserService (+8 more) ### Community 98 - "Community 98" -Cohesion: 0.25 +Cohesion: 0.28 Nodes (6): extractTokenPayload(), Tests for extractTokenPayload — the standalone token extraction dependency., Create a mock Starlette Request with given headers., Authorization: Bearer (empty) — no token after Bearer., Authorization: Basic xxx — not Bearer, so no token found., TestExtractTokenPayload ### Community 99 - "Community 99" -Cohesion: 0.06 -Nodes (29): _make_prometheus_client(), Return (client, app) with prometheus router and mocked deps., Covers lines 33-36: GET /prometheus/sessions., Covers lines 33-36: GET /prometheus/sessions., Covers lines 33-36: GET /prometheus/sessions., Covers line 52: POST /prometheus/sessions., Covers line 52: POST /prometheus/sessions., Covers line 52: POST /prometheus/sessions. (+21 more) +Cohesion: 0.05 +Nodes (34): _make_prometheus_client(), Generic Exception in chat propagates to FastAPI's default 500 handler., Generic Exception in chat propagates to FastAPI's default 500 handler., Generic Exception in chat propagates to FastAPI's default 500 handler., Generic Exception in chat propagates via SSE error event., Covers line 125, 126-128: generic Exception in chat., Return (client, app) with prometheus router and mocked deps., Covers lines 33-36: GET /prometheus/sessions. (+26 more) ### Community 100 - "Community 100" -Cohesion: 0.16 -Nodes (6): _assert_gemini_safe(), Assert a tool function has only Gemini-compatible parameter types., Assert a tool function has only Gemini-compatible parameter types., test_get_state_no_state_returns_error(), test_tool_has_gemini_safe_signature(), TestStateToolFunctions +Cohesion: 0.06 +Nodes (14): _assert_gemini_safe(), Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Regression: HarnessState must never leak into tool signatures., Regression: HarnessState must never leak into tool signatures., Assert a tool function has only Gemini-compatible parameter types., Assert a tool function has only Gemini-compatible parameter types., test_get_state_no_state_returns_error() (+6 more) ### Community 101 - "Community 101" Cohesion: 0.17 -Nodes (7): Different query parameters should not share cache, Cache should expire after TTL, Tests for query result caching, CacheManager should track cached queries, Query cache should have configurable TTL, getCachedStocks should support column filtering, TestQueryCaching +Nodes (20): closeOwnSession(), popAuthSession(), Shared auth-guard + own-SessionLocal convention every tool repeats. Returns, Store a memory about the user's preferences, analysis results, or feedback., Search user's saved memories, preferences, and past analysis context. Use t, save_memory(), search_memory(), ensureOwnership() (+12 more) ### Community 102 - "Community 102" -Cohesion: 0.11 +Cohesion: 0.12 Nodes (11): BaseSettings, BaseMansaSettings, DiscordSettings, MysqlSettings, OrunmilaSettings, PrometheusSettings, ScraperSettings, StocksApiSettings (+3 more) ### Community 103 - "Community 103" @@ -1094,8 +1100,8 @@ Cohesion: 0.22 Nodes (3): parseYearInput(), TestParseYearInput, TestParseYearInput ### Community 107 - "Community 107" -Cohesion: 0.13 -Nodes (13): Covers lines 100-104, 106: GET /user/sessions/current., Covers lines 100-104, 106: GET /user/sessions/current., Covers lines 100-104, 106: session found., Covers lines 100-104, 106: session found., Covers lines 100-104, 106: GET /user/sessions/current., Covers lines 100-104, 106: session found., Covers line 104: session not found., Covers line 104: session not found. (+5 more) +Cohesion: 0.22 +Nodes (4): Authentication System, Google OAuth, JWT Authentication, TestSessionExpiryConfig ### Community 108 - "Community 108" Cohesion: 0.14 @@ -1130,8 +1136,8 @@ Cohesion: 0.17 Nodes (11): dateOnly(), EditDividendDialog(), EditLotDialog(), fmtBRL(), fmtMoney(), KIND_STYLES, lotTitle(), deleteDividend() (+3 more) ### Community 116 - "Community 116" -Cohesion: 0.13 -Nodes (17): _build_system_prompt(), buildSystemPrompt(), chatSession(), _execute_memory_tool(), executeMemoryTool(), _get_client(), _get_memory_tools(), getClient() (+9 more) +Cohesion: 0.15 +Nodes (13): _build_system_prompt(), buildSystemPrompt(), chatSession(), _execute_memory_tool(), executeMemoryTool(), _get_memory_tools(), openMCPClients(), persistEvent() (+5 more) ### Community 117 - "Community 117" Cohesion: 0.15 @@ -1147,15 +1153,15 @@ Nodes (26): code:python ("""Tests for SandboxManager file mutation helpers (dele ### Community 120 - "Community 120" Cohesion: 0.1 -Nodes (32): _make_auth_client(), Tests to cover uncovered lines across controllers, UserManager, and auth util., Covers lines 44-54, 63, 66-71: register success, ValueError, generic Exception., Covers lines 44-54, 63, 66-71: register success, ValueError, generic Exception., Covers lines 87-93, 102: login success and failure paths., Covers lines 87-93, 102: login success and failure paths., Return (client, app) with auth + user routers and mocked getSession., Covers lines 107, 109-130, 133: logout token extraction and revocation. (+24 more) +Nodes (32): _make_auth_client(), Tests to cover uncovered lines across controllers, UserManager, and auth util., Covers lines 44-54, 63, 66-71: register success, ValueError, generic Exception., Covers lines 44-54, 63, 66-71: register success, ValueError, generic Exception., Return (client, app) with auth + user routers and mocked getSession., Covers lines 107, 109-130, 133: logout token extraction and revocation., Covers lines 111-113: token extracted from Authorization Bearer header., Covers lines 155-156, 158, 160-168, 170-177, 179-184, 186, 190-204: googleCallba (+24 more) ### Community 121 - "Community 121" Cohesion: 0.21 Nodes (12): code:python (import inspect), code:python (from main.app.prometheus.sandbox import SandboxManager), code:python (TOOL_REGISTRY: dict[str, Any] = {), code:python (## Code Sandbox (On-Demand)), code:bash (git add main/app/prometheus/agent.py), code:dockerfile (FROM python:3.11-slim), code:bash (git add Dockerfile.sandbox), Phase 6: Agent Integration (All Layers) (+4 more) ### Community 122 - "Community 122" -Cohesion: 0.15 -Nodes (10): test_setup_discord_handler_disabled(), test_setup_discord_handler_enabled(), Many concurrent emit() calls must not create more threads than max_workers., Verify that DiscordHandler submits to a bounded executor, not raw threads., The module-level discordExecutor must exist with max_workers <= 5., DiscordHandler.emit() must use discordExecutor.submit, not Thread.start., TestDiscordHandlerThreadPool, DiscordHandler (+2 more) +Cohesion: 0.14 +Nodes (11): test_setup_discord_handler_disabled(), test_setup_discord_handler_enabled(), TestSetupLogging, Many concurrent emit() calls must not create more threads than max_workers., Verify that DiscordHandler submits to a bounded executor, not raw threads., The module-level discordExecutor must exist with max_workers <= 5., DiscordHandler.emit() must use discordExecutor.submit, not Thread.start., TestDiscordHandlerThreadPool (+3 more) ### Community 123 - "Community 123" Cohesion: 0.17 @@ -1165,10 +1171,6 @@ Nodes (12): Appendix A: Codebase Findings, code:block6 (D:\Repositories\server\) Cohesion: 0.07 Nodes (27): code:python (# tests/test_stocks_payload_cache.py), code:python (pc = self.cacheManager.tickerPayloads), code:python (# tests/test_stocks_sync_handlers.py), code:bash (git add main/controller/stocksapi_controller.py main/app/sto), code:python (def test_payload_cache_cotation_index():), code:python (self._cotations: dict[str, bytes] = {}), code:python (cotationCols = ["TICKER", "NOME", "TIME", "COTACAO 10Y PADRA), code:python (self._cotations = cot) (+19 more) -### Community 125 - "Community 125" -Cohesion: 0.13 -Nodes (3): PrometheusSession, createSession(), TestPrometheusSessionModel - ### Community 126 - "Community 126" Cohesion: 0.07 Nodes (26): code:powershell (netstat -ano | findstr ":80 " # must be empty; if not, ), code:powershell ($U = "http://localhost/stocks/cotations?search=PETR4"), code:nginx (proxy_pass http://stocks_api;), code:nginx (# Exact-match on purpose: a prefix match on /stocks/cotation), code:powershell (docker exec nginx nginx -t; if ($?) { docker exec nginx ngin), code:bash (git add nginx/conf.d/20-stocks.conf nginx/snippets/stocks-pr), code:powershell (docker stats --no-stream --format "{{.Name}},{{.CPUPerc}},{{), code:powershell ($env:PERF_API_KEY="sk-..." # all three make targets below ) (+18 more) @@ -1190,12 +1192,12 @@ Cohesion: 0.07 Nodes (27): 1.1 Functional (per surface; tags: EXISTS = build on it, PARTIAL = half reusable, MISSING = greenfield), 1.2 Non-functional, 1. Requirements, 2. Domain model, 3. API contracts (all under `/api/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout), 3. API contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout), 3. API contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth = wallet-local dependency on the **introspect contract** (user directive 2026-09-30): resolve the raw token (`X-Access-Token` → `Authorization: Bearer` → `mansa_token` cookie, order per `main/app/authentication/util.py:54-66`) → `introspectToken(db, raw)` (`main/app/authentication/introspect.py:14`) → `{userId, username, roles}` → `Roles.checkAccess(roles, Permission.WALLET)` (`main/utils/roles.py:29-39`) → `403` if absent; `Depends(getSession)` for the DB session), 4. Phased build plan (writing-plans: each phase independently reviewable; reviewer PASS per phase) (+19 more) ### Community 131 - "Community 131" -Cohesion: 0.11 -Nodes (17): Same input → same hash., Different inputs → different hashes., Returns 32-char hex string., pack → unpack preserves values., Empty list roundtrips., 384-dim vector packs to 1536 bytes., TestContentHash, TestPackUnpack (+9 more) +Cohesion: 0.23 +Nodes (8): pack → unpack preserves values., Empty list roundtrips., 384-dim vector packs to 1536 bytes., TestPackUnpack, pack_vector(), Unpack MySQL BLOB to float list., Vectorized cosine similarity: one query against N embeddings., unpack_vector() ### Community 132 - "Community 132" Cohesion: 0.25 -Nodes (7): code:python ("""add wallet_holdings and wallet_lots tables), code:python (import main.models.wallet), code:bash (git add migrations/versions/wallet_tables_20260904_add_walle), File Structure, Global Constraints, Task 2: Alembic migration for wallet tables, Wallet Management (Thoth/Iyagba) Implementation Plan +Nodes (7): code:python (from dataclasses import dataclass), code:bash (git add main/app/wallet/__init__.py main/app/wallet/math.py ), code:python (from datetime import date), File Structure, Global Constraints, Task 3: Pure derivation math, Wallet Management (Thoth/Iyagba) Implementation Plan ### Community 133 - "Community 133" Cohesion: 0.18 @@ -1206,16 +1208,16 @@ Cohesion: 0.18 Nodes (11): code:yaml (volumes:), code:bash (git add config.py docker-compose.yml), code:python (import pytest), code:python (import logging), code:bash (git add main/app/prometheus/sandbox.py tests/test_sandbox.py), code:python (class PrometheusSettings(BaseMansaSettings):), code:yaml (environment:), code:yaml (sandbox:) (+3 more) ### Community 135 - "Community 135" -Cohesion: 0.05 -Nodes (16): ResultCache — SHA256-keyed file-based cache for computed results., File-based cache keyed by SHA256 of code. Stores results as JSON under:, Return cached result dict or None if miss., Store result with timestamp., Delete all cached results for a session., Check if a result exists for the given code., ResultCache, cache() (+8 more) +Cohesion: 0.11 +Nodes (4): cache(), Tests for ResultCache., TestColumnValidator, TestResultCache ### Community 136 - "Community 136" -Cohesion: 0.18 -Nodes (12): _getDb(), Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use (+4 more) +Cohesion: 0.09 +Nodes (23): _getDb(), Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use (+15 more) ### Community 137 - "Community 137" Cohesion: 0.05 -Nodes (50): OrunmilaSession, buildSystemPrompt(), getClient(), Orunmila, persistEvent(), createSession(), buildSummary(), countTokens() (+42 more) +Nodes (50): buildSystemPrompt(), getClient(), persistEvent(), buildSummary(), countTokens(), dedup(), extractDecisions(), extractMetrics() (+42 more) ### Community 138 - "Community 138" Cohesion: 0.18 @@ -1226,8 +1228,8 @@ Cohesion: 0.24 Nodes (6): Dataset, produce_data(), Train script for a single file Need to set the TPU address first: export XRT_TP, A class that handles the reddit data files, A class that handles one dataset, RedditDataset ### Community 140 - "Community 140" -Cohesion: 0.07 -Nodes (36): PrometheusMemory, PrometheusMemory, MemoryManager, PrometheusMemory, All memory operations. Stateless class methods., PrometheusService, TestDifferentKeysNoMerge, TestExactSameKeyUpdates (+28 more) +Cohesion: 0.09 +Nodes (31): PrometheusMemory, PrometheusMemory, MemoryManager, PrometheusMemory, All memory operations. Stateless class methods., PrometheusService, TestDifferentKeysNoMerge, TestExactSameKeyUpdates (+23 more) ### Community 141 - "Community 141" Cohesion: 0.24 @@ -1270,8 +1272,8 @@ Cohesion: 0.2 Nodes (3): MEMORY_TOOLS must be defined as a Tool wrapping FunctionDeclarations., MEMORY_TOOLS must be a list of callables with proper signatures., TestMemoryToolsDefinition ### Community 152 - "Community 152" -Cohesion: 0.14 -Nodes (25): FastAPI, listEarnings(), syncEarnings(), addEntry(), applyEntries(), deleteEntry(), listEntries(), positionAtDate() (+17 more) +Cohesion: 0.13 +Nodes (26): get_wallet_allocation(), get_wallet_performance(), list_wallet_earnings(), Break wallet equity down by ticker or asset type. Read-only: never mutate, Break wallet equity down by ticker or asset type. Read-only: never mutate, List accrued earnings (dividends, JSCP) for a wallet. Read-only: never mu, List accrued earnings (dividends, JSCP) for a wallet. Read-only: never mu, Compute time-weighted return, volatility, and dividends for a wallet or ticker. (+18 more) ### Community 153 - "Community 153" Cohesion: 0.11 @@ -1310,8 +1312,8 @@ Cohesion: 0.11 Nodes (18): Category 2: Async/Sync Inconsistencies (MEDIUM), Category 4: Caching & Memory (MEDIUM), Category 6: Configuration & Environment (LOW), Category 7: Code Quality (LOW), Executive Summary, Full Code Review Report, Issue 2.1 — All route handlers are synchronous, Issue 2.2 — ServiceManager runs uvicorn in daemon threads (+10 more) ### Community 162 - "Community 162" -Cohesion: 0.12 -Nodes (10): Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Tests covering query.py lines 50-67., Tests covering query.py lines 50-67., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Tests covering query.py lines 50-67., Tests covering query.py lines 50-67. (+2 more) +Cohesion: 0.21 +Nodes (7): ResultCache — SHA256-keyed file-based cache for computed results., File-based cache keyed by SHA256 of code. Stores results as JSON under:, Return cached result dict or None if miss., Store result with timestamp., Delete all cached results for a session., Check if a result exists for the given code., ResultCache ### Community 163 - "Community 163" Cohesion: 0.22 @@ -1346,8 +1348,8 @@ Cohesion: 0.25 Nodes (8): padding, direction, pad_id, pad_to_multiple_of, pad_token, pad_type_id, strategy, Fixed ### Community 172 - "Community 172" -Cohesion: 0.12 -Nodes (19): AuthenticationManager, SessionManager, PrometheusChatManager, Cover getGoogleSSO (lines 6-14)., Cover getGoogleSSO (lines 6-14)., Cover __init__ and updateDates., Cover __init__ and updateDates (lines 22-37)., Cover streamMessage in agent.py. (+11 more) +Cohesion: 0.13 +Nodes (18): SessionManager, PrometheusChatManager, Cover getGoogleSSO (lines 6-14)., Cover getGoogleSSO (lines 6-14)., Cover __init__ and updateDates., Cover __init__ and updateDates (lines 22-37)., Cover streamMessage in agent.py., Cover sendMessage and streamMessage in agent.py. (+10 more) ### Community 173 - "Community 173" Cohesion: 0.25 @@ -1398,8 +1400,8 @@ Cohesion: 0.38 Nodes (7): code:python (import pytest), code:python (from __future__ import annotations), code:bash (git add main/app/prometheus/context.py tests/test_context.py), Phase 4: ToolContext (Bundled Dispatch Dependencies), Phase 4: ToolContext (Replace God Function), Task 5: ToolContext — Dataclass for Agent Use, Task 5: ToolContext — Single Dispatch Object ### Community 186 - "Community 186" -Cohesion: 0.07 -Nodes (4): Tests for inline pagination params (used in user + prometheus controllers)., TestInlinePagination, TestPaginationParams, PaginationParams +Cohesion: 0.1 +Nodes (15): generateKey(), JSONBytesResponse, listFields(), Sends pre-serialized JSON bytes without re-encoding (cache-friendly)., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental. (+7 more) ### Community 187 - "Community 187" Cohesion: 0.25 @@ -1430,8 +1432,8 @@ Cohesion: 0.33 Nodes (6): normalizer, clean_text, handle_chinese_chars, lowercase, strip_accents, type ### Community 194 - "Community 194" -Cohesion: 0.18 -Nodes (11): listFields(), Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental. (+3 more) +Cohesion: 0.08 +Nodes (23): Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers line 16: empty password raises ValueError., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 45-51: verifyAccessToken with expired and invalid tokens. (+15 more) ### Community 195 - "Community 195" Cohesion: 0.33 @@ -1534,12 +1536,12 @@ Cohesion: 0.4 Nodes (5): model, continuing_subword_prefix, max_input_chars_per_word, type, unk_token ### Community 221 - "Community 221" -Cohesion: 0.16 -Nodes (14): execute_code(), Store a value in the harness state for this session. Use this to save inter, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis, (+6 more) +Cohesion: 0.11 +Nodes (21): execute_code(), Store a value in the harness state for this session. Use this to save inter, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Execute Python code in an isolated sandbox. Use for quantitative analysis,, Read a file from the workspace. Args: path: Path to the file (e. (+13 more) ### Community 222 - "Community 222" -Cohesion: 0.19 -Nodes (17): charCount(), countTokens(), getTokenizer(), applyUpdate(), countMemories(), countTokensCached(), extract(), findSimilarKey() (+9 more) +Cohesion: 0.27 +Nodes (8): initialize(), P5: register memory maintenance on the shared scheduler. Kept in this ser, registerMemoryMaintenanceJob(), getSharedScheduler(), P5: single shared BackgroundScheduler for all services. Replaces the 4 per-serv, Return the process-wide scheduler, starting it on first use., Register func on the shared scheduler (replaces any same-id job). trigger i, registerJob() ### Community 223 - "Community 223" Cohesion: 0.4 @@ -1574,8 +1576,8 @@ Cohesion: 0.18 Nodes (11): 2.2.1 Complexity hotspots table (H1–H17 condensed to P0/P1/P2), 2.2.2 Blob inventory (LOC table + SRP evidence), 2.2.3 Mass data loads, 2.2.4 Phased fix roadmap (P0/P1/P2), §2.2 CODE EFFICIENCY — O(n²), Complexity & Blob Anti-Patterns, code:block4 (scraper.py:44 671 LOC — mass loads: SELECT * fetchma), code:powershell (ruff check . && ruff format --check .), code:powershell (pytest tests/test_stocks_cache_concurrency.py -v # ThreadPo) (+3 more) ### Community 231 - "Community 231" -Cohesion: 0.15 -Nodes (11): _count_memories(), _create_memory(), _get_memory(), Keys with Jaccard > 0.8 should merge., Keys with Jaccard > 0.8 should merge., Keys with low similarity should not merge., Keys with low similarity should not merge., Keys with low similarity should not merge. (+3 more) +Cohesion: 0.17 +Nodes (7): OrunmilaMemory, OrunmilaSession, Orunmila, createSession(), OrunmilaChatManager, MemoryCandidate, OrunmilaMemory ### Community 232 - "Community 232" Cohesion: 0.4 @@ -1586,8 +1588,8 @@ Cohesion: 0.4 Nodes (5): 8. Build Sequence (4 phases, each independently shippable), Phase 0 — Sandbox foundation (1-2 days, no user-facing change), Phase 1 — MCP exposure of STOCKS_API (1 day), Phase 2 — Refactor PROMETHEUS to agentic (3-5 days, the big one), Phase 3 — Hardening (1-2 days, can ship incrementally) ### Community 234 - "Community 234" -Cohesion: 0.11 -Nodes (25): chat_stream(), downloadWorkspaceFile(), getHistory(), resumeChatStream(), updateSessionTitle(), verifySessionOwnsership(), OrunmilaSandbox, create() (+17 more) +Cohesion: 0.1 +Nodes (27): chat_stream(), downloadWorkspaceFile(), getHistory(), resumeChatStream(), updateSessionTitle(), verifySessionOwnsership(), OrunmilaSandbox, create() (+19 more) ### Community 236 - "Community 236" Cohesion: 0.5 @@ -1678,8 +1680,8 @@ Cohesion: 0.22 Nodes (8): 1. Prime owns the goal, lanes own the work, 2. Dispatch: `delegate()`, one per lane, one turn, 3. Delegate toolsets vary — verify each lane, 4. Trust nothing — verify everything, 5. Windows PowerShell survival, 6. Finish per lane, not per swarm, 7. Standing bans (this repo), SWARMS.md — subagent swarm playbook (OpenCode / Hermes) ### Community 474 - "Community 474" -Cohesion: 0.1 -Nodes (9): B3Scraper, getCurrentSelic(), getInitialData(), calculateInvestingScore(), initialize(), P5: register the scraper cron jobs on the shared scheduler. Kept in this, registerScraperJobs(), runScraper() (+1 more) +Cohesion: 0.12 +Nodes (4): B3Scraper, getCurrentSelic(), getInitialData(), calculateInvestingScore() ### Community 475 - "Community 475" Cohesion: 0.15 @@ -1710,8 +1712,8 @@ Cohesion: 0.5 Nodes (4): code:python (def test_session_scoped_memory(db_session, sample_user):), code:python (# Add to main/models/memory.py), code:bash (git add main/models/memory.py main/app/prometheus/memory.py ), Task 8: Session Scoping ### Community 482 - "Community 482" -Cohesion: 0.23 -Nodes (13): fetchXangoScores(), getPositions(), getRebalance(), pricePass(), XANGO quality score per ticker (0-100 scale). One fundamental read per tick, XANGO quality score per ticker (0-100 scale). One fundamental read per tick, XANGO-informed buy flag (pure function, deterministic, no learned params)., Shared live-price/equity pass for positions + rebalance (single source, no dupli (+5 more) +Cohesion: 0.14 +Nodes (22): fetchCachedClose(), fetchLivePrices(), fetchMarketDividends(), fetchPadraoCloses(), stocksApiBase(), stocksApiHeaders(), fetchXangoScores(), getPositions() (+14 more) ### Community 483 - "Community 483" Cohesion: 0.5 @@ -1742,28 +1744,28 @@ Cohesion: 0.22 Nodes (8): API Endpoints, code:env (ORUNMILA_ENABLED=TRUE), code:bash (python run.py), code:mermaid (graph TD), License, Orunmila, Usage, Workflow ### Community 491 - "Community 491" -Cohesion: 0.08 -Nodes (6): Pytest Testing, Tests for main/utils/roles.py — covers requirePermission and edge cases., TestCheckAccess, TestPermissionAll, TestRequirePermission, TestRolesHierarchy +Cohesion: 0.09 +Nodes (5): Tests for main/utils/roles.py — covers requirePermission and edge cases., TestCheckAccess, TestPermissionAll, TestRequirePermission, TestRolesHierarchy ### Community 492 - "Community 492" Cohesion: 0.33 Nodes (5): Baseline (lane 4), Export recipe, Move triggers (any one fires the migration), Options, Vector Scale-Up Runbook ### Community 493 - "Community 493" -Cohesion: 0.09 -Nodes (10): Verify memory endpoints exist and are wired correctly., GET /prometheus/memories exists., POST /memories rejects missing key., POST /memories rejects missing value., POST /prometheus/memories exists., DELETE /prometheus/memories/{id} exists., GET /memories requires authentication., Full integration tests using mocked MemoryManager. (+2 more) +Cohesion: 0.29 +Nodes (6): GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422. ### Community 495 - "Community 495" Cohesion: 0.05 Nodes (42): 0. The blockers, ranked, 1.1 Process model — exactly one process, several threads, 1.1 Runtime topology — one process, many threads, 1.2 Cache (post-refactor) — RAM sharing works, 1.2 The cache is already the right shape for multi-process, 1.3 Per-process resources that multiply with N workers, 1.3 Per-process state that multiplies with N, 1. Verified current state (+34 more) ### Community 497 - "Community 497" -Cohesion: 0.19 -Nodes (11): buildFeatherCache(), Feather build / read helpers for the stocks cache. Owns the on-disk layout (CAC, Return (engine, featherPath, nestedPath), preferring live values on the cach, Return (engine, featherPath, nestedPath), preferring live values on the cach, readFeatherDataFrame(), _runtimeConf(), tryBuildLock(), arrowTypeFor() (+3 more) +Cohesion: 0.17 +Nodes (7): Tests for dynamic ticker index feature, Ticker index should be built when cache is loaded, Ticker index should contain all tickers from cache, Ticker index should be case-insensitive, Looking up ticker should return valid row index, Ticker index should be rebuilt when cache refreshes, TestTickerIndex ### Community 498 - "Community 498" -Cohesion: 0.07 -Nodes (30): Covers lines 114-115: session ownership check fails., Covers lines 114-115: session ownership check fails., Covers lines 114-115: session ownership check fails., Covers lines 120-121: session ownership check fails., Covers lines 114-115: session ownership check fails., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136. (+22 more) +Cohesion: 0.06 +Nodes (27): Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 126, 131, 135-136., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 127-129: session not found., Covers lines 127-129: session not found. (+19 more) ### Community 499 - "Community 499" Cohesion: 0.2 @@ -1777,13 +1779,9 @@ Nodes (17): createStoredApiKey(), hashApiKey(), initVerifyClient(), isValidStore Cohesion: 0.22 Nodes (3): getCurrentSession(), getSessions(), sessionToDict() -### Community 502 - "Community 502" -Cohesion: 0.2 -Nodes (7): Store a value in state. Marks state as changed for context injection., autoAbbreviate(), dedupAbbrev(), detectNestedFields(), generateAbbreviations(), TOOL_REGISTRY pattern must work correctly., TestToolRegistry - ### Community 503 - "Community 503" -Cohesion: 0.18 -Nodes (11): Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback. (+3 more) +Cohesion: 0.15 +Nodes (18): executeStateTool(), get_state(), Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, test_dispatch_get_state(), test_dispatch_set_state() (+10 more) ### Community 505 - "Community 505" Cohesion: 0.33 @@ -1806,20 +1804,20 @@ Cohesion: 0.6 Nodes (3): bench(), main(), stats() ### Community 511 - "Community 511" -Cohesion: 0.18 -Nodes (6): System prompt should include state context when provided., System prompt should not include state section when empty., State section should appear after memories section., All state entries should appear in the prompt., System prompt should work without state parameter., TestBuildSystemPromptState +Cohesion: 0.12 +Nodes (10): Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Tests covering query.py lines 50-67., Tests covering query.py lines 50-67., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Regression: is_string_dtype fails when column has strings + None (pandas 2.x)., Tests covering query.py lines 50-67., Tests covering query.py lines 50-67. (+2 more) ### Community 512 - "Community 512" Cohesion: 0.18 Nodes (11): 2.0 Grounding: what the code actually does, 2.1 Hypotheses, 2.3 Scenarios, 2.4 Protocol, 2.5 Metrics, 2.6 Acceptance thresholds — **ALL PROPOSED, freeze after first real run**, 2.7 Results doc layout, 2.8 Feeding `/status` (TODO 14) (+3 more) ### Community 517 - "Community 517" -Cohesion: 0.2 -Nodes (16): baseFrame(), deserializeJsonColumns(), envelope(), fetchLivePayload(), filterBySearchTerms(), _filterCotationByDate(), filterCotationData(), finalize() (+8 more) +Cohesion: 0.28 +Nodes (4): Shared query pipeline for historical and fundamental endpoints., Fetch live prices for B3 tickers via yfinance. B3 tickers must match, sanitizeNanValues(), StocksQueryManager ### Community 518 - "Community 518" -Cohesion: 0.08 -Nodes (21): create_memories(), Zero access but score still above threshold → not archived., Even with low score, if accessed → not archived., Even with low score, if accessed → not archived., Already archived memories are skipped., Already archived memories are skipped., Decay happens first, then archive check with new scores., Decay happens first, then archive check with new scores. (+13 more) +Cohesion: 0.1 +Nodes (15): create_memories(), Decay happens first, then archive check with new scores., Decay happens first, then archive check with new scores., Score that decays to >= threshold stays alive. 0.11 * 0.95 = 0.1045 >= 0.1., Score that decays to >= threshold stays alive. 0.12 * 0.90 = 0.108 >= 0.1., 89 days with low score → not archived (need > 90)., 89 days with low score → not archived (need > 90)., Helper to create memories with controlled baseScore, lastAccessedAt, accessCount (+7 more) ### Community 519 - "Community 519" Cohesion: 0.57 @@ -1831,31 +1829,35 @@ Nodes (9): pd.NA is not a string, so lambda returns it unchanged., All four SPEC ### Community 521 - "Community 521" Cohesion: 0.15 -Nodes (18): executeStateTool(), get_state(), Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, test_dispatch_get_state(), test_dispatch_set_state() (+10 more) +Nodes (11): _count_memories(), _create_memory(), _get_memory(), Keys with Jaccard > 0.8 should merge., Keys with Jaccard > 0.8 should merge., Keys with low similarity should not merge., Keys with low similarity should not merge., Keys with low similarity should not merge. (+3 more) ### Community 522 - "Community 522" Cohesion: 0.18 Nodes (11): 2.0 Grounding: what the code actually does, 2.1 Hypotheses, 2.3 Scenarios, 2.4 Protocol, 2.5 Metrics, 2.6 Acceptance thresholds — **ALL PROPOSED, freeze after first real run**, 2.7 Results doc layout, 2.8 Feeding `/status` (TODO 14) (+3 more) ### Community 523 - "Community 523" -Cohesion: 0.38 -Nodes (9): compactCotations(), compactRow(), compactValue(), compressResponse(), fixHeaders(), getAbbr(), getNest(), toColumnar() (+1 more) +Cohesion: 0.14 +Nodes (15): Store a value in state. Marks state as changed for context injection., compactCotations(), compactRow(), compactValue(), compressResponse(), fixHeaders(), getAbbr(), getNest() (+7 more) ### Community 524 - "Community 524" Cohesion: 0.36 Nodes (4): countTokens(), getTokenizer(), PrometheusSummarizer, smartTruncate() ### Community 525 - "Community 525" -Cohesion: 0.11 -Nodes (21): list_files(), Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, List files in the workspace directory. Args: path: Directory pat, List files in the workspace directory. Args: path: Directory pat (+13 more) +Cohesion: 0.09 +Nodes (29): check_cache(), executeMemoryTool(), list_files(), Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri (+21 more) ### Community 526 - "Community 526" Cohesion: 0.33 Nodes (7): buildKey(), clearAll(), getMatrix(), invalidateUser(), runAwait(), main(), One-shot: renormalize stored embeddings to unit norm. Usage: python scripts/back +### Community 528 - "Community 528" +Cohesion: 0.17 +Nodes (6): FastAPI, PaginationParams, getWalletIdentity(), requireWalletOwnership(), resolveRawToken(), createWallet() + ### Community 529 - "Community 529" -Cohesion: 0.29 -Nodes (6): Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404. +Cohesion: 0.07 +Nodes (26): Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 17, 22-27: user found, role not present, role added. (+18 more) ### Community 530 - "Community 530" Cohesion: 0.2 @@ -1878,12 +1880,8 @@ Cohesion: 0.13 Nodes (13): Covers lines 95-98: session deleted., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 95-98: DELETE /prometheus/sessions/{sessionId}., Covers lines 95-98: session deleted., Covers lines 96-97: session not found., Covers lines 95-98: DELETE /prometheus/sessions/{sessionId}. (+5 more) ### Community 536 - "Community 536" -Cohesion: 0.07 -Nodes (25): _downloadModel(), getEmbeddingModel(), AuthenticationService, initialize(), initialize(), OrunmilaService, initialize(), P5: register memory maintenance on the shared scheduler. Kept in this ser (+17 more) - -### Community 538 - "Community 538" -Cohesion: 0.22 -Nodes (4): Authentication System, Google OAuth, JWT Authentication, TestSessionExpiryConfig +Cohesion: 0.18 +Nodes (9): AuthenticationService, initialize(), initialize(), MCPDetectMiddleware, StocksAPIService, initialize(), getApp(), runAll() (+1 more) ### Community 539 - "Community 539" Cohesion: 0.22 @@ -1910,8 +1908,8 @@ Cohesion: 0.29 Nodes (7): code:python (def test_split_cliff_no_fake_loss_on_adjusted_series(monkeyp), code:python (def test_snapshot_includes_received_and_cash_gain(dbSession,), code:python (def test_history_merges_dividend_receipts(dbSession, sampleU), code:python (def test_ex_div_methodology_decides_received_stacking(dbSess), code:python (def ex_div_smoothing_verdict(padrao_before: float, padrao_af), code:bash (git add main/app/wallet/manager.py main/controller/wallet_co), Task 12: Split-cliff regression test + snapshot/history dividend extension + final gate ### Community 546 - "Community 546" -Cohesion: 0.18 -Nodes (11): Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers line 16: empty password raises ValueError., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 48-49: jwt.ExpiredSignatureError. (+3 more) +Cohesion: 0.23 +Nodes (9): Same input → same hash., Different inputs → different hashes., Returns 32-char hex string., TestContentHash, ALL(), content_hash(), contentHash(), MD5 hash for change detection. (+1 more) ### Community 547 - "Community 547" Cohesion: 0.33 @@ -1966,37 +1964,37 @@ Cohesion: 0.5 Nodes (4): code:python (import pytest), code:python (import logging), code:bash (git add main/app/wallet/prices.py tests/test_wallet_prices.p), Task 6: Price client — one batched STOCKS_API fetch per snapshot ### Community 560 - "Community 560" -Cohesion: 0.22 -Nodes (4): generateKey(), JSONBytesResponse, Sends pre-serialized JSON bytes without re-encoding (cache-friendly)., FastAPIResponse +Cohesion: 0.28 +Nodes (7): create_memory(), createMemory(), _downloadModel(), embed(), getEmbeddingModel(), initialize(), OrunmilaService ### Community 561 - "Community 561" Cohesion: 0.09 Nodes (17): client(), pytest_configure(), TestClient with all routers mounted — no lifespan (no DB/service init). O, Set required env vars before test collection. config.py eagerly instantia, Reset slowapi in-memory rate limiter between every test., Set required env vars before test collection. config.py eagerly instantia, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O (+9 more) +### Community 562 - "Community 562" +Cohesion: 0.18 +Nodes (10): execute_code(), list_files(), Execute Python code in an isolated sandbox. Use for quantitative analysis, s, Read a file from the workspace. Args: path: Path to the file (e.g.,, Write a file to the workspace. Use this to save data files (CSV, JSON, scrip, List files in the workspace directory. Args: path: Directory path t, Get a download link for a workspace file to share with the user. Use this w, read_file() (+2 more) + ### Community 563 - "Community 563" -Cohesion: 0.2 -Nodes (9): Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval. (+1 more) +Cohesion: 0.07 +Nodes (27): Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval. (+19 more) ### Community 564 - "Community 564" -Cohesion: 0.25 -Nodes (30): Base, BaseModel, EarningsSync, WalletCreate, IntFlag, OrunmilaMemory, Earning, Holding (+22 more) +Cohesion: 0.3 +Nodes (31): Base, BaseModel, EarningsSync, WalletCreate, Earning, Holding, Snapshot, Target (+23 more) ### Community 565 - "Community 565" Cohesion: 0.33 Nodes (6): Tests covering key.py lines 48-66., Tests covering key.py lines 48-66., Tests covering key.py lines 48-66., Tests covering key.py lines 48-66., Tests covering key.py lines 48-66., TestCreateKey ### Community 566 - "Community 566" -Cohesion: 0.33 -Nodes (5): Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is. +Cohesion: 0.22 +Nodes (5): PrometheusSession, createSession(), Thread-safe proxy that delegates to per-thread sessions., SessionProxy, TestPrometheusSessionModel ### Community 567 - "Community 567" Cohesion: 0.14 Nodes (11): Integration tests for the verifyAPIKey function., Test successful API key verification., Integration tests for the verifyAPIKey function., Test API key verification when quota is exceeded., Test API key verification with invalid key., Test API key verification with missing key., Test API key verification with invalid key., Test that API key system can be disabled. (+3 more) -### Community 568 - "Community 568" -Cohesion: 0.33 -Nodes (5): Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails. - ### Community 569 - "Community 569" Cohesion: 0.39 Nodes (8): _build_error_response(), buildErrorResponse(), generic_exception_handler(), genericExceptionHandler(), http_exception_handler(), httpExceptionHandler(), validation_exception_handler(), validationExceptionHandler() @@ -2010,25 +2008,21 @@ Cohesion: 0.25 Nodes (8): code:python (TIPO_MAP = {"Dividendo": "Div", "JCP": "JSCP", "Juros Sobre ), code:python (from freezegun import freeze_time), code:bash (git add main/service/wallet_service.py main/controller/walle), code:python (def _flat_series_with_one_div(url, params=None, headers=None), code:bash (git add main/service/wallet_service.py main/controller/walle), Goal 2 — P2 earnings + performance (starts only after Goal 1 complete), Task P2-2: Earnings sync (accrue + transition, pull-based), Task P2-3: Performance windows (on-demand reconstruction, no new table) ### Community 572 - "Community 572" -Cohesion: 0.22 -Nodes (7): Integration tests for all query optimizations, Integration tests for all query optimizations, All optimizations should be implemented, All optimizations should be implemented, Query filter should use ticker index, Query filter should use ticker index, TestQueryOptimization +Cohesion: 0.24 +Nodes (5): lifespan(), status(), checkDatabaseConnection(), checkSingleDb(), runMigrations() ### Community 573 - "Community 573" Cohesion: 0.29 Nodes (6): Global Constraints, Goal 3 — P3+ assist + narration (starts only after Goal 2 complete), Mansa Wallet Implementation Plan (P1 + P2 + P3+), Task P3-0: Write the P3+ detailed plan (required before P3-1/P3-2), Task P3-1: Ratings-assist tuning (gated on the P3+ plan), Task P3-2: Orunmila narration tools (gated on the P3+ plan) +### Community 574 - "Community 574" +Cohesion: 0.11 +Nodes (15): memoryMaintenance(), Zero access but score still above threshold → not archived., Even with low score, if accessed → not archived., Even with low score, if accessed → not archived., Already archived memories are skipped., Already archived memories are skipped., Score below threshold + accessCount=0 + 90+ days → archived., Score below threshold + accessCount=0 + 90+ days → archived. (+7 more) + ### Community 575 - "Community 575" Cohesion: 0.13 Nodes (8): create_entry_route(), delete_entry_route(), list_earnings_route(), list_entries_route(), serialize_earning(), serialize_entry(), serialize_holding(), update_entry_route() -### Community 576 - "Community 576" -Cohesion: 0.29 -Nodes (7): check_cache(), Read a file from the sandbox filesystem. Args: path: Absolute pa, List files in the workspace directory. Args: path: Directory pat, Upload a file to the sandbox filesystem. Use this to push data files (CSV,, Check if a computed result exists in the cache. Use before executing expens, read_sandbox_file(), upload_to_sandbox() - -### Community 577 - "Community 577" -Cohesion: 0.33 -Nodes (5): replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34). - ### Community 578 - "Community 578" Cohesion: 0.29 Nodes (7): code:python (def make_wallet_client(mock_identity=None, db=None):), code:python (import main.models.wallet # noqa: F401), code:python (def test_list_wallets_returns_only_mine(dbSession):), code:python (from sqlalchemy.orm import Session), code:python (from fastapi import APIRouter, Depends), code:bash (git add main/controller/wallet_controller.py main/service/wa), Task 5: Wallets CRUD + mount + `make_wallet_client` @@ -2058,20 +2052,24 @@ Cohesion: 0.33 Nodes (5): Environment, Standing rules (do not re-derive), Swarm protocol (all three goals), The three goals (sequential — one at a time, never parallel), Wallet Orchestrator Prompt (P1 + P2 + P3+ — one goal per scope) ### Community 586 - "Community 586" -Cohesion: 0.09 -Nodes (17): Tests for connection pool configuration, Stocks engine should have optimized pool settings, Integration tests for all query optimizations, All optimizations should be implemented, Query filter should use ticker index, Tests for optimized search filtering, Filter should use ticker index for O(1) lookup, Performance tests for query operations (+9 more) +Cohesion: 0.07 +Nodes (18): Different query parameters should not share cache, Cache should expire after TTL, Tests for connection pool configuration, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Query manager should have deserialize method, Tests for optimized search filtering, Filter should use ticker index for O(1) lookup (+10 more) ### Community 588 - "Community 588" -Cohesion: 0.25 -Nodes (8): Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the sandbox filesystem. Args: path: Absolute pa, Read a file from the sandbox filesystem. Args: path: Absolute pa, Read a file from the workspace. Args: path: Path to the file (e., read_file() +Cohesion: 0.33 +Nodes (5): Tests for optimized search filtering, Tests for optimized search filtering, Filter should use ticker index for O(1) lookup, Filter should use ticker index for O(1) lookup, TestFilterBySearchTerms + +### Community 589 - "Community 589" +Cohesion: 0.27 +Nodes (4): Test that invalid API key returns zero rows affected., Test that multiple API keys have independent quotas., Test that invalid API key returns zero rows affected., Test that multiple API keys have independent quotas. ### Community 591 - "Community 591" Cohesion: 0.4 Nodes (4): 0. Purpose and constraints, Next actions (not in scope here), nginx Scaling Plan — reverse proxy + response cache for `/stocks`, and the multi-server evolution, Open decisions (blocking or product-owned) ### Community 592 - "Community 592" -Cohesion: 0.2 -Nodes (9): introspectToken(), verifyAccessToken(), introspect(), Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError. (+1 more) +Cohesion: 0.33 +Nodes (4): Integration tests for all query optimizations, All optimizations should be implemented, Query filter should use ticker index, TestQueryOptimization ### Community 593 - "Community 593" Cohesion: 0.5 @@ -2098,8 +2096,8 @@ Cohesion: 0.5 Nodes (4): 1.4 Phase P1 — cache locations, TTL table, directives, code:nginx (proxy_pass http://stocks_api;), code:nginx (server {), code:bash (K=sk_test_...; U='http://localhost/stocks/historical?search=) ### Community 599 - "Community 599" -Cohesion: 0.33 -Nodes (10): Tests for main/utils/logging_config.py — covers DiscordHandler branches., test_discord_disabled(), test_discord_no_webhook(), test_exception_in_submit(), test_level_below_error(), test_message_truncation(), test_submit_called_on_error(), test_with_exception_info() (+2 more) +Cohesion: 0.38 +Nodes (9): Tests for main/utils/logging_config.py — covers DiscordHandler branches., test_discord_disabled(), test_discord_no_webhook(), test_exception_in_submit(), test_level_below_error(), test_message_truncation(), test_submit_called_on_error(), test_with_exception_info() (+1 more) ### Community 600 - "Community 600" Cohesion: 0.4 @@ -2113,13 +2111,17 @@ Nodes (5): code:python (import requests), code:python (import os), code:python ( Cohesion: 0.29 Nodes (6): dbSession(), Tests for atomic API key quota enforcement (race condition fix). Verifies tha, Sample API key data for tests., Create an in-memory SQLite database for testing., Sample API key data for tests., sampleKeyData() +### Community 603 - "Community 603" +Cohesion: 0.47 +Nodes (3): TestCleanup, cleanup(), Close the main thread's session at interpreter shutdown. + ### Community 604 - "Community 604" -Cohesion: 0.29 -Nodes (6): Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., TestStocksApiHealth +Cohesion: 0.4 +Nodes (5): initialize(), P5: register the scraper cron jobs on the shared scheduler. Kept in this, registerScraperJobs(), runScraper(), ScraperService ### Community 605 - "Community 605" -Cohesion: 0.29 -Nodes (6): Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., TestStocksApiFundamental +Cohesion: 0.33 +Nodes (5): replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34). ### Community 606 - "Community 606" Cohesion: 0.2 @@ -2133,9 +2135,9 @@ Nodes (4): code:python (from fastapi import Depends, FastAPI), code:python (impo Cohesion: 0.5 Nodes (4): code:python (from main.models.wallet import Earning), code:python (class Earning(Base):), code:bash (git add main/models/wallet.py migrations/versions/_wall), Task P2-1: `Earning` model + second migration revision -### Community 609 - "Community 609" -Cohesion: 0.29 -Nodes (6): Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers line 16: empty password raises ValueError. +### Community 610 - "Community 610" +Cohesion: 0.33 +Nodes (5): Performance tests for query operations, Query should respond within 1 second, Performance tests for query operations, Query should respond within 1 second, TestQueryPerformance ### Community 611 - "Community 611" Cohesion: 0.5 @@ -2146,91 +2148,67 @@ Cohesion: 0.67 Nodes (3): code:python (def test_summary_math_and_snapshot_upsert(dbSession, monkeyp), code:bash (git add main/service/wallet_service.py main/controller/walle), Task 8: Summary + snapshots + allocation + targets + ratings ### Community 613 - "Community 613" -Cohesion: 0.08 -Nodes (20): Tests for connection pool configuration, Tests for connection pool configuration, Stocks engine should have optimized pool settings, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Tests for lazy JSON deserialization, Query manager should have deserialize method, Query manager should have deserialize method (+12 more) +Cohesion: 0.07 +Nodes (22): Tests for connection pool configuration, Tests for connection pool configuration, Stocks engine should have optimized pool settings, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Tests for lazy JSON deserialization, Query manager should have deserialize method, Query manager should have deserialize method (+14 more) ### Community 614 - "Community 614" -Cohesion: 0.29 -Nodes (6): Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 48-49: jwt.ExpiredSignatureError. - -### Community 615 - "Community 615" Cohesion: 0.33 -Nodes (6): dispatchToolCall must route memory tool names via TOOL_REGISTRY., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., TestDispatchRoutesMemoryTools +Nodes (5): Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is. ### Community 616 - "Community 616" Cohesion: 0.2 Nodes (9): Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148. (+1 more) ### Community 617 - "Community 617" -Cohesion: 0.29 -Nodes (6): Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation. +Cohesion: 0.4 +Nodes (4): System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state. ### Community 618 - "Community 618" -Cohesion: 0.67 -Nodes (3): checkServiceConnection — success, not found, errors., checkServiceConnection — success, not found, errors., TestCheckServiceConnection - -### Community 620 - "Community 620" -Cohesion: 0.33 -Nodes (6): Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., TestAddRoleToUser +Cohesion: 0.2 +Nodes (16): baseFrame(), deserializeJsonColumns(), envelope(), fetchLivePayload(), filterBySearchTerms(), _filterCotationByDate(), filterCotationData(), finalize() (+8 more) ### Community 621 - "Community 621" Cohesion: 0.67 -Nodes (3): checkMySqlConnection — success, errors, engine=None paths., checkMySqlConnection — success, errors, engine=None paths., TestCheckMySqlConnection +Nodes (3): introspectToken(), verifyAccessToken(), introspect() ### Community 623 - "Community 623" -Cohesion: 0.33 -Nodes (5): Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added. +Cohesion: 0.5 +Nodes (4): code:python ("""add wallet_holdings and wallet_lots tables), code:python (import main.models.wallet), code:bash (git add migrations/versions/wallet_tables_20260904_add_walle), Task 2: Alembic migration for wallet tables ### Community 625 - "Community 625" -Cohesion: 0.33 -Nodes (5): Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers lines 42-44: session validation fails. - -### Community 626 - "Community 626" -Cohesion: 0.33 -Nodes (5): Covers line 24: GET /prometheus/health., Covers line 24: GET /prometheus/health., Covers line 24: GET /prometheus/health., Covers line 24: GET /prometheus/health., TestPrometheusHealth - -### Community 627 - "Community 627" -Cohesion: 0.47 -Nodes (3): TestCleanup, cleanup(), Close the main thread's session at interpreter shutdown. +Cohesion: 0.67 +Nodes (3): checkServiceConnection — success, not found, errors., checkServiceConnection — success, not found, errors., TestCheckServiceConnection ### Community 628 - "Community 628" Cohesion: 0.33 -Nodes (6): makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., TestMakeChatIncludesMemoryTools +Nodes (4): initialize(), P5: register the session-cleanup job on the shared scheduler. Kept in thi, registerSessionCleanupJobs(), UserService ### Community 629 - "Community 629" -Cohesion: 0.5 -Nodes (3): getWalletIdentity(), requireWalletOwnership(), resolveRawToken() - -### Community 630 - "Community 630" -Cohesion: 0.33 -Nodes (5): Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Regression: HarnessState must never leak into tool signatures., Regression: HarnessState must never leak into tool signatures., TestGeminiCompatibility - -### Community 631 - "Community 631" -Cohesion: 0.4 -Nodes (4): getGoogleSSO(), googleLogin(), test_get_google_sso_default_redirect(), test_get_google_sso_with_redirect() - -### Community 632 - "Community 632" -Cohesion: 0.5 -Nodes (4): code:python (from dataclasses import dataclass), code:bash (git add main/app/wallet/__init__.py main/app/wallet/math.py ), code:python (from datetime import date), Task 3: Pure derivation math +Cohesion: 0.67 +Nodes (3): checkMySqlConnection — success, errors, engine=None paths., checkMySqlConnection — success, errors, engine=None paths., TestCheckMySqlConnection ### Community 634 - "Community 634" Cohesion: 0.4 Nodes (5): Category 8: Testing Gaps (MEDIUM), Issue 8.1 — No integration tests for full request lifecycle, Issue 8.2 — No tests for scraper, stocks query, or cache, Issue 8.3 — No tests for Google OAuth callback, Issue 8.4 — No tests for session cleanup +### Community 643 - "Community 643" +Cohesion: 0.4 +Nodes (4): getGoogleSSO(), googleLogin(), test_get_google_sso_default_redirect(), test_get_google_sso_with_redirect() + ## Knowledge Gaps -- **3443 isolated node(s):** `$schema`, `style`, `rsc`, `tsx`, `config` (+3438 more) +- **3493 isolated node(s):** `$schema`, `style`, `rsc`, `tsx`, `config` (+3488 more) These have ≤1 connection - possible missing edges or undocumented components. -- **237 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. +- **250 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. ## Suggested Questions _Questions this graph is uniquely positioned to answer:_ -- **Why does `Pytest Testing` connect `Community 491` to `Authentication Core`, `Frontend Components`, `Community 129`, `Data Models & Types`, `Community 131`, `Community 518`, `Community 135`, `Device Detection`, `Community 521`, `Community 138`, `Community 140`, `Community 527`, `Community 18`, `Community 147`, `Community 24`, `Community 25`, `Community 538`, `Community 27`, `Community 29`, `Community 32`, `Community 33`, `Community 40`, `Community 44`, `Community 561`, `Community 49`, `Community 51`, `Community 186`, `Community 59`, `Community 188`, `Community 586`, `Community 595`, `Community 599`, `Community 602`, `Community 93`, `Community 477`, `Community 95`, `Community 610`, `Community 98`, `Community 100`, `Community 613`, `Community 102`, `Community 504`, `Community 493`, `Community 500`, `Community 120`, `Community 125`?** - _High betweenness centrality (0.078) - this node is a cross-community bridge._ -- **Why does `FastAPI` connect `Community 152` to `Community 129`, `Community 517`, `Community 519`, `Community 18`, `Community 147`, `Community 536`, `Community 538`, `Community 33`, `Community 34`, `Community 40`, `Community 172`, `Community 560`, `Community 54`, `Community 569`, `Community 58`, `Community 186`, `Community 575`, `Community 67`, `Community 68`, `Community 71`, `Community 72`, `Community 73`, `Community 584`, `Community 592`, `Community 84`, `Community 602`, `Community 477`, `Community 98`, `Community 504`, `Community 234`, `Community 491`, `Community 500`, `Community 501`, `Community 629`, `Community 120`?** - _High betweenness centrality (0.068) - this node is a cross-community bridge._ -- **Why does `UserManager` connect `Community 45` to `Community 256`, `Prometheus Agent`, `Community 519`, `Prometheus Memory`, `Community 140`, `Community 141`, `User Roles & Permissions`, `Community 148`, `Community 22`, `Community 535`, `Community 28`, `Community 541`, `Community 546`, `Community 162`, `Community 37`, `Community 172`, `Community 47`, `Community 563`, `Community 564`, `Community 565`, `Community 58`, `Community 61`, `Community 596`, `Community 604`, `Community 605`, `Community 99`, `Community 616`, `Community 107`, `Community 620`, `Community 493`, `Community 112`, `Community 498`, `Community 626`, `Community 114`, `Community 120`, `Community 125`?** - _High betweenness centrality (0.031) - this node is a cross-community bridge._ +- **Why does `FastAPI` connect `Community 528` to `Community 129`, `Community 519`, `Community 18`, `Community 147`, `Community 536`, `Community 152`, `Community 33`, `Community 34`, `Community 40`, `Community 43`, `Community 54`, `Community 569`, `Community 186`, `Community 58`, `Community 572`, `Community 575`, `Community 67`, `Community 68`, `Community 71`, `Community 584`, `Community 73`, `Community 84`, `Community 602`, `Community 477`, `Community 101`, `Community 504`, `Community 618`, `Community 107`, `Community 234`, `Community 621`, `Community 491`, `Community 500`, `Community 501`, `Community 502`, `Community 120`?** + _High betweenness centrality (0.060) - this node is a cross-community bridge._ +- **Why does `Pytest Testing` connect `Community 577` to `Authentication Core`, `Frontend Components`, `Community 129`, `Data Models & Types`, `Community 518`, `Community 135`, `Community 138`, `Community 140`, `Community 528`, `Community 18`, `Community 147`, `Community 21`, `Community 24`, `Community 25`, `Community 27`, `Community 29`, `Community 32`, `Community 33`, `Community 40`, `Community 44`, `Community 561`, `Community 49`, `Community 51`, `Community 566`, `Community 59`, `Community 188`, `Community 574`, `Community 72`, `Community 586`, `Community 590`, `Community 595`, `Community 599`, `Community 602`, `Community 93`, `Community 477`, `Community 100`, `Community 613`, `Community 102`, `Community 504`, `Community 107`, `Community 491`, `Community 500`, `Community 502`, `Community 503`, `Community 120`?** + _High betweenness centrality (0.055) - this node is a cross-community bridge._ +- **Why does `Config` connect `Community 564` to `Frontend Components`, `Community 137`, `Community 140`, `Community 524`, `Community 536`, `Community 538`, `Community 29`, `Community 45`, `Community 566`, `Community 189`, `Community 80`, `Community 87`, `Community 474`, `Community 604`, `Community 93`, `Community 102`, `Community 231`, `Community 105`, `Community 234`, `Community 122`?** + _High betweenness centrality (0.032) - this node is a cross-community bridge._ - **Are the 72 inferred relationships involving `StocksCacheManager` (e.g. with `TestStocksCacheManager` and `TestVerifyAPIKey`) actually correct?** _`StocksCacheManager` has 72 INFERRED edges - model-reasoned connections that need verification._ - **Are the 52 inferred relationships involving `HarnessState` (e.g. with `Prometheus` and `.streamMessage()`) actually correct?** diff --git a/graphify-out/graph.json b/graphify-out/graph.json index c6cfbe1e..47668ac7 100644 --- a/graphify-out/graph.json +++ b/graphify-out/graph.json @@ -264,7 +264,7 @@ "source_file": "run.py", "source_location": "L1", "id": "run_py", - "community": 72, + "community": 572, "norm_label": "run.py" }, { @@ -273,7 +273,7 @@ "source_file": "run.py", "source_location": "L29", "id": "server_run_lifespan", - "community": 72, + "community": 572, "norm_label": "lifespan()" }, { @@ -282,7 +282,7 @@ "source_file": "run.py", "source_location": "L82", "id": "server_run_health", - "community": 72, + "community": 572, "norm_label": "health()" }, { @@ -291,7 +291,7 @@ "source_file": "run.py", "source_location": "L87", "id": "server_run_status", - "community": 72, + "community": 572, "norm_label": "status()" }, { @@ -300,7 +300,7 @@ "source_file": "run.py", "source_location": "L121", "id": "server_run_triggerscraper", - "community": 72, + "community": 572, "norm_label": "triggerscraper()" }, { @@ -2190,7 +2190,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L1", "id": "main_app_authentication_authentication_py", - "community": 172, + "community": 43, "norm_label": "authentication.py" }, { @@ -2199,7 +2199,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L14", "id": "authentication_authentication_authenticationmanager", - "community": 172, + "community": 45, "norm_label": "authenticationmanager" }, { @@ -2217,7 +2217,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L51", "id": "authentication_authentication_authenticategoogleuser", - "community": 172, + "community": 43, "norm_label": "authenticategoogleuser()" }, { @@ -2235,7 +2235,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L79", "id": "authentication_authentication_resolveuniqueusername", - "community": 172, + "community": 43, "norm_label": "resolveuniqueusername()" }, { @@ -2253,7 +2253,7 @@ "source_file": "main/app/authentication/introspect.py", "source_location": "L1", "id": "main_app_authentication_introspect_py", - "community": 592, + "community": 621, "norm_label": "introspect.py" }, { @@ -2262,7 +2262,7 @@ "source_file": "main/app/authentication/introspect.py", "source_location": "L14", "id": "authentication_introspect_introspecttoken", - "community": 592, + "community": 621, "norm_label": "introspecttoken()" }, { @@ -2379,7 +2379,7 @@ "source_file": "main/app/authentication/sso.py", "source_location": "L1", "id": "main_app_authentication_sso_py", - "community": 631, + "community": 643, "norm_label": "sso.py" }, { @@ -2388,7 +2388,7 @@ "source_file": "main/app/authentication/sso.py", "source_location": "L6", "id": "authentication_sso_getgooglesso", - "community": 631, + "community": 643, "norm_label": "getgooglesso()" }, { @@ -2397,7 +2397,7 @@ "source_file": "main/app/authentication/util.py", "source_location": "L1", "id": "main_app_authentication_util_py", - "community": 538, + "community": 107, "norm_label": "util.py" }, { @@ -2424,7 +2424,7 @@ "source_file": "main/app/authentication/util.py", "source_location": "L31", "id": "authentication_util_createaccesstoken", - "community": 58, + "community": 43, "norm_label": "createaccesstoken()" }, { @@ -2433,7 +2433,7 @@ "source_file": "main/app/authentication/util.py", "source_location": "L44", "id": "authentication_util_verifyaccesstoken", - "community": 592, + "community": 621, "norm_label": "verifyaccesstoken()" }, { @@ -2487,7 +2487,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L208", "id": "orunmila_agent_orunmila", - "community": 137, + "community": 231, "norm_label": "orunmila" }, { @@ -2532,7 +2532,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L1", "id": "main_app_orunmila_chat_py", - "community": 137, + "community": 231, "norm_label": "chat.py" }, { @@ -2541,7 +2541,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L13", "id": "orunmila_chat_orunmilachatmanager", - "community": 564, + "community": 231, "norm_label": "orunmilachatmanager" }, { @@ -2550,7 +2550,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L15", "id": "orunmila_chat_getusersessions", - "community": 137, + "community": 231, "norm_label": "getusersessions()" }, { @@ -2559,7 +2559,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L34", "id": "orunmila_chat_createsession", - "community": 137, + "community": 231, "norm_label": "createsession()" }, { @@ -2568,7 +2568,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L42", "id": "orunmila_chat_updatesessiontitle", - "community": 137, + "community": 231, "norm_label": "updatesessiontitle()" }, { @@ -2577,7 +2577,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L53", "id": "orunmila_chat_appendhistory", - "community": 137, + "community": 231, "norm_label": "appendhistory()" }, { @@ -2586,7 +2586,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L72", "id": "orunmila_chat_gethistory", - "community": 137, + "community": 231, "norm_label": "gethistory()" }, { @@ -2595,7 +2595,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L93", "id": "orunmila_chat_deletesession", - "community": 137, + "community": 231, "norm_label": "deletesession()" }, { @@ -2604,7 +2604,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L107", "id": "orunmila_chat_verifysessionownership", - "community": 137, + "community": 231, "norm_label": "verifysessionownership()" }, { @@ -2937,7 +2937,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L64", "id": "orunmila_memory_memorycandidate", - "community": 564, + "community": 231, "norm_label": "memorycandidate" }, { @@ -3036,7 +3036,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L194", "id": "orunmila_memory_orunmilamemory", - "community": 564, + "community": 231, "norm_label": "orunmilamemory" }, { @@ -3391,247 +3391,409 @@ "norm_label": ".forward()" }, { - "label": "tools.py", + "label": "vector.py", "file_type": "code", - "source_file": "main/app/orunmila/tools.py", + "source_file": "main/app/orunmila/vector.py", "source_location": "L1", - "id": "main_app_orunmila_tools_py", - "community": 67, - "norm_label": "tools.py" + "id": "main_app_orunmila_vector_py", + "community": 137, + "norm_label": "vector.py" }, { - "label": "search_memory()", + "label": "normalizeRows()", "file_type": "code", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L21", - "id": "orunmila_tools_search_memory", - "community": 67, - "norm_label": "search_memory()" + "source_file": "main/app/orunmila/vector.py", + "source_location": "L10", + "id": "orunmila_vector_normalizerows", + "community": 137, + "norm_label": "normalizerows()" }, { - "label": "save_memory()", + "label": "embed()", "file_type": "code", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L52", - "id": "orunmila_tools_save_memory", + "source_file": "main/app/orunmila/vector.py", + "source_location": "L15", + "id": "orunmila_vector_embed", "community": 137, - "norm_label": "save_memory()" + "norm_label": "embed()" }, { - "label": "execute_code()", + "label": "decodeEmbeddings()", "file_type": "code", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L94", - "id": "orunmila_tools_execute_code", - "community": 67, - "norm_label": "execute_code()" + "source_file": "main/app/orunmila/vector.py", + "source_location": "L19", + "id": "orunmila_vector_decodeembeddings", + "community": 137, + "norm_label": "decodeembeddings()" }, { - "label": "read_file()", + "label": "batchCosineSimilarity()", "file_type": "code", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L115", - "id": "orunmila_tools_read_file", - "community": 67, - "norm_label": "read_file()" + "source_file": "main/app/orunmila/vector.py", + "source_location": "L41", + "id": "orunmila_vector_batchcosinesimilarity", + "community": 137, + "norm_label": "batchcosinesimilarity()" }, { - "label": "write_file()", + "label": "contentHash()", "file_type": "code", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L129", - "id": "orunmila_tools_write_file", - "community": 67, - "norm_label": "write_file()" + "source_file": "main/app/orunmila/vector.py", + "source_location": "L51", + "id": "orunmila_vector_contenthash", + "community": 137, + "norm_label": "contenthash()" }, { - "label": "list_files()", + "label": "toVectorString()", "file_type": "code", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L145", - "id": "orunmila_tools_list_files", - "community": 67, - "norm_label": "list_files()" + "source_file": "main/app/orunmila/vector.py", + "source_location": "L55", + "id": "orunmila_vector_tovectorstring", + "community": 137, + "norm_label": "tovectorstring()" }, { - "label": "serve_file()", + "label": "fromVectorString()", "file_type": "code", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L158", - "id": "orunmila_tools_serve_file", - "community": 234, - "norm_label": "serve_file()" + "source_file": "main/app/orunmila/vector.py", + "source_location": "L59", + "id": "orunmila_vector_fromvectorstring", + "community": 137, + "norm_label": "fromvectorstring()" }, { - "label": "narrate_positions()", + "label": "getRelevanceScore()", "file_type": "code", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L183", - "id": "orunmila_tools_narrate_positions", - "community": 68, - "norm_label": "narrate_positions()" + "source_file": "main/app/orunmila/vector.py", + "source_location": "L71", + "id": "orunmila_vector_getrelevancescore", + "community": 137, + "norm_label": "getrelevancescore()" }, { - "label": "dispatchToolCall()", + "label": "context.py", "file_type": "code", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L260", - "id": "orunmila_tools_dispatchtoolcall", - "community": 137, - "norm_label": "dispatchtoolcall()" + "source_file": "main/app/orunmila/tools/context.py", + "source_location": "L1", + "id": "main_app_orunmila_tools_context_py", + "community": 101, + "norm_label": "context.py" }, { - "label": "Search user's saved memories, preferences, and past analysis context. Use", + "label": "popAuthSession()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/context.py", + "source_location": "L7", + "id": "tools_context_popauthsession", + "community": 101, + "norm_label": "popauthsession()" + }, + { + "label": "closeOwnSession()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/context.py", + "source_location": "L24", + "id": "tools_context_closeownsession", + "community": 101, + "norm_label": "closeownsession()" + }, + { + "label": "Shared auth-guard + own-SessionLocal convention every tool repeats. Returns", "file_type": "rationale", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L22", - "id": "orunmila_tools_rationale_22", - "community": 67, - "norm_label": "search user's saved memories, preferences, and past analysis context. use" + "source_file": "main/app/orunmila/tools/context.py", + "source_location": "L8", + "id": "tools_context_rationale_8", + "community": 101, + "norm_label": "shared auth-guard + own-sessionlocal convention every tool repeats. returns" + }, + { + "label": "memory.py", + "file_type": "code", + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L1", + "id": "main_app_orunmila_tools_memory_py", + "community": 101, + "norm_label": "memory.py" + }, + { + "label": "search_memory()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L7", + "id": "tools_memory_search_memory", + "community": 101, + "norm_label": "search_memory()" + }, + { + "label": "save_memory()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L32", + "id": "tools_memory_save_memory", + "community": 101, + "norm_label": "save_memory()" + }, + { + "label": "Search user's saved memories, preferences, and past analysis context. Use t", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L8", + "id": "tools_memory_rationale_8", + "community": 101, + "norm_label": "search user's saved memories, preferences, and past analysis context. use t" }, { "label": "Store a memory about the user's preferences, analysis results, or feedback.", "file_type": "rationale", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L53", - "id": "orunmila_tools_rationale_53", - "community": 137, + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L33", + "id": "tools_memory_rationale_33", + "community": 101, "norm_label": "store a memory about the user's preferences, analysis results, or feedback." }, { - "label": "Execute Python code in an isolated sandbox. Use for quantitative analysis,", - "file_type": "rationale", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L95", - "id": "orunmila_tools_rationale_95", - "community": 67, - "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis," + "label": "sandbox.py", + "file_type": "code", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L1", + "id": "main_app_orunmila_tools_sandbox_py", + "community": 562, + "norm_label": "sandbox.py" }, { - "label": "Read a file from the workspace. Args: path: Path to the file (e.", + "label": "execute_code()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L11", + "id": "tools_sandbox_execute_code", + "community": 562, + "norm_label": "execute_code()" + }, + { + "label": "read_file()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L32", + "id": "tools_sandbox_read_file", + "community": 562, + "norm_label": "read_file()" + }, + { + "label": "write_file()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L46", + "id": "tools_sandbox_write_file", + "community": 562, + "norm_label": "write_file()" + }, + { + "label": "list_files()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L62", + "id": "tools_sandbox_list_files", + "community": 562, + "norm_label": "list_files()" + }, + { + "label": "serve_file()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L75", + "id": "tools_sandbox_serve_file", + "community": 562, + "norm_label": "serve_file()" + }, + { + "label": "Execute Python code in an isolated sandbox. Use for quantitative analysis, s", "file_type": "rationale", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L116", - "id": "orunmila_tools_rationale_116", - "community": 67, - "norm_label": "read a file from the workspace. args: path: path to the file (e." + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L12", + "id": "tools_sandbox_rationale_12", + "community": 562, + "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis, s" }, { - "label": "Write a file to the workspace. Use this to save data files (CSV, JSON, scri", + "label": "Read a file from the workspace. Args: path: Path to the file (e.g.,", "file_type": "rationale", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L130", - "id": "orunmila_tools_rationale_130", - "community": 67, - "norm_label": "write a file to the workspace. use this to save data files (csv, json, scri" + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L33", + "id": "tools_sandbox_rationale_33", + "community": 562, + "norm_label": "read a file from the workspace. args: path: path to the file (e.g.," }, { - "label": "List files in the workspace directory. Args: path: Directory pat", + "label": "Write a file to the workspace. Use this to save data files (CSV, JSON, scrip", "file_type": "rationale", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L146", - "id": "orunmila_tools_rationale_146", - "community": 67, - "norm_label": "list files in the workspace directory. args: path: directory pat" + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L47", + "id": "tools_sandbox_rationale_47", + "community": 562, + "norm_label": "write a file to the workspace. use this to save data files (csv, json, scrip" }, { - "label": "Get a download link for a workspace file to share with the user. Use this", + "label": "List files in the workspace directory. Args: path: Directory path t", "file_type": "rationale", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L159", - "id": "orunmila_tools_rationale_159", - "community": 234, - "norm_label": "get a download link for a workspace file to share with the user. use this" + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L63", + "id": "tools_sandbox_rationale_63", + "community": 562, + "norm_label": "list files in the workspace directory. args: path: directory path t" }, { - "label": "Narrate the user's wallet positions in plain language. Read-only summary", + "label": "Get a download link for a workspace file to share with the user. Use this w", "file_type": "rationale", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L184", - "id": "orunmila_tools_rationale_184", - "community": 68, - "norm_label": "narrate the user's wallet positions in plain language. read-only summary" + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L76", + "id": "tools_sandbox_rationale_76", + "community": 562, + "norm_label": "get a download link for a workspace file to share with the user. use this w" }, { - "label": "vector.py", + "label": "wallet.py", "file_type": "code", - "source_file": "main/app/orunmila/vector.py", + "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L1", - "id": "main_app_orunmila_vector_py", - "community": 137, - "norm_label": "vector.py" + "id": "main_app_orunmila_tools_wallet_py", + "community": 101, + "norm_label": "wallet.py" }, { - "label": "normalizeRows()", + "label": "ensureOwnership()", "file_type": "code", - "source_file": "main/app/orunmila/vector.py", - "source_location": "L10", - "id": "orunmila_vector_normalizerows", - "community": 137, - "norm_label": "normalizerows()" + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L15", + "id": "tools_wallet_ensureownership", + "community": 101, + "norm_label": "ensureownership()" }, { - "label": "embed()", + "label": "get_wallet_positions()", "file_type": "code", - "source_file": "main/app/orunmila/vector.py", - "source_location": "L15", - "id": "orunmila_vector_embed", - "community": 137, - "norm_label": "embed()" + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L27", + "id": "tools_wallet_get_wallet_positions", + "community": 101, + "norm_label": "get_wallet_positions()" }, { - "label": "decodeEmbeddings()", + "label": "get_wallet_summary()", "file_type": "code", - "source_file": "main/app/orunmila/vector.py", - "source_location": "L19", - "id": "orunmila_vector_decodeembeddings", - "community": 137, - "norm_label": "decodeembeddings()" + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L52", + "id": "tools_wallet_get_wallet_summary", + "community": 101, + "norm_label": "get_wallet_summary()" }, { - "label": "batchCosineSimilarity()", + "label": "get_wallet_allocation()", "file_type": "code", - "source_file": "main/app/orunmila/vector.py", - "source_location": "L41", - "id": "orunmila_vector_batchcosinesimilarity", - "community": 137, - "norm_label": "batchcosinesimilarity()" + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L77", + "id": "tools_wallet_get_wallet_allocation", + "community": 101, + "norm_label": "get_wallet_allocation()" }, { - "label": "contentHash()", + "label": "list_wallet_earnings()", "file_type": "code", - "source_file": "main/app/orunmila/vector.py", - "source_location": "L51", - "id": "orunmila_vector_contenthash", - "community": 137, - "norm_label": "contenthash()" + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L104", + "id": "tools_wallet_list_wallet_earnings", + "community": 101, + "norm_label": "list_wallet_earnings()" }, { - "label": "toVectorString()", + "label": "get_wallet_performance()", "file_type": "code", - "source_file": "main/app/orunmila/vector.py", - "source_location": "L55", - "id": "orunmila_vector_tovectorstring", - "community": 137, - "norm_label": "tovectorstring()" + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L148", + "id": "tools_wallet_get_wallet_performance", + "community": 101, + "norm_label": "get_wallet_performance()" }, { - "label": "fromVectorString()", + "label": "get_wallet_rebalance()", "file_type": "code", - "source_file": "main/app/orunmila/vector.py", - "source_location": "L59", - "id": "orunmila_vector_fromvectorstring", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L187", + "id": "tools_wallet_get_wallet_rebalance", + "community": 101, + "norm_label": "get_wallet_rebalance()" + }, + { + "label": "List wallet holdings with live prices, equity, allocation, and buy signals.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L28", + "id": "tools_wallet_rationale_28", + "community": 101, + "norm_label": "list wallet holdings with live prices, equity, allocation, and buy signals." + }, + { + "label": "Summarize applied capital, equity, and variation for a wallet. Read-only: n", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L53", + "id": "tools_wallet_rationale_53", + "community": 101, + "norm_label": "summarize applied capital, equity, and variation for a wallet. read-only: n" + }, + { + "label": "Break wallet equity down by ticker or asset type. Read-only: never mutates", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L78", + "id": "tools_wallet_rationale_78", + "community": 101, + "norm_label": "break wallet equity down by ticker or asset type. read-only: never mutates" + }, + { + "label": "List accrued earnings (dividends, JSCP) for a wallet. Read-only: never muta", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L105", + "id": "tools_wallet_rationale_105", + "community": 101, + "norm_label": "list accrued earnings (dividends, jscp) for a wallet. read-only: never muta" + }, + { + "label": "Compute time-weighted return, volatility, and dividends for a wallet or ticker.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L151", + "id": "tools_wallet_rationale_151", + "community": 101, + "norm_label": "compute time-weighted return, volatility, and dividends for a wallet or ticker." + }, + { + "label": "Show weight-share rebalance deltas per ticker (buy/sell/hold). Read-only: n", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L188", + "id": "tools_wallet_rationale_188", + "community": 101, + "norm_label": "show weight-share rebalance deltas per ticker (buy/sell/hold). read-only: n" + }, + { + "label": "__init__.py", + "file_type": "code", + "source_file": "main/app/orunmila/tools/__init__.py", + "source_location": "L1", + "id": "main_app_orunmila_tools_init_py", "community": 137, - "norm_label": "fromvectorstring()" + "norm_label": "__init__.py" }, { - "label": "getRelevanceScore()", + "label": "dispatchToolCall()", "file_type": "code", - "source_file": "main/app/orunmila/vector.py", - "source_location": "L71", - "id": "orunmila_vector_getrelevancescore", + "source_file": "main/app/orunmila/tools/__init__.py", + "source_location": "L39", + "id": "tools_init_dispatchtoolcall", "community": 137, - "norm_label": "getrelevancescore()" + "norm_label": "dispatchtoolcall()" }, { "label": "scraper.py", @@ -3846,7 +4008,7 @@ "source_file": "main/app/stocks_api/build.py", "source_location": "L1", "id": "main_app_stocks_api_build_py", - "community": 497, + "community": 82, "norm_label": "build.py" }, { @@ -3855,7 +4017,7 @@ "source_file": "main/app/stocks_api/build.py", "source_location": "L39", "id": "stocks_api_build_buildfeathercache", - "community": 497, + "community": 82, "norm_label": "buildfeathercache()" }, { @@ -3864,7 +4026,7 @@ "source_file": "main/app/stocks_api/build.py", "source_location": "L131", "id": "stocks_api_build_trybuildlock", - "community": 497, + "community": 82, "norm_label": "trybuildlock()" }, { @@ -3873,7 +4035,7 @@ "source_file": "main/app/stocks_api/build.py", "source_location": "L148", "id": "stocks_api_build_readfeatherdataframe", - "community": 497, + "community": 82, "norm_label": "readfeatherdataframe()" }, { @@ -4017,7 +4179,7 @@ "source_file": "main/app/stocks_api/frame.py", "source_location": "L1", "id": "main_app_stocks_api_frame_py", - "community": 497, + "community": 82, "norm_label": "frame.py" }, { @@ -4026,7 +4188,7 @@ "source_file": "main/app/stocks_api/frame.py", "source_location": "L14", "id": "stocks_api_frame_optimizedtypes", - "community": 497, + "community": 82, "norm_label": "optimizedtypes()" }, { @@ -4035,7 +4197,7 @@ "source_file": "main/app/stocks_api/frame.py", "source_location": "L34", "id": "stocks_api_frame_arrowtypefor", - "community": 497, + "community": 82, "norm_label": "arrowtypefor()" }, { @@ -4053,7 +4215,7 @@ "source_file": "main/app/stocks_api/frame.py", "source_location": "L55", "id": "stocks_api_frame_buildtickerindex", - "community": 497, + "community": 82, "norm_label": "buildtickerindex()" }, { @@ -4107,7 +4269,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L1", "id": "main_app_stocks_api_query_py", - "community": 517, + "community": 618, "norm_label": "query.py" }, { @@ -4116,7 +4278,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L19", "id": "stocks_api_query_sanitizenanvalues", - "community": 63, + "community": 517, "norm_label": "sanitizenanvalues()" }, { @@ -4134,7 +4296,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L55", "id": "stocks_api_query_baseframe", - "community": 517, + "community": 618, "norm_label": "baseframe()" }, { @@ -4143,7 +4305,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L68", "id": "stocks_api_query_validatefields", - "community": 517, + "community": 618, "norm_label": "validatefields()" }, { @@ -4152,7 +4314,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L81", "id": "stocks_api_query_envelope", - "community": 517, + "community": 618, "norm_label": "envelope()" }, { @@ -4161,7 +4323,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L92", "id": "stocks_api_query_finalize", - "community": 517, + "community": 618, "norm_label": "finalize()" }, { @@ -4170,7 +4332,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L125", "id": "stocks_api_query_deserializejsoncolumns", - "community": 517, + "community": 618, "norm_label": "deserializejsoncolumns()" }, { @@ -4179,7 +4341,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L156", "id": "stocks_api_query_filterbysearchterms", - "community": 517, + "community": 618, "norm_label": "filterbysearchterms()" }, { @@ -4188,7 +4350,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L174", "id": "stocks_api_query_queryhistorical", - "community": 517, + "community": 618, "norm_label": "queryhistorical()" }, { @@ -4197,7 +4359,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L231", "id": "stocks_api_query_queryfundamental", - "community": 517, + "community": 618, "norm_label": "queryfundamental()" }, { @@ -4206,7 +4368,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L294", "id": "stocks_api_query_querycotations", - "community": 517, + "community": 618, "norm_label": "querycotations()" }, { @@ -4215,7 +4377,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L335", "id": "stocks_api_query_istransientliveerror", - "community": 517, + "community": 618, "norm_label": "istransientliveerror()" }, { @@ -4224,7 +4386,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L350", "id": "stocks_api_query_fetchlivepayload", - "community": 517, + "community": 618, "norm_label": "fetchlivepayload()" }, { @@ -4233,7 +4395,7 @@ "source_file": "main/app/stocks_api/query.py", "source_location": "L359", "id": "stocks_api_query_querylivecotation", - "community": 517, + "community": 618, "norm_label": "querylivecotation()" }, { @@ -4242,25 +4404,25 @@ "source_file": "main/app/stocks_api/sync_cache.py", "source_location": "L1", "id": "main_app_stocks_api_sync_cache_py", - "community": 562, + "community": 615, "norm_label": "sync_cache.py" }, { "label": "cache()", "file_type": "code", "source_file": "main/app/stocks_api/sync_cache.py", - "source_location": "L14", + "source_location": "L15", "id": "stocks_api_sync_cache_cache", - "community": 562, + "community": 615, "norm_label": "cache()" }, { "label": "clearEndpointCache()", "file_type": "code", "source_file": "main/app/stocks_api/sync_cache.py", - "source_location": "L37", + "source_location": "L43", "id": "stocks_api_sync_cache_clearendpointcache", - "community": 562, + "community": 615, "norm_label": "clearendpointcache()" }, { @@ -4278,7 +4440,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L17", "id": "stocks_api_util_dedupabbrev", - "community": 502, + "community": 523, "norm_label": "dedupabbrev()" }, { @@ -4287,7 +4449,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L26", "id": "stocks_api_util_autoabbreviate", - "community": 502, + "community": 523, "norm_label": "autoabbreviate()" }, { @@ -4296,7 +4458,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L49", "id": "stocks_api_util_generateabbreviations", - "community": 502, + "community": 523, "norm_label": "generateabbreviations()" }, { @@ -4332,7 +4494,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L98", "id": "stocks_api_util_detectnestedfields", - "community": 502, + "community": 523, "norm_label": "detectnestedfields()" }, { @@ -4381,10 +4543,19 @@ "norm_label": "earnings.py" }, { - "label": "syncEarnings()", + "label": "EarningsManager", "file_type": "code", "source_file": "main/app/wallet/earnings.py", "source_location": "L24", + "id": "wallet_earnings_earningsmanager", + "community": 564, + "norm_label": "earningsmanager" + }, + { + "label": "syncEarnings()", + "file_type": "code", + "source_file": "main/app/wallet/earnings.py", + "source_location": "L26", "id": "wallet_earnings_syncearnings", "community": 152, "norm_label": "syncearnings()" @@ -4393,7 +4564,7 @@ "label": "listEarnings()", "file_type": "code", "source_file": "main/app/wallet/earnings.py", - "source_location": "L107", + "source_location": "L109", "id": "wallet_earnings_listearnings", "community": 152, "norm_label": "listearnings()" @@ -4411,7 +4582,7 @@ "label": "EntryCreate", "file_type": "code", "source_file": "main/app/wallet/entries.py", - "source_location": "L15", + "source_location": "L16", "id": "wallet_entries_entrycreate", "community": 564, "norm_label": "entrycreate" @@ -4420,16 +4591,25 @@ "label": "EntryUpdate", "file_type": "code", "source_file": "main/app/wallet/entries.py", - "source_location": "L26", + "source_location": "L27", "id": "wallet_entries_entryupdate", "community": 564, "norm_label": "entryupdate" }, + { + "label": "EntriesManager", + "file_type": "code", + "source_file": "main/app/wallet/entries.py", + "source_location": "L34", + "id": "wallet_entries_entriesmanager", + "community": 564, + "norm_label": "entriesmanager" + }, { "label": "applyEntries()", "file_type": "code", "source_file": "main/app/wallet/entries.py", - "source_location": "L33", + "source_location": "L36", "id": "wallet_entries_applyentries", "community": 152, "norm_label": "applyentries()" @@ -4438,7 +4618,7 @@ "label": "recalcHolding()", "file_type": "code", "source_file": "main/app/wallet/entries.py", - "source_location": "L52", + "source_location": "L55", "id": "wallet_entries_recalcholding", "community": 152, "norm_label": "recalcholding()" @@ -4447,7 +4627,7 @@ "label": "addEntry()", "file_type": "code", "source_file": "main/app/wallet/entries.py", - "source_location": "L89", + "source_location": "L90", "id": "wallet_entries_addentry", "community": 152, "norm_label": "addentry()" @@ -4456,7 +4636,7 @@ "label": "listEntries()", "file_type": "code", "source_file": "main/app/wallet/entries.py", - "source_location": "L121", + "source_location": "L124", "id": "wallet_entries_listentries", "community": 152, "norm_label": "listentries()" @@ -4465,7 +4645,7 @@ "label": "updateEntry()", "file_type": "code", "source_file": "main/app/wallet/entries.py", - "source_location": "L136", + "source_location": "L139", "id": "wallet_entries_updateentry", "community": 152, "norm_label": "updateentry()" @@ -4474,7 +4654,7 @@ "label": "deleteEntry()", "file_type": "code", "source_file": "main/app/wallet/entries.py", - "source_location": "L166", + "source_location": "L171", "id": "wallet_entries_deleteentry", "community": 152, "norm_label": "deleteentry()" @@ -4483,7 +4663,7 @@ "label": "positionAtDate()", "file_type": "code", "source_file": "main/app/wallet/entries.py", - "source_location": "L191", + "source_location": "L196", "id": "wallet_entries_positionatdate", "community": 152, "norm_label": "positionatdate()" @@ -4494,43 +4674,43 @@ "source_file": "main/app/wallet/market_data.py", "source_location": "L1", "id": "main_app_wallet_market_data_py", - "community": 152, + "community": 482, "norm_label": "market_data.py" }, { - "label": "fetchLivePrices()", + "label": "MarketDataManager", "file_type": "code", "source_file": "main/app/wallet/market_data.py", - "source_location": "L14", - "id": "wallet_market_data_fetchliveprices", - "community": 152, - "norm_label": "fetchliveprices()" + "source_location": "L19", + "id": "wallet_market_data_marketdatamanager", + "community": 564, + "norm_label": "marketdatamanager" }, { - "label": "fetchCachedClose()", + "label": "fetchLivePrices()", "file_type": "code", "source_file": "main/app/wallet/market_data.py", - "source_location": "L40", - "id": "wallet_market_data_fetchcachedclose", - "community": 152, - "norm_label": "fetchcachedclose()" + "source_location": "L22", + "id": "wallet_market_data_fetchliveprices", + "community": 482, + "norm_label": "fetchliveprices()" }, { "label": "fetchMarketDividends()", "file_type": "code", "source_file": "main/app/wallet/market_data.py", - "source_location": "L61", + "source_location": "L48", "id": "wallet_market_data_fetchmarketdividends", - "community": 152, + "community": 482, "norm_label": "fetchmarketdividends()" }, { "label": "fetchPadraoCloses()", "file_type": "code", "source_file": "main/app/wallet/market_data.py", - "source_location": "L80", + "source_location": "L68", "id": "wallet_market_data_fetchpadraocloses", - "community": 152, + "community": 482, "norm_label": "fetchpadraocloses()" }, { @@ -4542,11 +4722,20 @@ "community": 152, "norm_label": "performance.py" }, + { + "label": "PerformanceManager", + "file_type": "code", + "source_file": "main/app/wallet/performance.py", + "source_location": "L23", + "id": "wallet_performance_performancemanager", + "community": 564, + "norm_label": "performancemanager" + }, { "label": "cachedPerformance()", "file_type": "code", "source_file": "main/app/wallet/performance.py", - "source_location": "L21", + "source_location": "L29", "id": "wallet_performance_cachedperformance", "community": 152, "norm_label": "cachedperformance()" @@ -4555,7 +4744,7 @@ "label": "getPerformance()", "file_type": "code", "source_file": "main/app/wallet/performance.py", - "source_location": "L145", + "source_location": "L154", "id": "wallet_performance_getperformance", "community": 152, "norm_label": "getperformance()" @@ -4569,11 +4758,20 @@ "community": 482, "norm_label": "positions.py" }, + { + "label": "PositionsManager", + "file_type": "code", + "source_file": "main/app/wallet/positions.py", + "source_location": "L19", + "id": "wallet_positions_positionsmanager", + "community": 564, + "norm_label": "positionsmanager" + }, { "label": "fetchXangoScores()", "file_type": "code", "source_file": "main/app/wallet/positions.py", - "source_location": "L17", + "source_location": "L22", "id": "wallet_positions_fetchxangoscores", "community": 482, "norm_label": "fetchxangoscores()" @@ -4582,7 +4780,7 @@ "label": "weightOf()", "file_type": "code", "source_file": "main/app/wallet/positions.py", - "source_location": "L49", + "source_location": "L54", "id": "wallet_positions_weightof", "community": 482, "norm_label": "weightof()" @@ -4591,7 +4789,7 @@ "label": "pricePass()", "file_type": "code", "source_file": "main/app/wallet/positions.py", - "source_location": "L53", + "source_location": "L58", "id": "wallet_positions_pricepass", "community": 482, "norm_label": "pricepass()" @@ -4600,7 +4798,7 @@ "label": "rebalanceDeltas()", "file_type": "code", "source_file": "main/app/wallet/positions.py", - "source_location": "L75", + "source_location": "L80", "id": "wallet_positions_rebalancedeltas", "community": 482, "norm_label": "rebalancedeltas()" @@ -4609,7 +4807,7 @@ "label": "getPositions()", "file_type": "code", "source_file": "main/app/wallet/positions.py", - "source_location": "L91", + "source_location": "L96", "id": "wallet_positions_getpositions", "community": 482, "norm_label": "getpositions()" @@ -4618,36 +4816,27 @@ "label": "getRebalance()", "file_type": "code", "source_file": "main/app/wallet/positions.py", - "source_location": "L138", + "source_location": "L141", "id": "wallet_positions_getrebalance", "community": 482, "norm_label": "getrebalance()" }, { - "label": "XANGO quality score per ticker (0-100 scale). One fundamental read per tick", - "file_type": "rationale", - "source_file": "main/app/wallet/positions.py", - "source_location": "L18", - "id": "wallet_positions_rationale_18", - "community": 482, - "norm_label": "xango quality score per ticker (0-100 scale). one fundamental read per tick" - }, - { - "label": "Shared live-price/equity pass for positions + rebalance (single source, no dupli", + "label": "XANGO quality score per ticker (0-100 scale). One fundamental read per", "file_type": "rationale", "source_file": "main/app/wallet/positions.py", - "source_location": "L56", - "id": "wallet_positions_rationale_56", - "community": 482, - "norm_label": "shared live-price/equity pass for positions + rebalance (single source, no dupli" + "source_location": "L23", + "id": "wallet_positions_rationale_23", + "community": 637, + "norm_label": "xango quality score per ticker (0-100 scale). one fundamental read per" }, { "label": "Weight-share deltas on backend floats: target_i = w_i/\u03a3w, targetEquity = target_", "file_type": "rationale", "source_file": "main/app/wallet/positions.py", - "source_location": "L78", - "id": "wallet_positions_rationale_78", - "community": 482, + "source_location": "L83", + "id": "wallet_positions_rationale_83", + "community": 626, "norm_label": "weight-share deltas on backend floats: target_i = w_i/\u03c3w, targetequity = target_" }, { @@ -4678,10 +4867,19 @@ "norm_label": "ratingupsert" }, { - "label": "getSummary()", + "label": "SummaryManager", "file_type": "code", "source_file": "main/app/wallet/summary.py", "source_location": "L30", + "id": "wallet_summary_summarymanager", + "community": 564, + "norm_label": "summarymanager" + }, + { + "label": "getSummary()", + "file_type": "code", + "source_file": "main/app/wallet/summary.py", + "source_location": "L32", "id": "wallet_summary_getsummary", "community": 152, "norm_label": "getsummary()" @@ -4690,7 +4888,7 @@ "label": "getAllocation()", "file_type": "code", "source_file": "main/app/wallet/summary.py", - "source_location": "L88", + "source_location": "L91", "id": "wallet_summary_getallocation", "community": 152, "norm_label": "getallocation()" @@ -4699,7 +4897,7 @@ "label": "upsertTarget()", "file_type": "code", "source_file": "main/app/wallet/summary.py", - "source_location": "L118", + "source_location": "L122", "id": "wallet_summary_upserttarget", "community": 152, "norm_label": "upserttarget()" @@ -4708,7 +4906,7 @@ "label": "set_rating()", "file_type": "code", "source_file": "main/app/wallet/summary.py", - "source_location": "L147", + "source_location": "L151", "id": "wallet_summary_set_rating", "community": 152, "norm_label": "set_rating()" @@ -4719,14 +4917,23 @@ "source_file": "main/app/wallet/wallets.py", "source_location": "L1", "id": "main_app_wallet_wallets_py", - "community": 152, + "community": 528, "norm_label": "wallets.py" }, { - "label": "getWallet()", + "label": "WalletsManager", "file_type": "code", "source_file": "main/app/wallet/wallets.py", "source_location": "L11", + "id": "wallet_wallets_walletsmanager", + "community": 564, + "norm_label": "walletsmanager" + }, + { + "label": "getWallet()", + "file_type": "code", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L13", "id": "wallet_wallets_getwallet", "community": 152, "norm_label": "getwallet()" @@ -4735,20 +4942,29 @@ "label": "createWallet()", "file_type": "code", "source_file": "main/app/wallet/wallets.py", - "source_location": "L18", + "source_location": "L20", "id": "wallet_wallets_createwallet", - "community": 152, + "community": 528, "norm_label": "createwallet()" }, { "label": "listWallets()", "file_type": "code", "source_file": "main/app/wallet/wallets.py", - "source_location": "L26", + "source_location": "L28", "id": "wallet_wallets_listwallets", - "community": 152, + "community": 528, "norm_label": "listwallets()" }, + { + "label": "wallet_service.py", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L1", + "id": "main_app_wallet_wallet_service_py", + "community": 68, + "norm_label": "wallet_service.py" + }, { "label": "authentication_controller.py", "file_type": "code", @@ -4827,7 +5043,7 @@ "source_file": "main/controller/authentication_controller.py", "source_location": "L154", "id": "controller_authentication_controller_introspect", - "community": 592, + "community": 621, "norm_label": "introspect()" }, { @@ -4836,7 +5052,7 @@ "source_file": "main/controller/authentication_controller.py", "source_location": "L180", "id": "controller_authentication_controller_googlelogin", - "community": 631, + "community": 643, "norm_label": "googlelogin()" }, { @@ -4962,7 +5178,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L1", "id": "main_controller_stocksapi_controller_py", - "community": 560, + "community": 186, "norm_label": "stocksapi_controller.py" }, { @@ -4971,7 +5187,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L28", "id": "controller_stocksapi_controller_health", - "community": 560, + "community": 186, "norm_label": "health()" }, { @@ -4980,7 +5196,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L44", "id": "controller_stocksapi_controller_listfields", - "community": 194, + "community": 186, "norm_label": "listfields()" }, { @@ -5025,7 +5241,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L45", "id": "controller_stocksapi_controller_rationale_45", - "community": 194, + "community": 186, "norm_label": "discover available field names before querying /historical or /fundamental." }, { @@ -5158,7 +5374,7 @@ "label": "WalletCreate", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L20", + "source_location": "L24", "id": "controller_wallet_controller_walletcreate", "community": 564, "norm_label": "walletcreate" @@ -5167,7 +5383,7 @@ "label": "create_wallet_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L25", + "source_location": "L29", "id": "controller_wallet_controller_create_wallet_route", "community": 575, "norm_label": "create_wallet_route()" @@ -5176,7 +5392,7 @@ "label": "list_wallets_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L35", + "source_location": "L39", "id": "controller_wallet_controller_list_wallets_route", "community": 575, "norm_label": "list_wallets_route()" @@ -5185,7 +5401,7 @@ "label": "serialize_holding()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L45", + "source_location": "L49", "id": "controller_wallet_controller_serialize_holding", "community": 575, "norm_label": "serialize_holding()" @@ -5194,7 +5410,7 @@ "label": "serialize_entry()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L51", + "source_location": "L55", "id": "controller_wallet_controller_serialize_entry", "community": 575, "norm_label": "serialize_entry()" @@ -5203,7 +5419,7 @@ "label": "create_entry_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L66", + "source_location": "L70", "id": "controller_wallet_controller_create_entry_route", "community": 575, "norm_label": "create_entry_route()" @@ -5212,7 +5428,7 @@ "label": "list_entries_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L76", + "source_location": "L80", "id": "controller_wallet_controller_list_entries_route", "community": 575, "norm_label": "list_entries_route()" @@ -5221,7 +5437,7 @@ "label": "update_entry_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L89", + "source_location": "L93", "id": "controller_wallet_controller_update_entry_route", "community": 575, "norm_label": "update_entry_route()" @@ -5230,7 +5446,7 @@ "label": "delete_entry_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L100", + "source_location": "L104", "id": "controller_wallet_controller_delete_entry_route", "community": 575, "norm_label": "delete_entry_route()" @@ -5239,7 +5455,7 @@ "label": "list_positions_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L110", + "source_location": "L114", "id": "controller_wallet_controller_list_positions_route", "community": 575, "norm_label": "list_positions_route()" @@ -5248,7 +5464,7 @@ "label": "get_rebalance_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L119", + "source_location": "L123", "id": "controller_wallet_controller_get_rebalance_route", "community": 575, "norm_label": "get_rebalance_route()" @@ -5257,7 +5473,7 @@ "label": "get_summary_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L128", + "source_location": "L132", "id": "controller_wallet_controller_get_summary_route", "community": 575, "norm_label": "get_summary_route()" @@ -5266,7 +5482,7 @@ "label": "get_allocation_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L137", + "source_location": "L141", "id": "controller_wallet_controller_get_allocation_route", "community": 575, "norm_label": "get_allocation_route()" @@ -5275,7 +5491,7 @@ "label": "upsert_target_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L147", + "source_location": "L151", "id": "controller_wallet_controller_upsert_target_route", "community": 575, "norm_label": "upsert_target_route()" @@ -5284,7 +5500,7 @@ "label": "set_rating_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L162", + "source_location": "L166", "id": "controller_wallet_controller_set_rating_route", "community": 575, "norm_label": "set_rating_route()" @@ -5293,7 +5509,7 @@ "label": "EarningsSync", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L171", + "source_location": "L175", "id": "controller_wallet_controller_earningssync", "community": 564, "norm_label": "earningssync" @@ -5302,7 +5518,7 @@ "label": "serialize_earning()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L175", + "source_location": "L179", "id": "controller_wallet_controller_serialize_earning", "community": 575, "norm_label": "serialize_earning()" @@ -5311,7 +5527,7 @@ "label": "list_earnings_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L186", + "source_location": "L190", "id": "controller_wallet_controller_list_earnings_route", "community": 575, "norm_label": "list_earnings_route()" @@ -5320,7 +5536,7 @@ "label": "sync_earnings_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L196", + "source_location": "L200", "id": "controller_wallet_controller_sync_earnings_route", "community": 575, "norm_label": "sync_earnings_route()" @@ -5329,7 +5545,7 @@ "label": "get_performance_route()", "file_type": "code", "source_file": "main/controller/wallet_controller.py", - "source_location": "L205", + "source_location": "L209", "id": "controller_wallet_controller_get_performance_route", "community": 575, "norm_label": "get_performance_route()" @@ -5358,7 +5574,7 @@ "source_file": "main/models/memory.py", "source_location": "L8", "id": "models_memory_orunmilamemory", - "community": 564, + "community": 231, "norm_label": "orunmilamemory" }, { @@ -5376,7 +5592,7 @@ "source_file": "main/models/orunmila.py", "source_location": "L1", "id": "main_models_orunmila_py", - "community": 137, + "community": 231, "norm_label": "orunmila.py" }, { @@ -5385,7 +5601,7 @@ "source_file": "main/models/orunmila.py", "source_location": "L7", "id": "models_orunmila_orunmilasession", - "community": 137, + "community": 231, "norm_label": "orunmilasession" }, { @@ -5394,7 +5610,7 @@ "source_file": "main/models/sandbox.py", "source_location": "L1", "id": "main_models_sandbox_py", - "community": 234, + "community": 4, "norm_label": "sandbox.py" }, { @@ -5610,7 +5826,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L1", "id": "main_service_orunmila_service_py", - "community": 536, + "community": 560, "norm_label": "orunmila_service.py" }, { @@ -5628,7 +5844,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L65", "id": "service_orunmila_service_orunmilaservice", - "community": 536, + "community": 560, "norm_label": "orunmilaservice" }, { @@ -5637,7 +5853,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L67", "id": "service_orunmila_service_initialize", - "community": 536, + "community": 560, "norm_label": "initialize()" }, { @@ -5646,7 +5862,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L1", "id": "main_service_scraper_service_py", - "community": 474, + "community": 604, "norm_label": "scraper_service.py" }, { @@ -5655,7 +5871,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L13", "id": "service_scraper_service_runscraper", - "community": 474, + "community": 604, "norm_label": "runscraper()" }, { @@ -5664,7 +5880,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L23", "id": "service_scraper_service_registerscraperjobs", - "community": 474, + "community": 604, "norm_label": "registerscraperjobs()" }, { @@ -5673,7 +5889,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L49", "id": "service_scraper_service_scraperservice", - "community": 474, + "community": 604, "norm_label": "scraperservice" }, { @@ -5682,7 +5898,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L51", "id": "service_scraper_service_initialize", - "community": 474, + "community": 604, "norm_label": "initialize()" }, { @@ -5745,7 +5961,7 @@ "source_file": "main/service/user_service.py", "source_location": "L1", "id": "main_service_user_service_py", - "community": 536, + "community": 628, "norm_label": "user_service.py" }, { @@ -5754,7 +5970,7 @@ "source_file": "main/service/user_service.py", "source_location": "L17", "id": "service_user_service_removeinactivesessions", - "community": 536, + "community": 628, "norm_label": "removeinactivesessions()" }, { @@ -5763,7 +5979,7 @@ "source_file": "main/service/user_service.py", "source_location": "L42", "id": "service_user_service_userservice", - "community": 536, + "community": 628, "norm_label": "userservice" }, { @@ -5772,7 +5988,7 @@ "source_file": "main/service/user_service.py", "source_location": "L44", "id": "service_user_service_initialize", - "community": 536, + "community": 628, "norm_label": "initialize()" }, { @@ -5808,7 +6024,7 @@ "source_file": "main/utils/connectivity.py", "source_location": "L1", "id": "main_utils_connectivity_py", - "community": 72, + "community": 572, "norm_label": "connectivity.py" }, { @@ -5817,7 +6033,7 @@ "source_file": "main/utils/connectivity.py", "source_location": "L11", "id": "utils_connectivity_checkdatabaseconnection", - "community": 72, + "community": 572, "norm_label": "checkdatabaseconnection()" }, { @@ -5988,7 +6204,7 @@ "source_file": "main/utils/migrator.py", "source_location": "L1", "id": "main_utils_migrator_py", - "community": 72, + "community": 572, "norm_label": "migrator.py" }, { @@ -5997,7 +6213,7 @@ "source_file": "main/utils/migrator.py", "source_location": "L8", "id": "utils_migrator_runmigrations", - "community": 72, + "community": 572, "norm_label": "runmigrations()" }, { @@ -6060,7 +6276,7 @@ "source_file": "", "source_location": "", "id": "intflag", - "community": 564, + "community": 45, "norm_label": "intflag" }, { @@ -6069,7 +6285,7 @@ "source_file": "main/utils/roles.py", "source_location": "L15", "id": "utils_roles_all", - "community": 131, + "community": 546, "norm_label": "all()" }, { @@ -6078,7 +6294,7 @@ "source_file": "main/utils/roles.py", "source_location": "L19", "id": "utils_roles_roles", - "community": 564, + "community": 45, "norm_label": "roles" }, { @@ -6105,7 +6321,7 @@ "source_file": "main/utils/scheduler.py", "source_location": "L1", "id": "main_utils_scheduler_py", - "community": 536, + "community": 222, "norm_label": "scheduler.py" }, { @@ -6114,7 +6330,7 @@ "source_file": "main/utils/scheduler.py", "source_location": "L10", "id": "utils_scheduler_getsharedscheduler", - "community": 536, + "community": 222, "norm_label": "getsharedscheduler()" }, { @@ -6123,7 +6339,7 @@ "source_file": "main/utils/scheduler.py", "source_location": "L19", "id": "utils_scheduler_registerjob", - "community": 536, + "community": 222, "norm_label": "registerjob()" }, { @@ -6159,7 +6375,7 @@ "source_file": "main/utils/models/loader.py", "source_location": "L1", "id": "main_utils_models_loader_py", - "community": 536, + "community": 560, "norm_label": "loader.py" }, { @@ -6168,7 +6384,7 @@ "source_file": "main/utils/models/loader.py", "source_location": "L12", "id": "models_loader_getembeddingmodel", - "community": 536, + "community": 560, "norm_label": "getembeddingmodel()" }, { @@ -10605,7 +10821,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L166", "id": "plans_2026_09_04_wallet_management_task_2_alembic_migration_for_wallet_tables", - "community": 132, + "community": 623, "norm_label": "task 2: alembic migration for wallet tables" }, { @@ -10614,7 +10830,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L189", "id": "plans_2026_09_04_wallet_management_codeblock_6", - "community": 132, + "community": 623, "norm_label": "code:python (\"\"\"add wallet_holdings and wallet_lots tables)" }, { @@ -10623,7 +10839,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L248", "id": "plans_2026_09_04_wallet_management_codeblock_7", - "community": 132, + "community": 623, "norm_label": "code:python (import main.models.wallet)" }, { @@ -10632,7 +10848,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L262", "id": "plans_2026_09_04_wallet_management_codeblock_8", - "community": 132, + "community": 623, "norm_label": "code:bash (git add migrations/versions/wallet_tables_20260904_add_walle)" }, { @@ -10641,7 +10857,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L269", "id": "plans_2026_09_04_wallet_management_task_3_pure_derivation_math", - "community": 632, + "community": 132, "norm_label": "task 3: pure derivation math" }, { @@ -10650,7 +10866,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L281", "id": "plans_2026_09_04_wallet_management_codeblock_9", - "community": 632, + "community": 132, "norm_label": "code:python (from datetime import date)" }, { @@ -10659,7 +10875,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L325", "id": "plans_2026_09_04_wallet_management_codeblock_10", - "community": 632, + "community": 132, "norm_label": "code:python (from dataclasses import dataclass)" }, { @@ -10668,7 +10884,7 @@ "source_file": "docs/superpowers/plans/2026-09-04-wallet-management.md", "source_location": "L384", "id": "plans_2026_09_04_wallet_management_codeblock_11", - "community": 632, + "community": 132, "norm_label": "code:bash (git add main/app/wallet/__init__.py main/app/wallet/math.py )" }, { @@ -13497,6 +13713,564 @@ "community": 208, "norm_label": "10. plans and follow-ups" }, + { + "label": "tools.py", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L1", + "community": 67, + "norm_label": "tools.py", + "id": "main_app_orunmila_tools_py" + }, + { + "label": "search_memory()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L27", + "community": 67, + "norm_label": "search_memory()", + "id": "orunmila_tools_search_memory" + }, + { + "label": "save_memory()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L58", + "community": 137, + "norm_label": "save_memory()", + "id": "orunmila_tools_save_memory" + }, + { + "label": "execute_code()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L100", + "community": 67, + "norm_label": "execute_code()", + "id": "orunmila_tools_execute_code" + }, + { + "label": "read_file()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L121", + "community": 67, + "norm_label": "read_file()", + "id": "orunmila_tools_read_file" + }, + { + "label": "write_file()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L135", + "community": 67, + "norm_label": "write_file()", + "id": "orunmila_tools_write_file" + }, + { + "label": "list_files()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L151", + "community": 67, + "norm_label": "list_files()", + "id": "orunmila_tools_list_files" + }, + { + "label": "serve_file()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L164", + "community": 234, + "norm_label": "serve_file()", + "id": "orunmila_tools_serve_file" + }, + { + "label": "get_wallet_positions()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L189", + "community": 67, + "norm_label": "get_wallet_positions()", + "id": "orunmila_tools_get_wallet_positions" + }, + { + "label": "get_wallet_summary()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L225", + "community": 67, + "norm_label": "get_wallet_summary()", + "id": "orunmila_tools_get_wallet_summary" + }, + { + "label": "get_wallet_allocation()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L261", + "community": 152, + "norm_label": "get_wallet_allocation()", + "id": "orunmila_tools_get_wallet_allocation" + }, + { + "label": "list_wallet_earnings()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L299", + "community": 152, + "norm_label": "list_wallet_earnings()", + "id": "orunmila_tools_list_wallet_earnings" + }, + { + "label": "get_wallet_performance()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L354", + "community": 152, + "norm_label": "get_wallet_performance()", + "id": "orunmila_tools_get_wallet_performance" + }, + { + "label": "get_wallet_rebalance()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L404", + "community": 67, + "norm_label": "get_wallet_rebalance()", + "id": "orunmila_tools_get_wallet_rebalance" + }, + { + "label": "dispatchToolCall()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L457", + "community": 137, + "norm_label": "dispatchtoolcall()", + "id": "orunmila_tools_dispatchtoolcall" + }, + { + "label": "Search user's saved memories, preferences, and past analysis context. Use", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L28", + "community": 67, + "norm_label": "search user's saved memories, preferences, and past analysis context. use", + "id": "orunmila_tools_rationale_28" + }, + { + "label": "Store a memory about the user's preferences, analysis results, or feedback.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L59", + "community": 137, + "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", + "id": "orunmila_tools_rationale_59" + }, + { + "label": "Execute Python code in an isolated sandbox. Use for quantitative analysis,", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L101", + "community": 67, + "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", + "id": "orunmila_tools_rationale_101" + }, + { + "label": "Read a file from the workspace. Args: path: Path to the file (e.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L122", + "community": 67, + "norm_label": "read a file from the workspace. args: path: path to the file (e.", + "id": "orunmila_tools_rationale_122" + }, + { + "label": "Write a file to the workspace. Use this to save data files (CSV, JSON, scri", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L136", + "community": 67, + "norm_label": "write a file to the workspace. use this to save data files (csv, json, scri", + "id": "orunmila_tools_rationale_136" + }, + { + "label": "List files in the workspace directory. Args: path: Directory pat", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L152", + "community": 67, + "norm_label": "list files in the workspace directory. args: path: directory pat", + "id": "orunmila_tools_rationale_152" + }, + { + "label": "Get a download link for a workspace file to share with the user. Use this", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L165", + "community": 234, + "norm_label": "get a download link for a workspace file to share with the user. use this", + "id": "orunmila_tools_rationale_165" + }, + { + "label": "List wallet holdings with live prices, equity, allocation, and buy signals.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L190", + "community": 67, + "norm_label": "list wallet holdings with live prices, equity, allocation, and buy signals.", + "id": "orunmila_tools_rationale_190" + }, + { + "label": "Summarize applied capital, equity, and variation for a wallet. Read-only:", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L226", + "community": 67, + "norm_label": "summarize applied capital, equity, and variation for a wallet. read-only:", + "id": "orunmila_tools_rationale_226" + }, + { + "label": "Break wallet equity down by ticker or asset type. Read-only: never mutate", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L262", + "community": 152, + "norm_label": "break wallet equity down by ticker or asset type. read-only: never mutate", + "id": "orunmila_tools_rationale_262" + }, + { + "label": "List accrued earnings (dividends, JSCP) for a wallet. Read-only: never mu", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L300", + "community": 152, + "norm_label": "list accrued earnings (dividends, jscp) for a wallet. read-only: never mu", + "id": "orunmila_tools_rationale_300" + }, + { + "label": "Compute time-weighted return, volatility, and dividends for a wallet or ticker.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L357", + "community": 152, + "norm_label": "compute time-weighted return, volatility, and dividends for a wallet or ticker.", + "id": "orunmila_tools_rationale_357" + }, + { + "label": "Show weight-share rebalance deltas per ticker (buy/sell/hold). Read-only:", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L405", + "community": 67, + "norm_label": "show weight-share rebalance deltas per ticker (buy/sell/hold). read-only:", + "id": "orunmila_tools_rationale_405" + }, + { + "label": "Shared live-price/equity pass for positions + rebalance (single source, no dupli", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L61", + "community": 638, + "norm_label": "shared live-price/equity pass for positions + rebalance (single source, no dupli", + "id": "wallet_positions_rationale_61" + }, + { + "label": "Weight-share deltas on backend floats: target_i = w_i/\u03a3w, targetEquity = target_", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L84", + "community": 639, + "norm_label": "weight-share deltas on backend floats: target_i = w_i/\u03c3w, targetequity = target_", + "id": "wallet_positions_rationale_84" + }, + { + "label": "Search user's saved memories, preferences, and past analysis context. Use", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L23", + "community": 67, + "norm_label": "search user's saved memories, preferences, and past analysis context. use", + "id": "orunmila_tools_rationale_23" + }, + { + "label": "Store a memory about the user's preferences, analysis results, or feedback.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L54", + "community": 137, + "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", + "id": "orunmila_tools_rationale_54" + }, + { + "label": "Execute Python code in an isolated sandbox. Use for quantitative analysis,", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L96", + "community": 67, + "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", + "id": "orunmila_tools_rationale_96" + }, + { + "label": "Read a file from the workspace. Args: path: Path to the file (e.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L117", + "community": 67, + "norm_label": "read a file from the workspace. args: path: path to the file (e.", + "id": "orunmila_tools_rationale_117" + }, + { + "label": "Write a file to the workspace. Use this to save data files (CSV, JSON, scri", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L131", + "community": 67, + "norm_label": "write a file to the workspace. use this to save data files (csv, json, scri", + "id": "orunmila_tools_rationale_131" + }, + { + "label": "List files in the workspace directory. Args: path: Directory pat", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L147", + "community": 67, + "norm_label": "list files in the workspace directory. args: path: directory pat", + "id": "orunmila_tools_rationale_147" + }, + { + "label": "Get a download link for a workspace file to share with the user. Use this", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L160", + "community": 234, + "norm_label": "get a download link for a workspace file to share with the user. use this", + "id": "orunmila_tools_rationale_160" + }, + { + "label": "List wallet holdings with live prices, equity, allocation, and buy signals.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L185", + "community": 67, + "norm_label": "list wallet holdings with live prices, equity, allocation, and buy signals.", + "id": "orunmila_tools_rationale_185" + }, + { + "label": "Summarize applied capital, equity, and variation for a wallet. Read-only:", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L224", + "community": 67, + "norm_label": "summarize applied capital, equity, and variation for a wallet. read-only:", + "id": "orunmila_tools_rationale_224" + }, + { + "label": "Break wallet equity down by ticker or asset type. Read-only: never mutate", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L263", + "community": 152, + "norm_label": "break wallet equity down by ticker or asset type. read-only: never mutate", + "id": "orunmila_tools_rationale_263" + }, + { + "label": "List accrued earnings (dividends, JSCP) for a wallet. Read-only: never mu", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L304", + "community": 152, + "norm_label": "list accrued earnings (dividends, jscp) for a wallet. read-only: never mu", + "id": "orunmila_tools_rationale_304" + }, + { + "label": "Compute time-weighted return, volatility, and dividends for a wallet or ticker.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L364", + "community": 152, + "norm_label": "compute time-weighted return, volatility, and dividends for a wallet or ticker.", + "id": "orunmila_tools_rationale_364" + }, + { + "label": "Show weight-share rebalance deltas per ticker (buy/sell/hold). Read-only:", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L415", + "community": 67, + "norm_label": "show weight-share rebalance deltas per ticker (buy/sell/hold). read-only:", + "id": "orunmila_tools_rationale_415" + }, + { + "label": "fetchCachedClose()", + "file_type": "code", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L42", + "community": 482, + "norm_label": "fetchcachedclose()", + "id": "wallet_market_data_fetchcachedclose" + }, + { + "label": "XANGO quality score per ticker (0-100 scale). One fundamental read per", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L20", + "community": 648, + "norm_label": "xango quality score per ticker (0-100 scale). one fundamental read per", + "id": "wallet_positions_rationale_20" + }, + { + "label": "Shared live-price/equity pass for positions + rebalance (single source, no dupli", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L58", + "community": 649, + "norm_label": "shared live-price/equity pass for positions + rebalance (single source, no dupli", + "id": "wallet_positions_rationale_58" + }, + { + "label": "Weight-share deltas on backend floats: target_i = w_i/\u03a3w, targetEquity = target_", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L80", + "community": 650, + "norm_label": "weight-share deltas on backend floats: target_i = w_i/\u03c3w, targetequity = target_", + "id": "wallet_positions_rationale_80" + }, + { + "label": "XANGO quality score per ticker (0-100 scale). One fundamental read per ti", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L19", + "community": 482, + "norm_label": "xango quality score per ticker (0-100 scale). one fundamental read per ti", + "id": "wallet_positions_rationale_19" + }, + { + "label": "Shared live-price/equity pass for positions + rebalance (single source, no dupli", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L57", + "community": 482, + "norm_label": "shared live-price/equity pass for positions + rebalance (single source, no dupli", + "id": "wallet_positions_rationale_57" + }, + { + "label": "Weight-share deltas on backend floats: target_i = w_i/\u03a3w, targetEquity = target_", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L79", + "community": 482, + "norm_label": "weight-share deltas on backend floats: target_i = w_i/\u03c3w, targetequity = target_", + "id": "wallet_positions_rationale_79" + }, + { + "label": "narrate_positions()", + "file_type": "code", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L183", + "community": 68, + "norm_label": "narrate_positions()", + "id": "orunmila_tools_narrate_positions" + }, + { + "label": "Search user's saved memories, preferences, and past analysis context. Use", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L22", + "community": 67, + "norm_label": "search user's saved memories, preferences, and past analysis context. use", + "id": "orunmila_tools_rationale_22" + }, + { + "label": "Store a memory about the user's preferences, analysis results, or feedback.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L53", + "community": 137, + "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", + "id": "orunmila_tools_rationale_53" + }, + { + "label": "Execute Python code in an isolated sandbox. Use for quantitative analysis,", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L95", + "community": 67, + "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", + "id": "orunmila_tools_rationale_95" + }, + { + "label": "Read a file from the workspace. Args: path: Path to the file (e.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L116", + "community": 67, + "norm_label": "read a file from the workspace. args: path: path to the file (e.", + "id": "orunmila_tools_rationale_116" + }, + { + "label": "Write a file to the workspace. Use this to save data files (CSV, JSON, scri", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L130", + "community": 67, + "norm_label": "write a file to the workspace. use this to save data files (csv, json, scri", + "id": "orunmila_tools_rationale_130" + }, + { + "label": "List files in the workspace directory. Args: path: Directory pat", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L146", + "community": 67, + "norm_label": "list files in the workspace directory. args: path: directory pat", + "id": "orunmila_tools_rationale_146" + }, + { + "label": "Get a download link for a workspace file to share with the user. Use this", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L159", + "community": 234, + "norm_label": "get a download link for a workspace file to share with the user. use this", + "id": "orunmila_tools_rationale_159" + }, + { + "label": "Narrate the user's wallet positions in plain language. Read-only summary", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L184", + "community": 68, + "norm_label": "narrate the user's wallet positions in plain language. read-only summary", + "id": "orunmila_tools_rationale_184" + }, + { + "label": "XANGO quality score per ticker (0-100 scale). One fundamental read per tick", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L18", + "community": 482, + "norm_label": "xango quality score per ticker (0-100 scale). one fundamental read per tick", + "id": "wallet_positions_rationale_18" + }, + { + "label": "Shared live-price/equity pass for positions + rebalance (single source, no dupli", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L56", + "community": 482, + "norm_label": "shared live-price/equity pass for positions + rebalance (single source, no dupli", + "id": "wallet_positions_rationale_56" + }, + { + "label": "Weight-share deltas on backend floats: target_i = w_i/\u03a3w, targetEquity = target_", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L78", + "community": 482, + "norm_label": "weight-share deltas on backend floats: target_i = w_i/\u03c3w, targetequity = target_", + "id": "wallet_positions_rationale_78" + }, { "label": "scoreBuyFlag()", "file_type": "code", @@ -13538,7 +14312,7 @@ "file_type": "code", "source_file": "main/app/wallet/auth.py", "source_location": "L1", - "community": 629, + "community": 528, "norm_label": "auth.py", "id": "main_app_wallet_auth_py" }, @@ -13547,7 +14321,7 @@ "file_type": "code", "source_file": "main/app/wallet/auth.py", "source_location": "L13", - "community": 629, + "community": 528, "norm_label": "resolverawtoken()", "id": "wallet_auth_resolverawtoken" }, @@ -13556,7 +14330,7 @@ "file_type": "code", "source_file": "main/app/wallet/auth.py", "source_location": "L26", - "community": 629, + "community": 528, "norm_label": "getwalletidentity()", "id": "wallet_auth_getwalletidentity" }, @@ -13565,7 +14339,7 @@ "file_type": "code", "source_file": "main/app/wallet/auth.py", "source_location": "L30", - "community": 629, + "community": 528, "norm_label": "requirewalletuser()", "id": "wallet_auth_requirewalletuser" }, @@ -13574,7 +14348,7 @@ "file_type": "code", "source_file": "main/app/wallet/auth.py", "source_location": "L36", - "community": 629, + "community": 528, "norm_label": "requirewalletownership()", "id": "wallet_auth_requirewalletownership" }, @@ -13583,7 +14357,7 @@ "file_type": "code", "source_file": "main/app/wallet/market_data.py", "source_location": "L16", - "community": 152, + "community": 482, "norm_label": "stocksapibase()", "id": "wallet_market_data_stocksapibase" }, @@ -13592,7 +14366,7 @@ "file_type": "code", "source_file": "main/app/wallet/market_data.py", "source_location": "L20", - "community": 152, + "community": 482, "norm_label": "stocksapiheaders()", "id": "wallet_market_data_stocksapiheaders" }, @@ -13605,15 +14379,6 @@ "norm_label": "getownedwallet()", "id": "wallet_wallets_getownedwallet" }, - { - "label": "wallet_service.py", - "file_type": "code", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L1", - "community": 68, - "norm_label": "wallet_service.py", - "id": "main_app_wallet_wallet_service_py" - }, { "label": "fetchXangoScores()", "file_type": "code", @@ -14267,7 +15032,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/sync_cache.py", "source_location": "L38", - "community": 562, + "community": 615, "norm_label": "drop every cached endpoint body \u2014 called when the feather frame is replaced.", "id": "stocks_api_sync_cache_rationale_38" }, @@ -14276,7 +15041,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/build.py", "source_location": "L50", - "community": 497, + "community": 82, "norm_label": "_runtimeconf()", "id": "stocks_api_build_runtimeconf" }, @@ -14285,7 +15050,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/build.py", "source_location": "L1", - "community": 497, + "community": 82, "norm_label": "feather build / read helpers for the stocks cache. owns the on-disk layout (cac", "id": "stocks_api_build_rationale_1" }, @@ -14294,7 +15059,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/build.py", "source_location": "L51", - "community": 497, + "community": 82, "norm_label": "return (engine, featherpath, nestedpath), preferring live values on the cach", "id": "stocks_api_build_rationale_51" }, @@ -14321,7 +15086,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/frame.py", "source_location": "L1", - "community": 497, + "community": 82, "norm_label": "pure dataframe helpers for the stocks feather cache (no i/o, no imports from sib", "id": "stocks_api_frame_rationale_1" }, @@ -14330,7 +15095,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/build.py", "source_location": "L47", - "community": 497, + "community": 82, "norm_label": "return (engine, featherpath, nestedpath), preferring live values on the cach", "id": "stocks_api_build_rationale_47" }, @@ -14438,7 +15203,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L47", - "community": 194, + "community": 186, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_47" }, @@ -14483,7 +15248,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L39", - "community": 194, + "community": 186, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_39" }, @@ -15806,7 +16571,7 @@ "file_type": "code", "source_file": "main/app/prometheus/agent.py", "source_location": "L45", - "community": 116, + "community": 93, "norm_label": "getclient()", "id": "prometheus_agent_getclient" }, @@ -15815,7 +16580,7 @@ "file_type": "code", "source_file": "main/app/prometheus/agent.py", "source_location": "L208", - "community": 116, + "community": 93, "norm_label": "prometheus", "id": "prometheus_agent_prometheus" }, @@ -15824,7 +16589,7 @@ "file_type": "code", "source_file": "main/app/prometheus/agent.py", "source_location": "L209", - "community": 116, + "community": 93, "norm_label": ".__init__()", "id": "prometheus_agent_prometheus_init" }, @@ -15887,7 +16652,7 @@ "file_type": "code", "source_file": "main/app/prometheus/chat.py", "source_location": "L33", - "community": 125, + "community": 566, "norm_label": "createsession()", "id": "prometheus_chat_createsession" }, @@ -15950,7 +16715,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L35", - "community": 222, + "community": 80, "norm_label": "gettokenizer()", "id": "prometheus_compact_gettokenizer" }, @@ -15959,7 +16724,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L47", - "community": 222, + "community": 80, "norm_label": "counttokens()", "id": "prometheus_compact_counttokens" }, @@ -16076,7 +16841,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L195", - "community": 589, + "community": 80, "norm_label": "prometheuscompactor", "id": "prometheus_compact_prometheuscompactor" }, @@ -16085,7 +16850,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L196", - "community": 589, + "community": 80, "norm_label": ".shouldcompact()", "id": "prometheus_compact_prometheuscompactor_shouldcompact" }, @@ -16094,7 +16859,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L213", - "community": 589, + "community": 80, "norm_label": ".getcompactablechunk()", "id": "prometheus_compact_prometheuscompactor_getcompactablechunk" }, @@ -16112,7 +16877,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L244", - "community": 589, + "community": 80, "norm_label": ".consolidate()", "id": "prometheus_compact_prometheuscompactor_consolidate" }, @@ -16121,7 +16886,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L271", - "community": 589, + "community": 80, "norm_label": ".compact()", "id": "prometheus_compact_prometheuscompactor_compact" }, @@ -16130,7 +16895,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L310", - "community": 589, + "community": 80, "norm_label": ".getepisodes()", "id": "prometheus_compact_prometheuscompactor_getepisodes" }, @@ -16283,7 +17048,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L97", - "community": 222, + "community": 53, "norm_label": "getclient()", "id": "prometheus_memory_getclient" }, @@ -16301,7 +17066,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L113", - "community": 222, + "community": 53, "norm_label": "normalizekey()", "id": "prometheus_memory_normalizekey" }, @@ -16310,7 +17075,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L120", - "community": 222, + "community": 53, "norm_label": "findsimilarkey()", "id": "prometheus_memory_findsimilarkey" }, @@ -16346,7 +17111,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L179", - "community": 222, + "community": 53, "norm_label": "sumtokens()", "id": "prometheus_memory_sumtokens" }, @@ -16364,7 +17129,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L196", - "community": 222, + "community": 53, "norm_label": "getmemorylimit()", "id": "prometheus_memory_getmemorylimit" }, @@ -16373,7 +17138,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L202", - "community": 222, + "community": 53, "norm_label": "countmemories()", "id": "prometheus_memory_countmemories" }, @@ -16382,7 +17147,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L211", - "community": 222, + "community": 53, "norm_label": "touch()", "id": "prometheus_memory_touch" }, @@ -16391,7 +17156,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L222", - "community": 222, + "community": 53, "norm_label": "upsertmemory()", "id": "prometheus_memory_upsertmemory" }, @@ -16436,7 +17201,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L450", - "community": 222, + "community": 53, "norm_label": "extract()", "id": "prometheus_memory_extract" }, @@ -16715,7 +17480,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L1", - "community": 576, + "community": 525, "norm_label": "tools.py", "id": "main_app_prometheus_tools_py" }, @@ -16733,7 +17498,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L51", - "community": 503, + "community": 136, "norm_label": "save_memory()", "id": "prometheus_tools_save_memory" }, @@ -16751,7 +17516,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L114", - "community": 588, + "community": 221, "norm_label": "read_file()", "id": "prometheus_tools_read_file" }, @@ -16805,7 +17570,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L52", - "community": 503, + "community": 136, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_52" }, @@ -16823,7 +17588,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L115", - "community": 588, + "community": 221, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_115" }, @@ -16904,7 +17669,7 @@ "file_type": "code", "source_file": "main/app/prometheus/vector.py", "source_location": "L51", - "community": 222, + "community": 53, "norm_label": "contenthash()", "id": "prometheus_vector_contenthash" }, @@ -17030,7 +17795,7 @@ "file_type": "code", "source_file": "main/controller/prometheus_controller.py", "source_location": "L179", - "community": 84, + "community": 69, "norm_label": "downloadworkspacefile()", "id": "controller_prometheus_controller_downloadworkspacefile" }, @@ -17057,7 +17822,7 @@ "file_type": "code", "source_file": "main/models/prometheus.py", "source_location": "L1", - "community": 125, + "community": 566, "norm_label": "prometheus.py", "id": "main_models_prometheus_py" }, @@ -17066,7 +17831,7 @@ "file_type": "code", "source_file": "main/models/prometheus.py", "source_location": "L7", - "community": 125, + "community": 566, "norm_label": "prometheussession", "id": "models_prometheus_prometheussession" }, @@ -17084,7 +17849,7 @@ "file_type": "code", "source_file": "main/service/prometheus_service.py", "source_location": "L1", - "community": 536, + "community": 222, "norm_label": "prometheus_service.py", "id": "main_service_prometheus_service_py" }, @@ -17093,7 +17858,7 @@ "file_type": "code", "source_file": "main/service/prometheus_service.py", "source_location": "L23", - "community": 95, + "community": 574, "norm_label": "memorymaintenance()", "id": "service_prometheus_service_memorymaintenance" }, @@ -17111,7 +17876,7 @@ "file_type": "code", "source_file": "main/service/prometheus_service.py", "source_location": "L67", - "community": 536, + "community": 222, "norm_label": "initialize()", "id": "service_prometheus_service_initialize" }, @@ -17696,7 +18461,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L54", - "community": 63, + "community": 517, "norm_label": "stocksquerymanager", "id": "stocks_api_query_stocksquerymanager" }, @@ -17705,7 +18470,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L55", - "community": 63, + "community": 517, "norm_label": ".__init__()", "id": "stocks_api_query_stocksquerymanager_init" }, @@ -17714,7 +18479,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L58", - "community": 63, + "community": 517, "norm_label": ".baseframe()", "id": "stocks_api_query_stocksquerymanager_baseframe" }, @@ -17723,7 +18488,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L69", - "community": 63, + "community": 517, "norm_label": ".finalize()", "id": "stocks_api_query_stocksquerymanager_finalize" }, @@ -17732,7 +18497,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L109", - "community": 63, + "community": 517, "norm_label": ".deserializejsoncolumns()", "id": "stocks_api_query_stocksquerymanager_deserializejsoncolumns" }, @@ -17741,7 +18506,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L136", - "community": 63, + "community": 517, "norm_label": ".filterbysearchterms()", "id": "stocks_api_query_stocksquerymanager_filterbysearchterms" }, @@ -17750,7 +18515,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L153", - "community": 63, + "community": 517, "norm_label": ".queryhistorical()", "id": "stocks_api_query_stocksquerymanager_queryhistorical" }, @@ -17759,7 +18524,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L220", - "community": 63, + "community": 517, "norm_label": ".queryfundamental()", "id": "stocks_api_query_stocksquerymanager_queryfundamental" }, @@ -17768,7 +18533,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L284", - "community": 63, + "community": 517, "norm_label": ".querycotations()", "id": "stocks_api_query_stocksquerymanager_querycotations" }, @@ -17777,7 +18542,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L331", - "community": 63, + "community": 517, "norm_label": ".querylivecotation()", "id": "stocks_api_query_stocksquerymanager_querylivecotation" }, @@ -17831,7 +18596,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L450", - "community": 222, + "community": 53, "norm_label": "counttokenscached()", "id": "prometheus_memory_counttokenscached" }, @@ -17840,7 +18605,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/sync_cache.py", "source_location": "L13", - "community": 562, + "community": 615, "norm_label": "sync_cache()", "id": "stocks_api_sync_cache_sync_cache" }, @@ -17894,7 +18659,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L244", - "community": 222, + "community": 53, "norm_label": "upsertmemoryasync()", "id": "prometheus_memory_upsertmemoryasync" }, @@ -17930,7 +18695,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L50", - "community": 503, + "community": 136, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_50" }, @@ -17948,7 +18713,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L112", - "community": 588, + "community": 221, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_112" }, @@ -17966,7 +18731,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L142", - "community": 576, + "community": 525, "norm_label": "list files in the workspace directory. args: path: directory pat", "id": "prometheus_tools_rationale_142" }, @@ -18020,7 +18785,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L49", - "community": 503, + "community": 136, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_49" }, @@ -18038,7 +18803,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L111", - "community": 588, + "community": 221, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_111" }, @@ -18083,7 +18848,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L23", - "community": 560, + "community": 186, "norm_label": "jsonbytesresponse", "id": "controller_stocksapi_controller_jsonbytesresponse" }, @@ -18092,7 +18857,7 @@ "file_type": "code", "source_file": "", "source_location": "", - "community": 560, + "community": 186, "norm_label": "fastapiresponse", "id": "fastapiresponse" }, @@ -18101,7 +18866,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L26", - "community": 560, + "community": 186, "norm_label": ".render()", "id": "controller_stocksapi_controller_jsonbytesresponse_render" }, @@ -18893,7 +19658,7 @@ "file_type": "rationale", "source_file": "main/service/scraper_service.py", "source_location": "L23", - "community": 474, + "community": 604, "norm_label": "p5: register the scraper cron jobs on the shared scheduler. kept in this", "id": "service_scraper_service_rationale_23" }, @@ -18902,7 +19667,7 @@ "file_type": "code", "source_file": "main/service/user_service.py", "source_location": "L46", - "community": 536, + "community": 628, "norm_label": "registersessioncleanupjobs()", "id": "service_user_service_registersessioncleanupjobs" }, @@ -18911,7 +19676,7 @@ "file_type": "rationale", "source_file": "main/service/user_service.py", "source_location": "L47", - "community": 536, + "community": 628, "norm_label": "p5: register the session-cleanup job on the shared scheduler. kept in thi", "id": "service_user_service_rationale_47" }, @@ -20045,7 +20810,7 @@ "file_type": "code", "source_file": "main/service/prometheus_service.py", "source_location": "L60", - "community": 536, + "community": 222, "norm_label": "registermemorymaintenancejob()", "id": "service_prometheus_service_registermemorymaintenancejob" }, @@ -20054,7 +20819,7 @@ "file_type": "rationale", "source_file": "main/service/prometheus_service.py", "source_location": "L61", - "community": 536, + "community": 222, "norm_label": "p5: register memory maintenance on the shared scheduler. kept in this ser", "id": "service_prometheus_service_rationale_61" }, @@ -20063,7 +20828,7 @@ "file_type": "rationale", "source_file": "main/utils/scheduler.py", "source_location": "L1", - "community": 536, + "community": 222, "norm_label": "p5: single shared backgroundscheduler for all services. replaces the 4 per-serv", "id": "utils_scheduler_rationale_1" }, @@ -20072,7 +20837,7 @@ "file_type": "rationale", "source_file": "main/utils/scheduler.py", "source_location": "L33", - "community": 536, + "community": 222, "norm_label": "return the process-wide scheduler, starting it on first use.", "id": "utils_scheduler_rationale_33" }, @@ -20081,7 +20846,7 @@ "file_type": "rationale", "source_file": "main/utils/scheduler.py", "source_location": "L43", - "community": 536, + "community": 222, "norm_label": "register func on the shared scheduler (replaces any same-id job). trigger i", "id": "utils_scheduler_rationale_43" }, @@ -20090,7 +20855,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L36", - "community": 194, + "community": 186, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_36" }, @@ -20135,7 +20900,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L40", - "community": 194, + "community": 186, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_40" }, @@ -20216,7 +20981,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L89", - "community": 574, + "community": 538, "norm_label": "fieldregistry", "id": "prometheus_compact_fieldregistry" }, @@ -20225,7 +20990,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L94", - "community": 574, + "community": 538, "norm_label": ".buildurl()", "id": "prometheus_compact_fieldregistry_buildurl" }, @@ -20234,7 +20999,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L99", - "community": 574, + "community": 538, "norm_label": ".fetchfields()", "id": "prometheus_compact_fieldregistry_fetchfields" }, @@ -20243,7 +21008,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L120", - "community": 574, + "community": 538, "norm_label": ".getfields()", "id": "prometheus_compact_fieldregistry_getfields" }, @@ -20252,7 +21017,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L127", - "community": 574, + "community": 538, "norm_label": ".buildmetricregex()", "id": "prometheus_compact_fieldregistry_buildmetricregex" }, @@ -20261,7 +21026,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L134", - "community": 574, + "community": 538, "norm_label": ".getmetricregex()", "id": "prometheus_compact_fieldregistry_getmetricregex" }, @@ -20270,7 +21035,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L222", - "community": 589, + "community": 538, "norm_label": ".__init__()", "id": "prometheus_compact_prometheuscompactor_init" }, @@ -20297,7 +21062,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L54", - "community": 503, + "community": 136, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_54" }, @@ -20315,7 +21080,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L113", - "community": 588, + "community": 221, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_113" }, @@ -20351,7 +21116,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L110", - "community": 63, + "community": 517, "norm_label": "._executequery()", "id": "stocks_api_query_stocksquerymanager_executequery" }, @@ -20360,7 +21125,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/query.py", "source_location": "L123", - "community": 63, + "community": 517, "norm_label": "shared query pipeline for historical and fundamental endpoints.", "id": "stocks_api_query_rationale_123" }, @@ -20369,7 +21134,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L48", - "community": 194, + "community": 186, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_48" }, @@ -20576,7 +21341,7 @@ "file_type": "code", "source_file": "main/app/prometheus/agent.py", "source_location": "L58", - "community": 116, + "community": 93, "norm_label": "_get_client()", "id": "prometheus_agent_get_client" }, @@ -20585,7 +21350,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/agent.py", "source_location": "L59", - "community": 116, + "community": 93, "norm_label": "lazy module-level singleton so the genai client is created once, not per request", "id": "prometheus_agent_rationale_59" }, @@ -20774,7 +21539,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L139", - "community": 574, + "community": 538, "norm_label": ".invalidate()", "id": "prometheus_compact_fieldregistry_invalidate" }, @@ -20783,7 +21548,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L145", - "community": 574, + "community": 538, "norm_label": ".warmup()", "id": "prometheus_compact_fieldregistry_warmup" }, @@ -20792,7 +21557,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L153", - "community": 222, + "community": 80, "norm_label": "charcount()", "id": "prometheus_compact_charcount" }, @@ -20864,7 +21629,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L24", - "community": 560, + "community": 186, "norm_label": "sends pre-serialized json bytes without re-encoding (cache-friendly).", "id": "controller_stocksapi_controller_rationale_24" }, @@ -20873,7 +21638,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L49", - "community": 194, + "community": 186, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_49" }, @@ -20918,7 +21683,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L1", - "community": 603, + "community": 523, "norm_label": "response_cache.py", "id": "main_app_stocks_api_response_cache_py" }, @@ -20927,7 +21692,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L19", - "community": 603, + "community": 523, "norm_label": "responsecache", "id": "stocks_api_response_cache_responsecache" }, @@ -20936,7 +21701,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L20", - "community": 603, + "community": 523, "norm_label": ".__init__()", "id": "stocks_api_response_cache_responsecache_init" }, @@ -20945,7 +21710,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L29", - "community": 603, + "community": 523, "norm_label": ".makekey()", "id": "stocks_api_response_cache_responsecache_makekey" }, @@ -20954,7 +21719,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L34", - "community": 603, + "community": 523, "norm_label": ".get()", "id": "stocks_api_response_cache_responsecache_get" }, @@ -20963,7 +21728,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L51", - "community": 63, + "community": 523, "norm_label": ".set()", "id": "stocks_api_response_cache_responsecache_set" }, @@ -21008,7 +21773,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L323", - "community": 560, + "community": 186, "norm_label": "generatekey()", "id": "controller_stocksapi_controller_generatekey" }, @@ -21017,7 +21782,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L30", - "community": 194, + "community": 186, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_30" }, @@ -21746,7 +22511,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L94", - "community": 574, + "community": 538, "norm_label": ".__new__()", "id": "prometheus_compact_fieldregistry_new" }, @@ -22781,7 +23546,7 @@ "file_type": "code", "source_file": "main/app/prometheus/state.py", "source_location": "L14", - "community": 502, + "community": 523, "norm_label": ".set()", "id": "prometheus_state_harnessstate_set" }, @@ -22835,7 +23600,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L89", - "community": 521, + "community": 503, "norm_label": "get_state()", "id": "prometheus_tools_get_state" }, @@ -23060,7 +23825,7 @@ "file_type": "code", "source_file": "main/utils/connectivity.py", "source_location": "L13", - "community": 72, + "community": 572, "norm_label": "checksingledb()", "id": "utils_connectivity_checksingledb" }, @@ -23168,7 +23933,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L27", - "community": 194, + "community": 186, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_27" }, @@ -23330,7 +24095,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L48", - "community": 222, + "community": 53, "norm_label": "applyupdate()", "id": "prometheus_memory_applyupdate" }, @@ -24248,7 +25013,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L44", - "community": 503, + "community": 136, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_44" }, @@ -24257,7 +25022,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L81", - "community": 521, + "community": 503, "norm_label": "retrieve values from the harness state. use this to recall intermediate results,", "id": "prometheus_tools_rationale_81" }, @@ -24995,7 +25760,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L26", - "community": 194, + "community": 186, "norm_label": "discover available field names before querying /historical or /fundamental.", "id": "controller_stocksapi_controller_rationale_26" }, @@ -30683,7 +31448,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L7", - "community": 511, + "community": 8, "norm_label": "testbuildsystempromptstate", "id": "tests_test_agent_state_integration_testbuildsystempromptstate" }, @@ -30692,7 +31457,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L8", - "community": 511, + "community": 8, "norm_label": ".test_build_system_prompt_no_state()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_no_state" }, @@ -30701,7 +31466,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L13", - "community": 511, + "community": 8, "norm_label": ".test_build_system_prompt_with_state()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_with_state" }, @@ -30710,7 +31475,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L21", - "community": 511, + "community": 8, "norm_label": ".test_build_system_prompt_empty_state()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_empty_state" }, @@ -30719,7 +31484,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L27", - "community": 511, + "community": 8, "norm_label": ".test_build_system_prompt_state_after_memories()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_state_after_memories" }, @@ -30728,7 +31493,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L37", - "community": 511, + "community": 8, "norm_label": ".test_build_system_prompt_multiple_state_entries()", "id": "tests_test_agent_state_integration_testbuildsystempromptstate_test_build_system_prompt_multiple_state_entries" }, @@ -30800,7 +31565,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L195", - "community": 93, + "community": 617, "norm_label": ".test_system_prompt_has_memory_sync_section()", "id": "tests_test_agent_state_integration_testsystempromptstateinstructions_test_system_prompt_has_memory_sync_section" }, @@ -30809,7 +31574,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L9", - "community": 511, + "community": 8, "norm_label": "system prompt should work without state parameter.", "id": "tests_test_agent_state_integration_rationale_9" }, @@ -30818,7 +31583,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L14", - "community": 511, + "community": 8, "norm_label": "system prompt should include state context when provided.", "id": "tests_test_agent_state_integration_rationale_14" }, @@ -30827,7 +31592,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L22", - "community": 511, + "community": 8, "norm_label": "system prompt should not include state section when empty.", "id": "tests_test_agent_state_integration_rationale_22" }, @@ -30836,7 +31601,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L28", - "community": 511, + "community": 8, "norm_label": "state section should appear after memories section.", "id": "tests_test_agent_state_integration_rationale_28" }, @@ -30845,7 +31610,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L38", - "community": 511, + "community": 8, "norm_label": "all state entries should appear in the prompt.", "id": "tests_test_agent_state_integration_rationale_38" }, @@ -30890,7 +31655,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L196", - "community": 93, + "community": 617, "norm_label": "system prompt should instruct llm about memory vs state.", "id": "tests_test_agent_state_integration_rationale_196" }, @@ -30962,7 +31727,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L150", - "community": 26, + "community": 589, "norm_label": ".test_invalid_api_key_returns_zero_rows()", "id": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_invalid_api_key_returns_zero_rows" }, @@ -30971,7 +31736,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L164", - "community": 26, + "community": 589, "norm_label": ".test_multiple_keys_independent_quotas()", "id": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_multiple_keys_independent_quotas" }, @@ -31106,7 +31871,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L151", - "community": 26, + "community": 589, "norm_label": "test that invalid api key returns zero rows affected.", "id": "tests_test_api_key_quota_atomic_rationale_151" }, @@ -31115,7 +31880,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L165", - "community": 26, + "community": 589, "norm_label": "test that multiple api keys have independent quotas.", "id": "tests_test_api_key_quota_atomic_rationale_165" }, @@ -31187,7 +31952,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L1", - "community": 538, + "community": 107, "norm_label": "test_auth_util.py", "id": "tests_test_auth_util_py" }, @@ -31286,7 +32051,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L69", - "community": 538, + "community": 107, "norm_label": "testsessionexpiryconfig", "id": "tests_test_auth_util_testsessionexpiryconfig" }, @@ -31295,7 +32060,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L70", - "community": 538, + "community": 107, "norm_label": ".test_session_expiry_days_is_30()", "id": "tests_test_auth_util_testsessionexpiryconfig_test_session_expiry_days_is_30" }, @@ -31304,7 +32069,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L73", - "community": 538, + "community": 107, "norm_label": ".test_session_expiry_hours_calculation()", "id": "tests_test_auth_util_testsessionexpiryconfig_test_session_expiry_hours_calculation" }, @@ -31313,7 +32078,7 @@ "file_type": "code", "source_file": "tests/test_auth_util.py", "source_location": "L78", - "community": 538, + "community": 107, "norm_label": ".test_default_token_expiry_equals_30_days()", "id": "tests_test_auth_util_testsessionexpiryconfig_test_default_token_expiry_equals_30_days" }, @@ -31439,7 +32204,7 @@ "file_type": "code", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L8", - "community": 621, + "community": 629, "norm_label": "testcheckmysqlconnection", "id": "tests_test_connectivity_coverage_testcheckmysqlconnection" }, @@ -31529,7 +32294,7 @@ "file_type": "code", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L114", - "community": 618, + "community": 625, "norm_label": "testcheckserviceconnection", "id": "tests_test_connectivity_coverage_testcheckserviceconnection" }, @@ -31619,7 +32384,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L9", - "community": 621, + "community": 629, "norm_label": "checkmysqlconnection \u2014 success, errors, engine=none paths.", "id": "tests_test_connectivity_coverage_rationale_9" }, @@ -31628,7 +32393,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L115", - "community": 618, + "community": 625, "norm_label": "checkserviceconnection \u2014 success, not found, errors.", "id": "tests_test_connectivity_coverage_rationale_115" }, @@ -31781,7 +32546,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L215", - "community": 120, + "community": 45, "norm_label": "testloginendpoint", "id": "tests_test_controllers_coverage_testloginendpoint" }, @@ -32078,7 +32843,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L668", - "community": 107, + "community": 63, "norm_label": "testgetcurrentsession", "id": "tests_test_controllers_coverage_testgetcurrentsession" }, @@ -32087,7 +32852,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L671", - "community": 107, + "community": 63, "norm_label": ".test_get_current_session_found()", "id": "tests_test_controllers_coverage_testgetcurrentsession_test_get_current_session_found" }, @@ -32096,7 +32861,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L704", - "community": 107, + "community": 63, "norm_label": ".test_get_current_session_not_found()", "id": "tests_test_controllers_coverage_testgetcurrentsession_test_get_current_session_not_found" }, @@ -32159,7 +32924,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L835", - "community": 626, + "community": 45, "norm_label": "testprometheushealth", "id": "tests_test_controllers_coverage_testprometheushealth" }, @@ -32168,7 +32933,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L838", - "community": 626, + "community": 45, "norm_label": ".test_health()", "id": "tests_test_controllers_coverage_testprometheushealth_test_health" }, @@ -32330,7 +33095,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1085", - "community": 498, + "community": 148, "norm_label": ".test_chat_existing_session_not_owner()", "id": "tests_test_controllers_coverage_testprometheuschat_test_chat_existing_session_not_owner" }, @@ -32339,7 +33104,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1121", - "community": 148, + "community": 99, "norm_label": ".test_chat_generic_exception()", "id": "tests_test_controllers_coverage_testprometheuschat_test_chat_generic_exception" }, @@ -32348,7 +33113,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1144", - "community": 604, + "community": 45, "norm_label": "teststocksapihealth", "id": "tests_test_controllers_coverage_teststocksapihealth" }, @@ -32357,7 +33122,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1147", - "community": 604, + "community": 45, "norm_label": ".test_health()", "id": "tests_test_controllers_coverage_teststocksapihealth_test_health" }, @@ -32384,7 +33149,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1172", - "community": 605, + "community": 14, "norm_label": "teststocksapifundamental", "id": "tests_test_controllers_coverage_teststocksapifundamental" }, @@ -32393,7 +33158,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1175", - "community": 605, + "community": 14, "norm_label": ".test_get_fundamental()", "id": "tests_test_controllers_coverage_teststocksapifundamental_test_get_fundamental" }, @@ -32438,7 +33203,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1229", - "community": 620, + "community": 529, "norm_label": "testaddroletouser", "id": "tests_test_controllers_coverage_testaddroletouser" }, @@ -32447,7 +33212,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1232", - "community": 623, + "community": 529, "norm_label": ".test_add_role_success()", "id": "tests_test_controllers_coverage_testaddroletouser_test_add_role_success" }, @@ -32456,7 +33221,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1249", - "community": 625, + "community": 529, "norm_label": ".test_add_role_already_has_role()", "id": "tests_test_controllers_coverage_testaddroletouser_test_add_role_already_has_role" }, @@ -32501,7 +33266,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1307", - "community": 568, + "community": 529, "norm_label": ".test_get_current_user_session_revoked()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_session_revoked" }, @@ -32510,7 +33275,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1323", - "community": 609, + "community": 563, "norm_label": ".test_get_current_user_not_found()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_not_found" }, @@ -32519,7 +33284,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1340", - "community": 614, + "community": 563, "norm_label": ".test_get_current_user_generic_exception()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_generic_exception" }, @@ -32528,7 +33293,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1357", - "community": 617, + "community": 563, "norm_label": ".test_get_current_user_no_session_id()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_no_session_id" }, @@ -32537,7 +33302,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1381", - "community": 45, + "community": 194, "norm_label": "testhashpasswordempty", "id": "tests_test_controllers_coverage_testhashpasswordempty" }, @@ -32546,7 +33311,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1384", - "community": 45, + "community": 43, "norm_label": ".test_empty_password_raises()", "id": "tests_test_controllers_coverage_testhashpasswordempty_test_empty_password_raises" }, @@ -32555,7 +33320,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1391", - "community": 546, + "community": 194, "norm_label": "testverifyaccesstoken", "id": "tests_test_controllers_coverage_testverifyaccesstoken" }, @@ -32564,7 +33329,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1394", - "community": 546, + "community": 194, "norm_label": ".test_expired_token()", "id": "tests_test_controllers_coverage_testverifyaccesstoken_test_expired_token" }, @@ -32573,7 +33338,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1410", - "community": 592, + "community": 194, "norm_label": ".test_invalid_token()", "id": "tests_test_controllers_coverage_testverifyaccesstoken_test_invalid_token" }, @@ -32726,7 +33491,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L216", - "community": 120, + "community": 45, "norm_label": "covers lines 87-93, 102: login success and failure paths.", "id": "tests_test_controllers_coverage_rationale_216" }, @@ -32951,7 +33716,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L669", - "community": 107, + "community": 63, "norm_label": "covers lines 100-104, 106: get /user/sessions/current.", "id": "tests_test_controllers_coverage_rationale_669" }, @@ -32960,7 +33725,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L672", - "community": 107, + "community": 63, "norm_label": "covers lines 100-104, 106: session found.", "id": "tests_test_controllers_coverage_rationale_672" }, @@ -32969,7 +33734,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L705", - "community": 107, + "community": 63, "norm_label": "covers line 104: session not found.", "id": "tests_test_controllers_coverage_rationale_705" }, @@ -33032,7 +33797,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L836", - "community": 626, + "community": 45, "norm_label": "covers line 24: get /prometheus/health.", "id": "tests_test_controllers_coverage_rationale_836" }, @@ -33176,7 +33941,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1086", - "community": 498, + "community": 148, "norm_label": "covers lines 120-121: session ownership check fails.", "id": "tests_test_controllers_coverage_rationale_1086" }, @@ -33185,7 +33950,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1122", - "community": 148, + "community": 99, "norm_label": "generic exception in chat propagates via sse error event.", "id": "tests_test_controllers_coverage_rationale_1122" }, @@ -33194,7 +33959,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1145", - "community": 604, + "community": 45, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1145" }, @@ -33212,7 +33977,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1173", - "community": 605, + "community": 14, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1173" }, @@ -33257,7 +34022,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1230", - "community": 620, + "community": 529, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1230" }, @@ -33266,7 +34031,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1233", - "community": 623, + "community": 529, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1233" }, @@ -33275,7 +34040,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1250", - "community": 625, + "community": 529, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1250" }, @@ -33311,7 +34076,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1308", - "community": 568, + "community": 529, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1308" }, @@ -33320,7 +34085,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1324", - "community": 609, + "community": 563, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1324" }, @@ -33329,7 +34094,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1341", - "community": 614, + "community": 563, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1341" }, @@ -33338,7 +34103,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1358", - "community": 617, + "community": 563, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1358" }, @@ -33347,7 +34112,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1382", - "community": 546, + "community": 194, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1382" }, @@ -33356,7 +34121,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1392", - "community": 546, + "community": 194, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1392" }, @@ -33365,7 +34130,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1395", - "community": 546, + "community": 194, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1395" }, @@ -33374,7 +34139,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1411", - "community": 592, + "community": 194, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1411" }, @@ -33977,7 +34742,7 @@ "file_type": "code", "source_file": "tests/test_error_handlers.py", "source_location": "L25", - "community": 498, + "community": 33, "norm_label": "app()", "id": "tests_test_error_handlers_app" }, @@ -34265,7 +35030,7 @@ "file_type": "code", "source_file": "tests/test_harness_state.py", "source_location": "L1", - "community": 8, + "community": 577, "norm_label": "test_harness_state.py", "id": "tests_test_harness_state_py" }, @@ -34373,7 +35138,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L1", - "community": 610, + "community": 590, "norm_label": "test_http_session_coverage.py", "id": "tests_test_http_session_coverage_py" }, @@ -34382,7 +35147,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L8", - "community": 610, + "community": 590, "norm_label": "testgetsession", "id": "tests_test_http_session_coverage_testgetsession" }, @@ -34391,7 +35156,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L9", - "community": 610, + "community": 590, "norm_label": ".test_returns_same_session()", "id": "tests_test_http_session_coverage_testgetsession_test_returns_same_session" }, @@ -34400,7 +35165,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L16", - "community": 610, + "community": 590, "norm_label": ".test_returns_requests_session()", "id": "tests_test_http_session_coverage_testgetsession_test_returns_requests_session" }, @@ -34409,7 +35174,7 @@ "file_type": "rationale", "source_file": "tests/test_http_session_coverage.py", "source_location": "L1", - "community": 610, + "community": 590, "norm_label": "tests for main/utils/http_session.py \u2014 covers all branches.", "id": "tests_test_http_session_coverage_rationale_1" }, @@ -34427,7 +35192,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L14", - "community": 25, + "community": 587, "norm_label": "testregistervalidation", "id": "tests_test_input_validation_testregistervalidation" }, @@ -34436,7 +35201,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L17", - "community": 25, + "community": 587, "norm_label": ".test_valid_registration()", "id": "tests_test_input_validation_testregistervalidation_test_valid_registration" }, @@ -34445,7 +35210,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L25", - "community": 25, + "community": 587, "norm_label": ".test_username_too_short()", "id": "tests_test_input_validation_testregistervalidation_test_username_too_short" }, @@ -34454,7 +35219,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L32", - "community": 25, + "community": 587, "norm_label": ".test_username_too_long()", "id": "tests_test_input_validation_testregistervalidation_test_username_too_long" }, @@ -34463,7 +35228,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L39", - "community": 25, + "community": 587, "norm_label": ".test_email_too_short()", "id": "tests_test_input_validation_testregistervalidation_test_email_too_short" }, @@ -34472,7 +35237,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L46", - "community": 25, + "community": 587, "norm_label": ".test_password_too_short()", "id": "tests_test_input_validation_testregistervalidation_test_password_too_short" }, @@ -34481,7 +35246,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L54", - "community": 25, + "community": 620, "norm_label": "testloginvalidation", "id": "tests_test_input_validation_testloginvalidation" }, @@ -34490,7 +35255,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L57", - "community": 25, + "community": 620, "norm_label": ".test_valid_login_payload()", "id": "tests_test_input_validation_testloginvalidation_test_valid_login_payload" }, @@ -34499,7 +35264,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L65", - "community": 25, + "community": 620, "norm_label": ".test_username_too_short()", "id": "tests_test_input_validation_testloginvalidation_test_username_too_short" }, @@ -34508,7 +35273,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L72", - "community": 25, + "community": 620, "norm_label": ".test_password_too_short()", "id": "tests_test_input_validation_testloginvalidation_test_password_too_short" }, @@ -34661,7 +35426,7 @@ "file_type": "rationale", "source_file": "tests/test_input_validation.py", "source_location": "L15", - "community": 25, + "community": 587, "norm_label": "post /auth/register \u2014 validates username, email, password via body(...)", "id": "tests_test_input_validation_rationale_15" }, @@ -34670,7 +35435,7 @@ "file_type": "rationale", "source_file": "tests/test_input_validation.py", "source_location": "L55", - "community": 25, + "community": 620, "norm_label": "post /auth/login \u2014 validates username, password via body(...)", "id": "tests_test_input_validation_rationale_55" }, @@ -34814,7 +35579,7 @@ "file_type": "code", "source_file": "tests/test_logging_config_coverage.py", "source_location": "L103", - "community": 599, + "community": 122, "norm_label": "testsetuplogging", "id": "tests_test_logging_config_coverage_testsetuplogging" }, @@ -34859,7 +35624,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L8", - "community": 231, + "community": 521, "norm_label": "_create_memory()", "id": "tests_test_memory_dedup_create_memory" }, @@ -34868,7 +35633,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L12", - "community": 231, + "community": 521, "norm_label": "_count_memories()", "id": "tests_test_memory_dedup_count_memories" }, @@ -34877,7 +35642,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L20", - "community": 231, + "community": 521, "norm_label": "_get_memory()", "id": "tests_test_memory_dedup_get_memory" }, @@ -34895,7 +35660,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L29", - "community": 231, + "community": 521, "norm_label": ".test_exact_same_key_updates()", "id": "tests_test_memory_dedup_testexactsamekeyupdates_test_exact_same_key_updates" }, @@ -34913,7 +35678,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L37", - "community": 231, + "community": 521, "norm_label": ".test_similar_key_merges()", "id": "tests_test_memory_dedup_testsimilarkeymerges_test_similar_key_merges" }, @@ -34931,7 +35696,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L47", - "community": 231, + "community": 521, "norm_label": ".test_different_keys_no_merge()", "id": "tests_test_memory_dedup_testdifferentkeysnomerge_test_different_keys_no_merge" }, @@ -34949,7 +35714,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L56", - "community": 231, + "community": 521, "norm_label": ".test_merge_boosts_score()", "id": "tests_test_memory_dedup_testmergeboostsscore_test_merge_boosts_score" }, @@ -34967,7 +35732,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L65", - "community": 231, + "community": 521, "norm_label": ".test_merge_increments_access()", "id": "tests_test_memory_dedup_testmergeincrementsaccess_test_merge_increments_access" }, @@ -34985,7 +35750,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L74", - "community": 231, + "community": 521, "norm_label": ".test_threshold_boundary()", "id": "tests_test_memory_dedup_testthresholdboundary_test_threshold_boundary" }, @@ -34994,7 +35759,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L38", - "community": 231, + "community": 521, "norm_label": "keys with jaccard > 0.8 should merge.", "id": "tests_test_memory_dedup_rationale_38" }, @@ -35003,7 +35768,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L48", - "community": 231, + "community": 521, "norm_label": "keys with low similarity should not merge.", "id": "tests_test_memory_dedup_rationale_48" }, @@ -35012,7 +35777,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L75", - "community": 231, + "community": 521, "norm_label": "keys with jaccard <= 0.8 should not merge.", "id": "tests_test_memory_dedup_rationale_75" }, @@ -35048,7 +35813,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L46", - "community": 95, + "community": 518, "norm_label": "testdecay", "id": "tests_test_memory_maintenance_testdecay" }, @@ -35057,7 +35822,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L47", - "community": 95, + "community": 518, "norm_label": ".test_active_memory_decays()", "id": "tests_test_memory_maintenance_testdecay_test_active_memory_decays" }, @@ -35066,7 +35831,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L54", - "community": 95, + "community": 518, "norm_label": ".test_zero_access_count_still_decays()", "id": "tests_test_memory_maintenance_testdecay_test_zero_access_count_still_decays" }, @@ -35075,7 +35840,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L61", - "community": 95, + "community": 518, "norm_label": ".test_high_score_decays_proportionally()", "id": "tests_test_memory_maintenance_testdecay_test_high_score_decays_proportionally" }, @@ -35084,7 +35849,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L67", - "community": 95, + "community": 518, "norm_label": ".test_very_low_score_stays_above_zero()", "id": "tests_test_memory_maintenance_testdecay_test_very_low_score_stays_above_zero" }, @@ -35093,7 +35858,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L74", - "community": 95, + "community": 518, "norm_label": ".test_multiple_users_all_decayed()", "id": "tests_test_memory_maintenance_testdecay_test_multiple_users_all_decayed" }, @@ -35102,7 +35867,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L84", - "community": 518, + "community": 574, "norm_label": "testarchive", "id": "tests_test_memory_maintenance_testarchive" }, @@ -35111,7 +35876,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L85", - "community": 518, + "community": 574, "norm_label": ".test_dead_memory_archived()", "id": "tests_test_memory_maintenance_testarchive_test_dead_memory_archived" }, @@ -35120,7 +35885,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L92", - "community": 518, + "community": 574, "norm_label": ".test_low_score_but_recent_not_archived()", "id": "tests_test_memory_maintenance_testarchive_test_low_score_but_recent_not_archived" }, @@ -35129,7 +35894,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L99", - "community": 518, + "community": 574, "norm_label": ".test_zero_access_but_high_score_not_archived()", "id": "tests_test_memory_maintenance_testarchive_test_zero_access_but_high_score_not_archived" }, @@ -35138,7 +35903,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L106", - "community": 518, + "community": 574, "norm_label": ".test_accessed_memory_not_archived()", "id": "tests_test_memory_maintenance_testarchive_test_accessed_memory_not_archived" }, @@ -35147,7 +35912,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L113", - "community": 518, + "community": 574, "norm_label": ".test_already_archived_not_double_archived()", "id": "tests_test_memory_maintenance_testarchive_test_already_archived_not_double_archived" }, @@ -35156,7 +35921,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L123", - "community": 518, + "community": 574, "norm_label": ".test_multiple_users_independent_archive()", "id": "tests_test_memory_maintenance_testarchive_test_multiple_users_independent_archive" }, @@ -35228,7 +35993,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L171", - "community": 95, + "community": 574, "norm_label": ".test_no_memories_does_not_crash()", "id": "tests_test_memory_maintenance_testemptydatabase_test_no_memories_does_not_crash" }, @@ -35246,7 +36011,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L55", - "community": 95, + "community": 518, "norm_label": "decay applies to all active memories, not just accessed ones.", "id": "tests_test_memory_maintenance_rationale_55" }, @@ -35255,7 +36020,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L68", - "community": 95, + "community": 518, "norm_label": "basescore should never reach exactly 0 from decay alone.", "id": "tests_test_memory_maintenance_rationale_68" }, @@ -35264,7 +36029,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L86", - "community": 518, + "community": 574, "norm_label": "score below threshold + accesscount=0 + 90+ days \u2192 archived.", "id": "tests_test_memory_maintenance_rationale_86" }, @@ -35273,7 +36038,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L93", - "community": 518, + "community": 574, "norm_label": "low score but accessed recently \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_93" }, @@ -35282,7 +36047,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L100", - "community": 518, + "community": 574, "norm_label": "zero access but score still above threshold \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_100" }, @@ -35291,7 +36056,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L107", - "community": 518, + "community": 574, "norm_label": "even with low score, if accessed \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_107" }, @@ -35300,7 +36065,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L114", - "community": 518, + "community": 574, "norm_label": "already archived memories are skipped.", "id": "tests_test_memory_maintenance_rationale_114" }, @@ -35372,7 +36137,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L15", - "community": 140, + "community": 627, "norm_label": ".test_admin_user()", "id": "tests_test_memory_manager_testgetmemorylimit_test_admin_user" }, @@ -35390,7 +36155,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L20", - "community": 140, + "community": 632, "norm_label": ".test_create()", "id": "tests_test_memory_manager_testupsertmemory_test_create" }, @@ -35408,7 +36173,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L40", - "community": 636, + "community": 633, "norm_label": ".test_unchanged()", "id": "tests_test_memory_manager_testupsertmemory_test_unchanged" }, @@ -35426,7 +36191,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L59", - "community": 140, + "community": 635, "norm_label": ".test_limit_not_enforced_without_roles()", "id": "tests_test_memory_manager_testupsertmemory_test_limit_not_enforced_without_roles" }, @@ -35453,7 +36218,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L81", - "community": 140, + "community": 636, "norm_label": ".test_counts_active()", "id": "tests_test_memory_manager_testcountmemories_test_counts_active" }, @@ -35489,7 +36254,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L102", - "community": 635, + "community": 140, "norm_label": ".test_returns_memories()", "id": "tests_test_memory_manager_testgetusermemories_test_returns_memories" }, @@ -35525,7 +36290,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L126", - "community": 140, + "community": 630, "norm_label": ".test_soft_delete()", "id": "tests_test_memory_manager_testdeletememory_test_soft_delete" }, @@ -35534,7 +36299,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L132", - "community": 140, + "community": 631, "norm_label": ".test_delete_nonexistent()", "id": "tests_test_memory_manager_testdeletememory_test_delete_nonexistent" }, @@ -35579,7 +36344,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L23", - "community": 590, + "community": 568, "norm_label": "testmemorytoolfunctions", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions" }, @@ -35588,7 +36353,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L26", - "community": 590, + "community": 568, "norm_label": ".test_search_memory_has_docstring()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_search_memory_has_docstring" }, @@ -35597,7 +36362,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L30", - "community": 590, + "community": 568, "norm_label": ".test_save_memory_has_docstring()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_save_memory_has_docstring" }, @@ -35606,7 +36371,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L34", - "community": 590, + "community": 568, "norm_label": ".test_search_memory_signature()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_search_memory_signature" }, @@ -35615,7 +36380,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L39", - "community": 590, + "community": 568, "norm_label": ".test_save_memory_signature()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_save_memory_signature" }, @@ -35624,7 +36389,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L46", - "community": 590, + "community": 568, "norm_label": ".test_search_memory_has_type_hints()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_search_memory_has_type_hints" }, @@ -35633,7 +36398,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L50", - "community": 590, + "community": 568, "norm_label": ".test_save_memory_has_type_hints()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_save_memory_has_type_hints" }, @@ -35642,7 +36407,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L54", - "community": 590, + "community": 568, "norm_label": ".test_memory_tools_is_list_of_callables()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_memory_tools_is_list_of_callables" }, @@ -35651,7 +36416,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L60", - "community": 502, + "community": 523, "norm_label": ".test_memory_tool_names_unchanged()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_memory_tool_names_unchanged" }, @@ -35660,7 +36425,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L64", - "community": 502, + "community": 609, "norm_label": "testtoolregistry", "id": "tests_test_memory_tools_wiring_testtoolregistry" }, @@ -35669,7 +36434,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L67", - "community": 502, + "community": 609, "norm_label": ".test_registry_contains_memory_tools()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_contains_memory_tools" }, @@ -35678,7 +36443,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L71", - "community": 502, + "community": 609, "norm_label": ".test_registry_values_are_callable()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_values_are_callable" }, @@ -35687,7 +36452,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L75", - "community": 502, + "community": 609, "norm_label": ".test_registry_matches_tool_names()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_matches_tool_names" }, @@ -35696,7 +36461,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L79", - "community": 628, + "community": 49, "norm_label": "testmakechatincludesmemorytools", "id": "tests_test_memory_tools_wiring_testmakechatincludesmemorytools" }, @@ -35714,7 +36479,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L112", - "community": 615, + "community": 49, "norm_label": "testdispatchroutesmemorytools", "id": "tests_test_memory_tools_wiring_testdispatchroutesmemorytools" }, @@ -35759,7 +36524,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L24", - "community": 590, + "community": 568, "norm_label": "verify the actual async tool functions have correct signatures.", "id": "tests_test_memory_tools_wiring_rationale_24" }, @@ -35768,7 +36533,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L65", - "community": 502, + "community": 609, "norm_label": "tool_registry pattern must work correctly.", "id": "tests_test_memory_tools_wiring_rationale_65" }, @@ -35777,7 +36542,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L80", - "community": 628, + "community": 49, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_80" }, @@ -35786,7 +36551,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L113", - "community": 615, + "community": 49, "norm_label": "dispatchtoolcall must route memory tool names via tool_registry.", "id": "tests_test_memory_tools_wiring_rationale_113" }, @@ -35903,7 +36668,7 @@ "file_type": "code", "source_file": "tests/test_models.py", "source_location": "L1", - "community": 125, + "community": 566, "norm_label": "test_models.py", "id": "tests_test_models_py" }, @@ -36119,7 +36884,7 @@ "file_type": "code", "source_file": "tests/test_models.py", "source_location": "L162", - "community": 125, + "community": 566, "norm_label": "testprometheussessionmodel", "id": "tests_test_models_testprometheussessionmodel" }, @@ -36128,7 +36893,7 @@ "file_type": "code", "source_file": "tests/test_models.py", "source_location": "L163", - "community": 125, + "community": 566, "norm_label": ".test_create_session()", "id": "tests_test_models_testprometheussessionmodel_test_create_session" }, @@ -36137,7 +36902,7 @@ "file_type": "code", "source_file": "tests/test_models.py", "source_location": "L172", - "community": 125, + "community": 566, "norm_label": ".test_default_history()", "id": "tests_test_models_testprometheussessionmodel_test_default_history" }, @@ -36344,7 +37109,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L1", - "community": 186, + "community": 502, "norm_label": "test_pagination.py", "id": "tests_test_pagination_py" }, @@ -36353,7 +37118,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L14", - "community": 186, + "community": 502, "norm_label": "app()", "id": "tests_test_pagination_app" }, @@ -36362,7 +37127,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L35", - "community": 186, + "community": 502, "norm_label": "client()", "id": "tests_test_pagination_client" }, @@ -36371,7 +37136,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L39", - "community": 186, + "community": 576, "norm_label": "testinlinepagination", "id": "tests_test_pagination_testinlinepagination" }, @@ -36380,7 +37145,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L40", - "community": 186, + "community": 576, "norm_label": ".test_defaults()", "id": "tests_test_pagination_testinlinepagination_test_defaults" }, @@ -36389,7 +37154,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L48", - "community": 186, + "community": 576, "norm_label": ".test_custom_limit()", "id": "tests_test_pagination_testinlinepagination_test_custom_limit" }, @@ -36398,7 +37163,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L54", - "community": 186, + "community": 576, "norm_label": ".test_custom_offset()", "id": "tests_test_pagination_testinlinepagination_test_custom_offset" }, @@ -36407,7 +37172,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L61", - "community": 186, + "community": 576, "norm_label": ".test_limit_and_offset()", "id": "tests_test_pagination_testinlinepagination_test_limit_and_offset" }, @@ -36416,7 +37181,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L69", - "community": 186, + "community": 576, "norm_label": ".test_limit_exceeds_max_rejected()", "id": "tests_test_pagination_testinlinepagination_test_limit_exceeds_max_rejected" }, @@ -36425,7 +37190,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L73", - "community": 186, + "community": 576, "norm_label": ".test_limit_zero_rejected()", "id": "tests_test_pagination_testinlinepagination_test_limit_zero_rejected" }, @@ -36434,7 +37199,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L77", - "community": 186, + "community": 576, "norm_label": ".test_negative_offset_rejected()", "id": "tests_test_pagination_testinlinepagination_test_negative_offset_rejected" }, @@ -36443,7 +37208,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L81", - "community": 186, + "community": 576, "norm_label": ".test_offset_beyond_total()", "id": "tests_test_pagination_testinlinepagination_test_offset_beyond_total" }, @@ -36452,7 +37217,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L86", - "community": 186, + "community": 576, "norm_label": ".test_limit_equals_max()", "id": "tests_test_pagination_testinlinepagination_test_limit_equals_max" }, @@ -36461,7 +37226,7 @@ "file_type": "rationale", "source_file": "tests/test_pagination.py", "source_location": "L1", - "community": 186, + "community": 502, "norm_label": "tests for inline pagination params (used in user + prometheus controllers).", "id": "tests_test_pagination_rationale_1" }, @@ -37064,7 +37829,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L919", - "community": 631, + "community": 643, "norm_label": "test_get_google_sso_with_redirect()", "id": "tests_test_prometheus_auth_coverage_test_get_google_sso_with_redirect" }, @@ -37073,7 +37838,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L938", - "community": 631, + "community": 643, "norm_label": "test_get_google_sso_default_redirect()", "id": "tests_test_prometheus_auth_coverage_test_get_google_sso_default_redirect" }, @@ -37190,7 +37955,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L44", - "community": 587, + "community": 100, "norm_label": "testmemorytoolfunctions", "id": "tests_test_prometheus_tools_testmemorytoolfunctions" }, @@ -37199,7 +37964,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L45", - "community": 587, + "community": 100, "norm_label": ".test_search_memory_has_docstring()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_search_memory_has_docstring" }, @@ -37208,7 +37973,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L49", - "community": 587, + "community": 100, "norm_label": ".test_save_memory_has_docstring()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_save_memory_has_docstring" }, @@ -37217,7 +37982,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L53", - "community": 587, + "community": 100, "norm_label": ".test_search_memory_signature()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_search_memory_signature" }, @@ -37226,7 +37991,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L59", - "community": 587, + "community": 100, "norm_label": ".test_save_memory_signature()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_save_memory_signature" }, @@ -37235,7 +38000,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L66", - "community": 587, + "community": 100, "norm_label": ".test_search_memory_has_type_hints()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_search_memory_has_type_hints" }, @@ -37244,7 +38009,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L71", - "community": 587, + "community": 100, "norm_label": ".test_save_memory_has_type_hints()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_save_memory_has_type_hints" }, @@ -37253,7 +38018,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L77", - "community": 587, + "community": 100, "norm_label": ".test_memory_tools_is_list_of_callables()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_memory_tools_is_list_of_callables" }, @@ -37262,7 +38027,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L83", - "community": 587, + "community": 100, "norm_label": ".test_memory_tool_names_unchanged()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_memory_tool_names_unchanged" }, @@ -37352,7 +38117,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L126", - "community": 630, + "community": 100, "norm_label": "testgeminicompatibility", "id": "tests_test_prometheus_tools_testgeminicompatibility" }, @@ -37370,7 +38135,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L135", - "community": 630, + "community": 100, "norm_label": ".test_no_harnessstate_in_any_signature()", "id": "tests_test_prometheus_tools_testgeminicompatibility_test_no_harnessstate_in_any_signature" }, @@ -37379,7 +38144,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L151", - "community": 633, + "community": 100, "norm_label": "testtoolregistry", "id": "tests_test_prometheus_tools_testtoolregistry" }, @@ -37388,7 +38153,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L152", - "community": 633, + "community": 100, "norm_label": ".test_registry_contains_memory_tools()", "id": "tests_test_prometheus_tools_testtoolregistry_test_registry_contains_memory_tools" }, @@ -37397,7 +38162,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L156", - "community": 633, + "community": 100, "norm_label": ".test_registry_values_are_callable()", "id": "tests_test_prometheus_tools_testtoolregistry_test_registry_values_are_callable" }, @@ -37406,7 +38171,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L160", - "community": 633, + "community": 100, "norm_label": ".test_registry_matches_tool_names()", "id": "tests_test_prometheus_tools_testtoolregistry_test_registry_matches_tool_names" }, @@ -37424,7 +38189,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_tools.py", "source_location": "L127", - "community": 630, + "community": 100, "norm_label": "every function in tool_registry must have gemini-safe signatures. custom cl", "id": "tests_test_prometheus_tools_rationale_127" }, @@ -37433,7 +38198,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_tools.py", "source_location": "L136", - "community": 630, + "community": 100, "norm_label": "regression: harnessstate must never leak into tool signatures.", "id": "tests_test_prometheus_tools_rationale_136" }, @@ -37811,7 +38576,7 @@ "file_type": "code", "source_file": "tests/test_roles.py", "source_location": "L1", - "community": 527, + "community": 577, "norm_label": "test_roles.py", "id": "tests_test_roles_py" }, @@ -37820,7 +38585,7 @@ "file_type": "code", "source_file": "tests/test_roles.py", "source_location": "L4", - "community": 527, + "community": 577, "norm_label": "testpermission", "id": "tests_test_roles_testpermission" }, @@ -37829,7 +38594,7 @@ "file_type": "code", "source_file": "tests/test_roles.py", "source_location": "L5", - "community": 527, + "community": 577, "norm_label": ".test_permission_enum_values()", "id": "tests_test_roles_testpermission_test_permission_enum_values" }, @@ -37838,7 +38603,7 @@ "file_type": "code", "source_file": "tests/test_roles.py", "source_location": "L10", - "community": 527, + "community": 577, "norm_label": ".test_permission_all_includes_all()", "id": "tests_test_roles_testpermission_test_permission_all_includes_all" }, @@ -39062,7 +39827,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L1", - "community": 521, + "community": 503, "norm_label": "test_state_tools.py", "id": "tests_test_state_tools_py" }, @@ -39152,7 +39917,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L60", - "community": 521, + "community": 503, "norm_label": "testgetstate", "id": "tests_test_state_tools_testgetstate" }, @@ -39161,7 +39926,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L62", - "community": 521, + "community": 503, "norm_label": "test_get_state_specific_key()", "id": "tests_test_state_tools_test_get_state_specific_key" }, @@ -39170,7 +39935,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L69", - "community": 521, + "community": 503, "norm_label": "test_get_state_all()", "id": "tests_test_state_tools_test_get_state_all" }, @@ -39179,7 +39944,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L77", - "community": 521, + "community": 503, "norm_label": "test_get_state_missing_key()", "id": "tests_test_state_tools_test_get_state_missing_key" }, @@ -39188,7 +39953,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L83", - "community": 521, + "community": 503, "norm_label": "test_get_state_no_state()", "id": "tests_test_state_tools_test_get_state_no_state" }, @@ -39197,7 +39962,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L88", - "community": 521, + "community": 503, "norm_label": "testsetstate", "id": "tests_test_state_tools_testsetstate" }, @@ -39206,7 +39971,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L90", - "community": 521, + "community": 503, "norm_label": "test_set_state()", "id": "tests_test_state_tools_test_set_state" }, @@ -39224,7 +39989,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L102", - "community": 521, + "community": 503, "norm_label": "teststatedispatch", "id": "tests_test_state_tools_teststatedispatch" }, @@ -39233,7 +39998,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L104", - "community": 521, + "community": 503, "norm_label": "test_dispatch_get_state()", "id": "tests_test_state_tools_test_dispatch_get_state" }, @@ -39242,7 +40007,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L114", - "community": 521, + "community": 503, "norm_label": "test_dispatch_set_state()", "id": "tests_test_state_tools_test_dispatch_set_state" }, @@ -39665,7 +40430,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L344", - "community": 63, + "community": 517, "norm_label": "._make_manager()", "id": "tests_test_stocks_api_coverage_testdeserializejsoncolumns_make_manager" }, @@ -39764,7 +40529,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L419", - "community": 577, + "community": 605, "norm_label": ".test_deserialize_float_nan_direct()", "id": "tests_test_stocks_api_coverage_testdeserializejsoncolumns_test_deserialize_float_nan_direct" }, @@ -39773,7 +40538,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L433", - "community": 566, + "community": 614, "norm_label": ".test_deserialize_non_nan_float()", "id": "tests_test_stocks_api_coverage_testdeserializejsoncolumns_test_deserialize_non_nan_float" }, @@ -39791,7 +40556,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L451", - "community": 162, + "community": 511, "norm_label": ".test_deserialize_mixed_string_none_parses_json()", "id": "tests_test_stocks_api_coverage_testdeserializejsoncolumns_test_deserialize_mixed_string_none_parses_json" }, @@ -39809,7 +40574,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L498", - "community": 162, + "community": 511, "norm_label": "testfilterbysearchterms", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms" }, @@ -39818,7 +40583,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L501", - "community": 162, + "community": 511, "norm_label": "._make_manager()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_make_manager" }, @@ -39827,7 +40592,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L509", - "community": 162, + "community": 511, "norm_label": ".test_filter_empty_search_returns_all()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_empty_search_returns_all" }, @@ -39836,7 +40601,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L515", - "community": 162, + "community": 511, "norm_label": ".test_filter_ticker_index_hit()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_ticker_index_hit" }, @@ -39845,7 +40610,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L523", - "community": 162, + "community": 511, "norm_label": ".test_filter_multiple_terms_index()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_multiple_terms_index" }, @@ -39854,7 +40619,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L530", - "community": 162, + "community": 511, "norm_label": ".test_filter_no_index_match_fallback_to_str()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_no_index_match_fallback_to_str" }, @@ -39863,7 +40628,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L538", - "community": 162, + "community": 511, "norm_label": ".test_filter_fallback_multiple_terms()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_fallback_multiple_terms" }, @@ -39872,7 +40637,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L545", - "community": 162, + "community": 511, "norm_label": ".test_filter_case_insensitive()", "id": "tests_test_stocks_api_coverage_testfilterbysearchterms_test_filter_case_insensitive" }, @@ -39890,7 +40655,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L556", - "community": 63, + "community": 517, "norm_label": "._make_manager()", "id": "tests_test_stocks_api_coverage_testqueryhistorical_make_manager" }, @@ -40196,7 +40961,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L841", - "community": 17, + "community": 39, "norm_label": ".test_fundamental_date_range_two_dates()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_date_range_two_dates" }, @@ -40223,7 +40988,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L882", - "community": 39, + "community": 17, "norm_label": ".test_fundamental_search_multiple_terms()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_search_multiple_terms" }, @@ -40241,7 +41006,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L898", - "community": 17, + "community": 39, "norm_label": ".test_fundamental_dates_one_date()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_dates_one_date" }, @@ -40520,7 +41285,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1265", - "community": 22, + "community": 493, "norm_label": ".test_http_route_search_required()", "id": "tests_test_stocks_api_coverage_testquerylivecotation_test_http_route_search_required" }, @@ -40718,7 +41483,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L420", - "community": 577, + "community": 605, "norm_label": "replacenan handles direct float nan values (line 34).", "id": "tests_test_stocks_api_coverage_rationale_420" }, @@ -40727,7 +41492,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L434", - "community": 566, + "community": 614, "norm_label": "non-json-dict/list string is left as-is.", "id": "tests_test_stocks_api_coverage_rationale_434" }, @@ -40745,7 +41510,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L452", - "community": 162, + "community": 511, "norm_label": "regression: is_string_dtype fails when column has strings + none (pandas 2.x).", "id": "tests_test_stocks_api_coverage_rationale_452" }, @@ -40763,7 +41528,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L499", - "community": 162, + "community": 511, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_499" }, @@ -40889,7 +41654,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L842", - "community": 17, + "community": 39, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_842" }, @@ -40916,7 +41681,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L883", - "community": 39, + "community": 17, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_883" }, @@ -40934,7 +41699,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L899", - "community": 17, + "community": 39, "norm_label": "len(daterange) == 1 -> per-ticker closest snapshot.", "id": "tests_test_stocks_api_coverage_rationale_899" }, @@ -41015,7 +41780,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1266", - "community": 22, + "community": 493, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1266" }, @@ -42266,7 +43031,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L1", - "community": 95, + "community": 574, "norm_label": "test_type_aware_decay.py", "id": "tests_test_type_aware_decay_py" }, @@ -42275,7 +43040,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L11", - "community": 95, + "community": 574, "norm_label": "_create()", "id": "tests_test_type_aware_decay_create" }, @@ -42284,7 +43049,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L29", - "community": 95, + "community": 574, "norm_label": "testtypeawaredecay", "id": "tests_test_type_aware_decay_testtypeawaredecay" }, @@ -42293,7 +43058,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L30", - "community": 95, + "community": 574, "norm_label": ".test_preference_decays_slowly()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_preference_decays_slowly" }, @@ -42302,7 +43067,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L36", - "community": 95, + "community": 574, "norm_label": ".test_context_decays_fast()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_context_decays_fast" }, @@ -42311,7 +43076,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L42", - "community": 95, + "community": 574, "norm_label": ".test_analysis_decays_normally()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_analysis_decays_normally" }, @@ -42320,7 +43085,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L48", - "community": 95, + "community": 574, "norm_label": ".test_feedback_decays_medium()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_feedback_decays_medium" }, @@ -42329,7 +43094,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L54", - "community": 95, + "community": 574, "norm_label": ".test_unknown_type_uses_default()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_unknown_type_uses_default" }, @@ -42338,7 +43103,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L60", - "community": 95, + "community": 574, "norm_label": ".test_mixed_types_all_correct()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_mixed_types_all_correct" }, @@ -42347,7 +43112,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L76", - "community": 95, + "community": 574, "norm_label": ".test_preference_survives_longer()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_preference_survives_longer" }, @@ -42356,7 +43121,7 @@ "file_type": "rationale", "source_file": "tests/test_type_aware_decay.py", "source_location": "L77", - "community": 95, + "community": 574, "norm_label": "after 10 cycles, preference (0.99^10) > context (0.90^10).", "id": "tests_test_type_aware_decay_rationale_77" }, @@ -42365,7 +43130,7 @@ "file_type": "code", "source_file": "tests/test_user_deps.py", "source_location": "L1", - "community": 98, + "community": 528, "norm_label": "test_user_deps.py", "id": "tests_test_user_deps_py" }, @@ -42500,7 +43265,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L1", - "community": 131, + "community": 21, "norm_label": "test_vector_utils.py", "id": "tests_test_vector_utils_py" }, @@ -42554,7 +43319,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L38", - "community": 131, + "community": 546, "norm_label": "testcontenthash", "id": "tests_test_vector_utils_testcontenthash" }, @@ -42563,7 +43328,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L39", - "community": 131, + "community": 546, "norm_label": ".test_deterministic()", "id": "tests_test_vector_utils_testcontenthash_test_deterministic" }, @@ -42572,7 +43337,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L42", - "community": 131, + "community": 546, "norm_label": ".test_different_inputs()", "id": "tests_test_vector_utils_testcontenthash_test_different_inputs" }, @@ -42581,7 +43346,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L45", - "community": 131, + "community": 546, "norm_label": ".test_hex_format()", "id": "tests_test_vector_utils_testcontenthash_test_hex_format" }, @@ -43904,7 +44669,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L190", - "community": 93, + "community": 617, "norm_label": "system prompt should instruct llm about memory vs state.", "id": "tests_test_agent_state_integration_rationale_190" }, @@ -43922,7 +44687,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1083", - "community": 498, + "community": 148, "norm_label": "covers lines 114-115: session ownership check fails.", "id": "tests_test_controllers_coverage_rationale_1083" }, @@ -43931,7 +44696,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1120", - "community": 148, + "community": 99, "norm_label": "generic exception in chat propagates to fastapi's default 500 handler.", "id": "tests_test_controllers_coverage_rationale_1120" }, @@ -43940,7 +44705,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1138", - "community": 604, + "community": 45, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1138" }, @@ -43958,7 +44723,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1166", - "community": 605, + "community": 14, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1166" }, @@ -44003,7 +44768,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1223", - "community": 620, + "community": 529, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1223" }, @@ -44012,7 +44777,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1226", - "community": 623, + "community": 529, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1226" }, @@ -44021,7 +44786,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1243", - "community": 625, + "community": 529, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1243" }, @@ -44048,7 +44813,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1301", - "community": 568, + "community": 529, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1301" }, @@ -44057,7 +44822,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1317", - "community": 609, + "community": 563, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1317" }, @@ -44066,7 +44831,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1334", - "community": 614, + "community": 563, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1334" }, @@ -44075,7 +44840,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1351", - "community": 617, + "community": 563, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1351" }, @@ -44084,7 +44849,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1375", - "community": 45, + "community": 194, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1375" }, @@ -44093,7 +44858,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1385", - "community": 546, + "community": 194, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1385" }, @@ -44102,7 +44867,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1388", - "community": 546, + "community": 194, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1388" }, @@ -44111,7 +44876,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1404", - "community": 592, + "community": 194, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1404" }, @@ -44246,7 +45011,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L42", - "community": 503, + "community": 136, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_42" }, @@ -44255,7 +45020,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L79", - "community": 521, + "community": 503, "norm_label": "retrieve values from the harness state. use this to recall intermediate results,", "id": "prometheus_tools_rationale_79" }, @@ -44264,7 +45029,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L147", - "community": 588, + "community": 221, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_147" }, @@ -44282,7 +45047,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L30", - "community": 231, + "community": 521, "norm_label": "keys with jaccard > 0.8 should merge.", "id": "tests_test_memory_dedup_rationale_30" }, @@ -44291,7 +45056,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L40", - "community": 231, + "community": 521, "norm_label": "keys with low similarity should not merge.", "id": "tests_test_memory_dedup_rationale_40" }, @@ -44300,7 +45065,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L67", - "community": 231, + "community": 521, "norm_label": "keys with jaccard <= 0.8 should not merge.", "id": "tests_test_memory_dedup_rationale_67" }, @@ -44570,7 +45335,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L131", - "community": 588, + "community": 221, "norm_label": "read a file from the sandbox filesystem. args: path: absolute pa", "id": "prometheus_tools_rationale_131" }, @@ -44768,7 +45533,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L130", - "community": 588, + "community": 221, "norm_label": "read a file from the sandbox filesystem. args: path: absolute pa", "id": "prometheus_tools_rationale_130" }, @@ -44777,7 +45542,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L7", - "community": 528, + "community": 24, "norm_label": "testagentsandboxintegration", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration" }, @@ -44786,7 +45551,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L8", - "community": 528, + "community": 24, "norm_label": ".test_build_system_prompt_includes_sandbox_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_includes_sandbox_instructions" }, @@ -44795,7 +45560,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L14", - "community": 528, + "community": 24, "norm_label": ".test_build_system_prompt_includes_state_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_includes_state_instructions" }, @@ -44804,7 +45569,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L19", - "community": 528, + "community": 24, "norm_label": ".test_build_system_prompt_with_state()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_with_state" }, @@ -44903,7 +45668,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L41", - "community": 503, + "community": 136, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_41" }, @@ -44912,7 +45677,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L78", - "community": 521, + "community": 503, "norm_label": "retrieve values from the harness state. use this to recall intermediate results,", "id": "prometheus_tools_rationale_78" }, @@ -47117,7 +47882,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L119", - "community": 221, + "community": 100, "norm_label": "test_set_state_no_state_returns_error()", "id": "tests_test_prometheus_tools_test_set_state_no_state_returns_error" }, @@ -47135,7 +47900,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_tools.py", "source_location": "L128", - "community": 630, + "community": 100, "norm_label": "every function in tool_registry must have gemini-safe signatures. custom cl", "id": "tests_test_prometheus_tools_rationale_128" }, @@ -47144,7 +47909,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_tools.py", "source_location": "L137", - "community": 630, + "community": 100, "norm_label": "regression: harnessstate must never leak into tool signatures.", "id": "tests_test_prometheus_tools_rationale_137" }, @@ -47153,7 +47918,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L1", - "community": 135, + "community": 162, "norm_label": "cache.py", "id": "main_app_prometheus_cache_py" }, @@ -47162,7 +47927,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L7", - "community": 135, + "community": 162, "norm_label": "resultcache", "id": "prometheus_cache_resultcache" }, @@ -47171,7 +47936,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L8", - "community": 135, + "community": 162, "norm_label": ".__init__()", "id": "prometheus_cache_resultcache_init" }, @@ -47180,7 +47945,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L11", - "community": 135, + "community": 162, "norm_label": ".cachepath()", "id": "prometheus_cache_resultcache_cachepath" }, @@ -47189,7 +47954,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L15", - "community": 135, + "community": 162, "norm_label": ".get()", "id": "prometheus_cache_resultcache_get" }, @@ -47198,7 +47963,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L21", - "community": 135, + "community": 162, "norm_label": ".set()", "id": "prometheus_cache_resultcache_set" }, @@ -47207,7 +47972,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L31", - "community": 135, + "community": 162, "norm_label": ".invalidate()", "id": "prometheus_cache_resultcache_invalidate" }, @@ -47216,7 +47981,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L38", - "community": 135, + "community": 162, "norm_label": ".exists()", "id": "prometheus_cache_resultcache_exists" }, @@ -47261,7 +48026,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L139", - "community": 576, + "community": 525, "norm_label": "read_sandbox_file()", "id": "prometheus_tools_read_sandbox_file" }, @@ -47270,7 +48035,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L151", - "community": 576, + "community": 525, "norm_label": "upload_to_sandbox()", "id": "prometheus_tools_upload_to_sandbox" }, @@ -47279,7 +48044,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L165", - "community": 576, + "community": 525, "norm_label": "check_cache()", "id": "prometheus_tools_check_cache" }, @@ -47306,7 +48071,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L140", - "community": 576, + "community": 525, "norm_label": "read a file from the sandbox filesystem. args: path: absolute pa", "id": "prometheus_tools_rationale_140" }, @@ -47315,7 +48080,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L152", - "community": 576, + "community": 525, "norm_label": "upload a file to the sandbox filesystem. use this to push data files (csv,", "id": "prometheus_tools_rationale_152" }, @@ -47324,7 +48089,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L166", - "community": 576, + "community": 525, "norm_label": "check if a computed result exists in the cache. use before executing expens", "id": "prometheus_tools_rationale_166" }, @@ -47333,7 +48098,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L9", - "community": 528, + "community": 24, "norm_label": ".test_build_system_prompt_no_state()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_no_state" }, @@ -47342,7 +48107,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L20", - "community": 528, + "community": 24, "norm_label": ".test_build_system_prompt_empty_state()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_empty_state" }, @@ -47351,7 +48116,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L25", - "community": 528, + "community": 24, "norm_label": ".test_system_prompt_includes_state_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_system_prompt_includes_state_instructions" }, @@ -47360,7 +48125,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L30", - "community": 528, + "community": 24, "norm_label": ".test_system_prompt_includes_sandbox_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_system_prompt_includes_sandbox_instructions" }, @@ -47369,7 +48134,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L34", - "community": 528, + "community": 24, "norm_label": ".test_system_prompt_includes_cache_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_system_prompt_includes_cache_instructions" }, @@ -47378,7 +48143,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L38", - "community": 528, + "community": 24, "norm_label": ".test_makechat_uses_tool_registry()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_makechat_uses_tool_registry" }, @@ -47549,7 +48314,7 @@ "file_type": "code", "source_file": "tests/test_config_sandbox.py", "source_location": "L1", - "community": 102, + "community": 577, "norm_label": "test_config_sandbox.py", "id": "tests_test_config_sandbox_py" }, @@ -47972,7 +48737,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L194", - "community": 93, + "community": 617, "norm_label": "system prompt should instruct llm about memory vs state.", "id": "tests_test_agent_state_integration_rationale_194" }, @@ -48206,7 +48971,7 @@ "file_type": "code", "source_file": "main/app/prometheus/cache.py", "source_location": "L19", - "community": 135, + "community": 162, "norm_label": "._cache_path()", "id": "prometheus_cache_resultcache_cache_path" }, @@ -48215,7 +48980,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L1", - "community": 135, + "community": 162, "norm_label": "resultcache \u2014 sha256-keyed file-based cache for computed results.", "id": "prometheus_cache_rationale_1" }, @@ -48224,7 +48989,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L10", - "community": 135, + "community": 162, "norm_label": "file-based cache keyed by sha256 of code. stores results as json under:", "id": "prometheus_cache_rationale_10" }, @@ -48233,7 +48998,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L24", - "community": 135, + "community": 162, "norm_label": "return cached result dict or none if miss.", "id": "prometheus_cache_rationale_24" }, @@ -48242,7 +49007,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L31", - "community": 135, + "community": 162, "norm_label": "store result with timestamp.", "id": "prometheus_cache_rationale_31" }, @@ -48251,7 +49016,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L42", - "community": 135, + "community": 162, "norm_label": "delete all cached results for a session.", "id": "prometheus_cache_rationale_42" }, @@ -48260,7 +49025,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/cache.py", "source_location": "L50", - "community": 135, + "community": 162, "norm_label": "check if a result exists for the given code.", "id": "prometheus_cache_rationale_50" }, @@ -48602,7 +49367,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L77", - "community": 521, + "community": 503, "norm_label": "retrieve values from the harness state. use this to recall intermediate results,", "id": "prometheus_tools_rationale_77" }, @@ -48656,7 +49421,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L191", - "community": 93, + "community": 617, "norm_label": "system prompt should instruct llm about memory vs state.", "id": "tests_test_agent_state_integration_rationale_191" }, @@ -48665,7 +49430,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L104", - "community": 521, + "community": 503, "norm_label": "executestatetool()", "id": "prometheus_tools_executestatetool" }, @@ -48683,7 +49448,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L39", - "community": 503, + "community": 136, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_39" }, @@ -48710,7 +49475,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L54", - "community": 521, + "community": 503, "norm_label": "testexecutestatetool", "id": "tests_test_state_tools_testexecutestatetool" }, @@ -48719,7 +49484,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L84", - "community": 521, + "community": 503, "norm_label": "test_unknown_tool()", "id": "tests_test_state_tools_test_unknown_tool" }, @@ -48746,7 +49511,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/state.py", "source_location": "L22", - "community": 502, + "community": 523, "norm_label": "store a value in state. marks state as changed for context injection.", "id": "prometheus_state_rationale_22" }, @@ -48809,7 +49574,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L38", - "community": 503, + "community": 136, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_38" }, @@ -48863,7 +49628,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L46", - "community": 84, + "community": 525, "norm_label": "executememorytool()", "id": "prometheus_tools_executememorytool" }, @@ -48872,7 +49637,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L29", - "community": 503, + "community": 136, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_29" }, @@ -48881,7 +49646,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L52", - "community": 231, + "community": 521, "norm_label": "keys with low similarity should not merge.", "id": "tests_test_memory_dedup_rationale_52" }, @@ -48890,7 +49655,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L85", - "community": 231, + "community": 521, "norm_label": "keys with jaccard <= 0.8 should not merge.", "id": "tests_test_memory_dedup_rationale_85" }, @@ -49007,7 +49772,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L52", - "community": 628, + "community": 49, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_52" }, @@ -49016,7 +49781,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L89", - "community": 615, + "community": 49, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_89" }, @@ -49043,7 +49808,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L57", - "community": 628, + "community": 49, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_57" }, @@ -49052,7 +49817,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L92", - "community": 615, + "community": 49, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_92" }, @@ -49061,7 +49826,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L17", - "community": 222, + "community": 53, "norm_label": "_normalize_key()", "id": "prometheus_memory_normalize_key" }, @@ -49079,7 +49844,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L54", - "community": 95, + "community": 518, "norm_label": "decay applies to all active memories, not just accessed ones.", "id": "tests_test_memory_maintenance_rationale_54" }, @@ -49088,7 +49853,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L67", - "community": 95, + "community": 518, "norm_label": "basescore should never reach exactly 0 from decay alone.", "id": "tests_test_memory_maintenance_rationale_67" }, @@ -49097,7 +49862,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L85", - "community": 518, + "community": 574, "norm_label": "score below threshold + accesscount=0 + 90+ days \u2192 archived.", "id": "tests_test_memory_maintenance_rationale_85" }, @@ -49106,7 +49871,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L92", - "community": 518, + "community": 574, "norm_label": "low score but accessed recently \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_92" }, @@ -49115,7 +49880,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L99", - "community": 518, + "community": 574, "norm_label": "zero access but score still above threshold \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_99" }, @@ -49124,7 +49889,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L106", - "community": 518, + "community": 574, "norm_label": "even with low score, if accessed \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_106" }, @@ -49133,7 +49898,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L113", - "community": 518, + "community": 574, "norm_label": "already archived memories are skipped.", "id": "tests_test_memory_maintenance_rationale_113" }, @@ -49169,7 +49934,7 @@ "file_type": "code", "source_file": "main/utils/models/loader.py", "source_location": "L23", - "community": 84, + "community": 560, "norm_label": "embed()", "id": "models_loader_embed" }, @@ -49349,7 +50114,7 @@ "file_type": "code", "source_file": "main/utils/models/loader.py", "source_location": "L11", - "community": 536, + "community": 560, "norm_label": "_downloadmodel()", "id": "models_loader_downloadmodel" }, @@ -49484,7 +50249,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1277", - "community": 620, + "community": 563, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1277" }, @@ -49493,7 +50258,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1302", - "community": 568, + "community": 529, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1302" }, @@ -49502,7 +50267,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1318", - "community": 609, + "community": 563, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1318" }, @@ -49511,7 +50276,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1335", - "community": 614, + "community": 563, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1335" }, @@ -49520,7 +50285,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1352", - "community": 617, + "community": 563, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1352" }, @@ -49529,7 +50294,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1376", - "community": 45, + "community": 194, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1376" }, @@ -49538,7 +50303,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1386", - "community": 546, + "community": 194, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1386" }, @@ -49547,7 +50312,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1389", - "community": 614, + "community": 194, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1389" }, @@ -49556,7 +50321,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1405", - "community": 592, + "community": 194, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1405" }, @@ -49808,7 +50573,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L56", - "community": 628, + "community": 49, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_56" }, @@ -49817,7 +50582,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L91", - "community": 615, + "community": 49, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_91" }, @@ -49844,7 +50609,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L20", - "community": 131, + "community": 546, "norm_label": "contenthash()", "id": "utils_vector_contenthash" }, @@ -50141,7 +50906,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L48", - "community": 628, + "community": 49, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_48" }, @@ -50150,7 +50915,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L76", - "community": 615, + "community": 49, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_76" }, @@ -50240,7 +51005,7 @@ "file_type": "code", "source_file": "main/controller/prometheus_controller.py", "source_location": "L177", - "community": 84, + "community": 560, "norm_label": "creatememory()", "id": "controller_prometheus_controller_creatememory" }, @@ -50258,7 +51023,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L1", - "community": 493, + "community": 72, "norm_label": "test_memory_controller.py", "id": "tests_test_memory_controller_py" }, @@ -50267,7 +51032,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L10", - "community": 493, + "community": 498, "norm_label": "testmemorycontrollerroutes", "id": "tests_test_memory_controller_testmemorycontrollerroutes" }, @@ -50276,7 +51041,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L11", - "community": 493, + "community": 498, "norm_label": ".test_get_memories_endpoint_exists()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_get_memories_endpoint_exists" }, @@ -50285,7 +51050,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L15", - "community": 493, + "community": 498, "norm_label": ".test_post_memories_endpoint_exists()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_post_memories_endpoint_exists" }, @@ -50294,7 +51059,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L19", - "community": 493, + "community": 498, "norm_label": ".test_delete_memories_endpoint_exists()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_delete_memories_endpoint_exists" }, @@ -50303,7 +51068,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L23", - "community": 493, + "community": 498, "norm_label": ".test_get_memories_rejects_unauthenticated()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_get_memories_rejects_unauthenticated" }, @@ -50321,7 +51086,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L65", - "community": 493, + "community": 72, "norm_label": "testmemoryendpointsintegration", "id": "tests_test_memory_controller_testmemoryendpointsintegration" }, @@ -50330,7 +51095,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L67", - "community": 493, + "community": 72, "norm_label": "test_get_memories_calls_manager()", "id": "tests_test_memory_controller_test_get_memories_calls_manager" }, @@ -50339,7 +51104,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L90", - "community": 493, + "community": 72, "norm_label": "test_create_memory_calls_manager()", "id": "tests_test_memory_controller_test_create_memory_calls_manager" }, @@ -50348,7 +51113,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L111", - "community": 493, + "community": 72, "norm_label": "test_create_memory_limit_reached()", "id": "tests_test_memory_controller_test_create_memory_limit_reached" }, @@ -50357,7 +51122,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L126", - "community": 493, + "community": 72, "norm_label": "test_delete_memory_calls_manager()", "id": "tests_test_memory_controller_test_delete_memory_calls_manager" }, @@ -50366,7 +51131,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L135", - "community": 493, + "community": 72, "norm_label": "test_delete_memory_not_found()", "id": "tests_test_memory_controller_test_delete_memory_not_found" }, @@ -50375,7 +51140,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L141", - "community": 493, + "community": 72, "norm_label": ".test_create_memory_missing_key()", "id": "tests_test_memory_controller_testmemoryendpointsintegration_test_create_memory_missing_key" }, @@ -50384,7 +51149,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L145", - "community": 493, + "community": 72, "norm_label": ".test_create_memory_missing_value()", "id": "tests_test_memory_controller_testmemoryendpointsintegration_test_create_memory_missing_value" }, @@ -50411,7 +51176,7 @@ "file_type": "rationale", "source_file": "main/utils/vector.py", "source_location": "L19", - "community": 131, + "community": 546, "norm_label": "md5 hash for change detection.", "id": "utils_vector_rationale_19" }, @@ -51050,7 +51815,7 @@ "file_type": "code", "source_file": "main/controller/prometheus_controller.py", "source_location": "L177", - "community": 84, + "community": 560, "norm_label": "create_memory()", "id": "controller_prometheus_controller_create_memory" }, @@ -51104,7 +51869,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L41", - "community": 131, + "community": 546, "norm_label": "content_hash()", "id": "utils_vector_content_hash" }, @@ -51140,7 +51905,7 @@ "file_type": "rationale", "source_file": "main/utils/vector.py", "source_location": "L42", - "community": 131, + "community": 546, "norm_label": "md5 hash for change detection.", "id": "utils_vector_rationale_42" }, @@ -51149,7 +51914,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L11", - "community": 493, + "community": 498, "norm_label": "verify memory endpoints exist and are wired correctly.", "id": "tests_test_memory_controller_rationale_11" }, @@ -51158,7 +51923,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L14", - "community": 493, + "community": 498, "norm_label": "get /prometheus/memories exists.", "id": "tests_test_memory_controller_rationale_14" }, @@ -51167,7 +51932,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L20", - "community": 493, + "community": 498, "norm_label": "post /prometheus/memories exists.", "id": "tests_test_memory_controller_rationale_20" }, @@ -51176,7 +51941,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L25", - "community": 493, + "community": 498, "norm_label": "delete /prometheus/memories/{id} exists.", "id": "tests_test_memory_controller_rationale_25" }, @@ -51185,7 +51950,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L30", - "community": 493, + "community": 498, "norm_label": "get /memories requires authentication.", "id": "tests_test_memory_controller_rationale_30" }, @@ -51203,7 +51968,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L75", - "community": 493, + "community": 72, "norm_label": "full integration tests using mocked memorymanager.", "id": "tests_test_memory_controller_rationale_75" }, @@ -51257,7 +52022,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L141", - "community": 493, + "community": 72, "norm_label": "post /memories rejects missing key.", "id": "tests_test_memory_controller_rationale_141" }, @@ -51266,7 +52031,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L146", - "community": 493, + "community": 72, "norm_label": "post /memories rejects missing value.", "id": "tests_test_memory_controller_rationale_146" }, @@ -51293,7 +52058,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L19", - "community": 140, + "community": 627, "norm_label": "admin gets extended limit (has all permissions).", "id": "tests_test_memory_manager_rationale_19" }, @@ -51302,7 +52067,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L25", - "community": 140, + "community": 632, "norm_label": "creates a new memory.", "id": "tests_test_memory_manager_rationale_25" }, @@ -51320,7 +52085,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L43", - "community": 636, + "community": 633, "norm_label": "returns unchanged when value is identical.", "id": "tests_test_memory_manager_rationale_43" }, @@ -51338,7 +52103,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L61", - "community": 140, + "community": 635, "norm_label": "no role check when user_roles not provided.", "id": "tests_test_memory_manager_rationale_61" }, @@ -51356,7 +52121,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L82", - "community": 140, + "community": 636, "norm_label": "counts only non-archived memories.", "id": "tests_test_memory_manager_rationale_82" }, @@ -51374,7 +52139,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L107", - "community": 635, + "community": 140, "norm_label": "returns paginated memories.", "id": "tests_test_memory_manager_rationale_107" }, @@ -51401,7 +52166,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L135", - "community": 140, + "community": 630, "norm_label": "soft-deletes a memory.", "id": "tests_test_memory_manager_rationale_135" }, @@ -51410,7 +52175,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L142", - "community": 140, + "community": 631, "norm_label": "returns false for non-existent memory.", "id": "tests_test_memory_manager_rationale_142" }, @@ -51635,7 +52400,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L101", - "community": 131, + "community": 546, "norm_label": "same input \u2192 same hash.", "id": "tests_test_vector_utils_rationale_101" }, @@ -51644,7 +52409,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L105", - "community": 131, + "community": 546, "norm_label": "different inputs \u2192 different hashes.", "id": "tests_test_vector_utils_rationale_105" }, @@ -51653,7 +52418,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L109", - "community": 131, + "community": 546, "norm_label": "returns 32-char hex string.", "id": "tests_test_vector_utils_rationale_109" }, @@ -52175,7 +52940,7 @@ "file_type": "code", "source_file": "main/app/prometheus/agent.py", "source_location": "L33", - "community": 116, + "community": 93, "norm_label": ".updatedates()", "id": "prometheus_agent_prometheus_updatedates" }, @@ -52526,7 +53291,7 @@ "file_type": "code", "source_file": "main/app/prometheus/generation.py", "source_location": "L1", - "community": 29, + "community": 566, "norm_label": "generation.py", "id": "main_app_prometheus_generation_py" }, @@ -52724,7 +53489,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L665", - "community": 107, + "community": 63, "norm_label": "covers lines 100-104, 106: get /user/sessions/current.", "id": "tests_test_controllers_coverage_rationale_665" }, @@ -52733,7 +53498,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L668", - "community": 107, + "community": 63, "norm_label": "covers lines 100-104, 106: session found.", "id": "tests_test_controllers_coverage_rationale_668" }, @@ -52742,7 +53507,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L701", - "community": 107, + "community": 63, "norm_label": "covers line 104: session not found.", "id": "tests_test_controllers_coverage_rationale_701" }, @@ -52805,7 +53570,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L832", - "community": 626, + "community": 45, "norm_label": "covers line 24: get /prometheus/health.", "id": "tests_test_controllers_coverage_rationale_832" }, @@ -52949,7 +53714,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1079", - "community": 498, + "community": 148, "norm_label": "covers lines 114-115: session ownership check fails.", "id": "tests_test_controllers_coverage_rationale_1079" }, @@ -52958,7 +53723,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1116", - "community": 148, + "community": 99, "norm_label": "generic exception in chat propagates to fastapi's default 500 handler.", "id": "tests_test_controllers_coverage_rationale_1116" }, @@ -52967,7 +53732,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1134", - "community": 604, + "community": 45, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1134" }, @@ -52985,7 +53750,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1162", - "community": 605, + "community": 14, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1162" }, @@ -53030,7 +53795,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1219", - "community": 620, + "community": 529, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1219" }, @@ -53039,7 +53804,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1222", - "community": 623, + "community": 529, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1222" }, @@ -53048,7 +53813,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1239", - "community": 625, + "community": 529, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1239" }, @@ -53084,7 +53849,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1298", - "community": 568, + "community": 529, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1298" }, @@ -53093,7 +53858,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1314", - "community": 609, + "community": 563, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1314" }, @@ -53102,7 +53867,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1331", - "community": 614, + "community": 563, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1331" }, @@ -53111,7 +53876,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1348", - "community": 617, + "community": 563, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1348" }, @@ -53120,7 +53885,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1372", - "community": 609, + "community": 563, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1372" }, @@ -53129,7 +53894,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1401", - "community": 592, + "community": 194, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1401" }, @@ -53336,7 +54101,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L663", - "community": 107, + "community": 63, "norm_label": "covers lines 100-104, 106: get /user/sessions/current.", "id": "tests_test_controllers_coverage_rationale_663" }, @@ -53345,7 +54110,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L666", - "community": 107, + "community": 63, "norm_label": "covers lines 100-104, 106: session found.", "id": "tests_test_controllers_coverage_rationale_666" }, @@ -53354,7 +54119,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L699", - "community": 107, + "community": 63, "norm_label": "covers line 104: session not found.", "id": "tests_test_controllers_coverage_rationale_699" }, @@ -53417,7 +54182,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L830", - "community": 626, + "community": 45, "norm_label": "covers line 24: get /prometheus/health.", "id": "tests_test_controllers_coverage_rationale_830" }, @@ -53561,7 +54326,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1078", - "community": 498, + "community": 148, "norm_label": "covers lines 114-115: session ownership check fails.", "id": "tests_test_controllers_coverage_rationale_1078" }, @@ -53570,7 +54335,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1115", - "community": 148, + "community": 99, "norm_label": "generic exception in chat propagates to fastapi's default 500 handler.", "id": "tests_test_controllers_coverage_rationale_1115" }, @@ -53579,7 +54344,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1133", - "community": 604, + "community": 45, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1133" }, @@ -53597,7 +54362,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1161", - "community": 605, + "community": 14, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1161" }, @@ -53633,7 +54398,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1218", - "community": 620, + "community": 529, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1218" }, @@ -53642,7 +54407,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1221", - "community": 623, + "community": 529, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1221" }, @@ -53651,7 +54416,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1238", - "community": 625, + "community": 529, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1238" }, @@ -53687,7 +54452,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1297", - "community": 625, + "community": 529, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1297" }, @@ -53696,7 +54461,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1313", - "community": 609, + "community": 563, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1313" }, @@ -53705,7 +54470,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1330", - "community": 614, + "community": 563, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1330" }, @@ -53714,7 +54479,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1347", - "community": 617, + "community": 563, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1347" }, @@ -53723,7 +54488,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1371", - "community": 45, + "community": 194, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1371" }, @@ -53732,7 +54497,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1381", - "community": 546, + "community": 194, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1381" }, @@ -53741,7 +54506,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1384", - "community": 546, + "community": 194, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1384" }, @@ -53750,7 +54515,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1400", - "community": 592, + "community": 194, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1400" }, @@ -53867,7 +54632,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L42", - "community": 517, + "community": 618, "norm_label": "parsecotationdates()", "id": "stocks_api_query_parsecotationdates" }, @@ -53876,7 +54641,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L14", - "community": 135, + "community": 95, "norm_label": "testcachelrueviction", "id": "tests_test_cache_testcachelrueviction" }, @@ -53885,7 +54650,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L17", - "community": 135, + "community": 95, "norm_label": "._make_manager()", "id": "tests_test_cache_testcachelrueviction_make_manager" }, @@ -53894,7 +54659,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L22", - "community": 135, + "community": 95, "norm_label": ".test_query_cache_starts_empty()", "id": "tests_test_cache_testcachelrueviction_test_query_cache_starts_empty" }, @@ -53903,7 +54668,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L26", - "community": 135, + "community": 95, "norm_label": ".test_query_cache_max_size_constant()", "id": "tests_test_cache_testcachelrueviction_test_query_cache_max_size_constant" }, @@ -53912,7 +54677,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L29", - "community": 135, + "community": 95, "norm_label": ".test_lru_eviction_when_over_limit()", "id": "tests_test_cache_testcachelrueviction_test_lru_eviction_when_over_limit" }, @@ -53921,7 +54686,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L50", - "community": 135, + "community": 95, "norm_label": ".test_move_to_end_on_cache_hit()", "id": "tests_test_cache_testcachelrueviction_test_move_to_end_on_cache_hit" }, @@ -53930,7 +54695,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L68", - "community": 135, + "community": 95, "norm_label": ".test_clear_query_cache()", "id": "tests_test_cache_testcachelrueviction_test_clear_query_cache" }, @@ -53939,7 +54704,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L77", - "community": 135, + "community": 95, "norm_label": ".test_none_columns_key_is_none()", "id": "tests_test_cache_testcachelrueviction_test_none_columns_key_is_none" }, @@ -53948,7 +54713,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L83", - "community": 135, + "community": 95, "norm_label": ".test_columns_key_is_tuple()", "id": "tests_test_cache_testcachelrueviction_test_columns_key_is_tuple" }, @@ -53993,7 +54758,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L107", - "community": 135, + "community": 95, "norm_label": "testcachettllogic", "id": "tests_test_cache_testcachettllogic" }, @@ -54002,7 +54767,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L108", - "community": 135, + "community": 95, "norm_label": "._make_manager()", "id": "tests_test_cache_testcachettllogic_make_manager" }, @@ -54011,7 +54776,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L112", - "community": 135, + "community": 95, "norm_label": ".test_expired_entry_detected()", "id": "tests_test_cache_testcachettllogic_test_expired_entry_detected" }, @@ -54020,7 +54785,7 @@ "file_type": "code", "source_file": "tests/test_cache.py", "source_location": "L123", - "community": 135, + "community": 95, "norm_label": ".test_fresh_entry_detected()", "id": "tests_test_cache_testcachettllogic_test_fresh_entry_detected" }, @@ -54029,7 +54794,7 @@ "file_type": "rationale", "source_file": "tests/test_cache.py", "source_location": "L15", - "community": 135, + "community": 95, "norm_label": "tests for stockscachemanager querycache lru eviction.", "id": "tests_test_cache_rationale_15" }, @@ -54038,7 +54803,7 @@ "file_type": "rationale", "source_file": "tests/test_cache.py", "source_location": "L18", - "community": 135, + "community": 95, "norm_label": "create a stockscachemanager with a mock db engine.", "id": "tests_test_cache_rationale_18" }, @@ -54047,7 +54812,7 @@ "file_type": "rationale", "source_file": "tests/test_cache.py", "source_location": "L78", - "community": 135, + "community": 95, "norm_label": "when columns is none, cache key should be none.", "id": "tests_test_cache_rationale_78" }, @@ -54218,7 +54983,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L496", - "community": 577, + "community": 605, "norm_label": "replacenan handles direct float nan values (line 34).", "id": "tests_test_stocks_api_coverage_rationale_496" }, @@ -54227,7 +54992,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L510", - "community": 566, + "community": 614, "norm_label": "non-json-dict/list string is left as-is.", "id": "tests_test_stocks_api_coverage_rationale_510" }, @@ -54245,7 +55010,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L528", - "community": 162, + "community": 511, "norm_label": "regression: is_string_dtype fails when column has strings + none (pandas 2.x).", "id": "tests_test_stocks_api_coverage_rationale_528" }, @@ -54263,7 +55028,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L575", - "community": 162, + "community": 511, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_575" }, @@ -54362,7 +55127,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L896", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_896" }, @@ -54371,7 +55136,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L905", - "community": 17, + "community": 39, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_905" }, @@ -54380,7 +55145,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L918", - "community": 17, + "community": 39, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_918" }, @@ -54407,7 +55172,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L959", - "community": 39, + "community": 17, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_959" }, @@ -54425,7 +55190,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L975", - "community": 17, + "community": 39, "norm_label": "len(daterange) == 1 -> per-ticker closest snapshot.", "id": "tests_test_stocks_api_coverage_rationale_975" }, @@ -54506,7 +55271,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1342", - "community": 22, + "community": 493, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1342" }, @@ -54641,7 +55406,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1344", - "community": 22, + "community": 493, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1344" }, @@ -54830,7 +55595,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1400", - "community": 22, + "community": 493, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1400" }, @@ -54983,7 +55748,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L495", - "community": 577, + "community": 605, "norm_label": "replacenan handles direct float nan values (line 34).", "id": "tests_test_stocks_api_coverage_rationale_495" }, @@ -54992,7 +55757,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L509", - "community": 566, + "community": 614, "norm_label": "non-json-dict/list string is left as-is.", "id": "tests_test_stocks_api_coverage_rationale_509" }, @@ -55010,7 +55775,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L527", - "community": 162, + "community": 511, "norm_label": "regression: is_string_dtype fails when column has strings + none (pandas 2.x).", "id": "tests_test_stocks_api_coverage_rationale_527" }, @@ -55028,7 +55793,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L574", - "community": 162, + "community": 511, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_574" }, @@ -55145,7 +55910,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L917", - "community": 17, + "community": 39, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_917" }, @@ -55163,7 +55928,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L956", - "community": 39, + "community": 17, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_956" }, @@ -55181,7 +55946,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L972", - "community": 17, + "community": 39, "norm_label": "len(daterange) == 1 -> single date filter.", "id": "tests_test_stocks_api_coverage_rationale_972" }, @@ -55262,7 +56027,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1396", - "community": 22, + "community": 493, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1396" }, @@ -55298,7 +56063,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1388", - "community": 22, + "community": 493, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1388" }, @@ -55433,7 +56198,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L907", - "community": 17, + "community": 39, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_907" }, @@ -55451,7 +56216,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L946", - "community": 39, + "community": 17, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_946" }, @@ -55469,7 +56234,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L962", - "community": 17, + "community": 39, "norm_label": "len(daterange) == 1 -> single date filter.", "id": "tests_test_stocks_api_coverage_rationale_962" }, @@ -56027,7 +56792,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L49", - "community": 517, + "community": 618, "norm_label": "filtercotationdata()", "id": "stocks_api_query_filtercotationdata" }, @@ -56117,7 +56882,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L45", - "community": 517, + "community": 618, "norm_label": "_parsecotationdate()", "id": "stocks_api_query_parsecotationdate" }, @@ -56126,7 +56891,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L55", - "community": 517, + "community": 618, "norm_label": "_filtercotationbydate()", "id": "stocks_api_query_filtercotationbydate" }, @@ -56135,7 +56900,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/query.py", "source_location": "L344", - "community": 63, + "community": 517, "norm_label": ".queryrealtimecotation()", "id": "stocks_api_query_stocksquerymanager_queryrealtimecotation" }, @@ -56144,7 +56909,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/query.py", "source_location": "L46", - "community": 517, + "community": 618, "norm_label": "parse dd-mm-yyyy from cotacao 10y json data field. ponytail: stdlib datetime onl", "id": "stocks_api_query_rationale_46" }, @@ -56153,7 +56918,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/query.py", "source_location": "L56", - "community": 517, + "community": 618, "norm_label": "filter cotacao 10y json entries by their inner data field (dd-mm-yyyy).", "id": "stocks_api_query_rationale_56" }, @@ -56162,7 +56927,7 @@ "file_type": "rationale", "source_file": "main/app/stocks_api/query.py", "source_location": "L345", - "community": 63, + "community": 517, "norm_label": "fetch live prices for b3 tickers via yfinance. b3 tickers must match", "id": "stocks_api_query_rationale_345" }, @@ -56171,7 +56936,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L63", - "community": 560, + "community": 186, "norm_label": "getrealtimecotation()", "id": "controller_stocksapi_controller_getrealtimecotation" }, @@ -56225,7 +56990,7 @@ "file_type": "code", "source_file": "main/app/prometheus/generation.py", "source_location": "L19", - "community": 29, + "community": 566, "norm_label": "sessionproxy", "id": "prometheus_generation_sessionproxy" }, @@ -56243,7 +57008,7 @@ "file_type": "code", "source_file": "main/app/prometheus/generation.py", "source_location": "L23", - "community": 29, + "community": 566, "norm_label": ".post()", "id": "prometheus_generation_sessionproxy_post" }, @@ -56279,7 +57044,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L23", - "community": 560, + "community": 186, "norm_label": "apikeytest()", "id": "controller_stocksapi_controller_apikeytest" }, @@ -56333,7 +57098,7 @@ "file_type": "code", "source_file": "main/utils/http_session.py", "source_location": "L18", - "community": 627, + "community": 603, "norm_label": "cleanup()", "id": "utils_http_session_cleanup" }, @@ -56342,7 +57107,7 @@ "file_type": "code", "source_file": "main/utils/pagination.py", "source_location": "L1", - "community": 186, + "community": 528, "norm_label": "pagination.py", "id": "main_utils_pagination_py" }, @@ -56351,7 +57116,7 @@ "file_type": "code", "source_file": "main/utils/pagination.py", "source_location": "L4", - "community": 186, + "community": 528, "norm_label": "paginationparams", "id": "utils_pagination_paginationparams" }, @@ -56360,7 +57125,7 @@ "file_type": "code", "source_file": "main/utils/pagination.py", "source_location": "L5", - "community": 186, + "community": 528, "norm_label": ".__init__()", "id": "utils_pagination_paginationparams_init" }, @@ -56459,7 +57224,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L166", - "community": 26, + "community": 589, "norm_label": "test that invalid api key returns zero rows affected.", "id": "tests_test_api_key_quota_atomic_rationale_166" }, @@ -56468,7 +57233,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L180", - "community": 26, + "community": 589, "norm_label": "test that multiple api keys have independent quotas.", "id": "tests_test_api_key_quota_atomic_rationale_180" }, @@ -56630,7 +57395,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L228", - "community": 120, + "community": 45, "norm_label": "covers lines 87-93, 102: login success and failure paths.", "id": "tests_test_controllers_coverage_rationale_228" }, @@ -56828,7 +57593,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L708", - "community": 107, + "community": 63, "norm_label": "covers lines 100-104, 106: get /user/sessions/current.", "id": "tests_test_controllers_coverage_rationale_708" }, @@ -56837,7 +57602,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L711", - "community": 107, + "community": 63, "norm_label": "covers lines 100-104, 106: session found.", "id": "tests_test_controllers_coverage_rationale_711" }, @@ -56846,7 +57611,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L744", - "community": 107, + "community": 63, "norm_label": "covers line 104: session not found.", "id": "tests_test_controllers_coverage_rationale_744" }, @@ -56909,7 +57674,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L875", - "community": 626, + "community": 45, "norm_label": "covers line 24: get /prometheus/health.", "id": "tests_test_controllers_coverage_rationale_875" }, @@ -57053,7 +57818,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1123", - "community": 498, + "community": 148, "norm_label": "covers lines 114-115: session ownership check fails.", "id": "tests_test_controllers_coverage_rationale_1123" }, @@ -57062,7 +57827,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1160", - "community": 148, + "community": 99, "norm_label": "covers line 125, 126-128: generic exception in chat.", "id": "tests_test_controllers_coverage_rationale_1160" }, @@ -57071,7 +57836,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1181", - "community": 604, + "community": 45, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1181" }, @@ -57098,7 +57863,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1220", - "community": 605, + "community": 14, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1220" }, @@ -57134,7 +57899,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1280", - "community": 623, + "community": 529, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1280" }, @@ -57152,7 +57917,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1356", - "community": 568, + "community": 529, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1356" }, @@ -57161,7 +57926,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1406", - "community": 617, + "community": 563, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1406" }, @@ -57170,7 +57935,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1430", - "community": 45, + "community": 194, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1430" }, @@ -57179,7 +57944,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1440", - "community": 546, + "community": 194, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1440" }, @@ -57188,7 +57953,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1443", - "community": 546, + "community": 194, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1443" }, @@ -57197,7 +57962,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1459", - "community": 592, + "community": 194, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1459" }, @@ -57233,7 +57998,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L9", - "community": 610, + "community": 590, "norm_label": ".test_creates_new_session()", "id": "tests_test_http_session_coverage_testgetsession_test_creates_new_session" }, @@ -57242,7 +58007,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L28", - "community": 627, + "community": 603, "norm_label": "testcleanup", "id": "tests_test_http_session_coverage_testcleanup" }, @@ -57251,7 +58016,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L29", - "community": 627, + "community": 603, "norm_label": ".test_cleanup_closes_session()", "id": "tests_test_http_session_coverage_testcleanup_test_cleanup_closes_session" }, @@ -57260,7 +58025,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L37", - "community": 627, + "community": 603, "norm_label": ".test_cleanup_no_session()", "id": "tests_test_http_session_coverage_testcleanup_test_cleanup_no_session" }, @@ -57269,7 +58034,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L46", - "community": 627, + "community": 603, "norm_label": ".test_cleanup_exception_during_close()", "id": "tests_test_http_session_coverage_testcleanup_test_cleanup_exception_during_close" }, @@ -57296,7 +58061,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L37", - "community": 186, + "community": 502, "norm_label": "testpaginationparams", "id": "tests_test_pagination_testpaginationparams" }, @@ -57305,7 +58070,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L38", - "community": 186, + "community": 502, "norm_label": ".test_defaults()", "id": "tests_test_pagination_testpaginationparams_test_defaults" }, @@ -57314,7 +58079,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L46", - "community": 186, + "community": 502, "norm_label": ".test_custom_limit()", "id": "tests_test_pagination_testpaginationparams_test_custom_limit" }, @@ -57323,7 +58088,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L52", - "community": 186, + "community": 502, "norm_label": ".test_custom_offset()", "id": "tests_test_pagination_testpaginationparams_test_custom_offset" }, @@ -57332,7 +58097,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L59", - "community": 186, + "community": 502, "norm_label": ".test_limit_and_offset()", "id": "tests_test_pagination_testpaginationparams_test_limit_and_offset" }, @@ -57341,7 +58106,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L67", - "community": 186, + "community": 502, "norm_label": ".test_limit_exceeds_max_rejected()", "id": "tests_test_pagination_testpaginationparams_test_limit_exceeds_max_rejected" }, @@ -57350,7 +58115,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L71", - "community": 186, + "community": 502, "norm_label": ".test_limit_zero_rejected()", "id": "tests_test_pagination_testpaginationparams_test_limit_zero_rejected" }, @@ -57359,7 +58124,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L75", - "community": 186, + "community": 502, "norm_label": ".test_negative_offset_rejected()", "id": "tests_test_pagination_testpaginationparams_test_negative_offset_rejected" }, @@ -57368,7 +58133,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L79", - "community": 186, + "community": 502, "norm_label": ".test_offset_beyond_total()", "id": "tests_test_pagination_testpaginationparams_test_offset_beyond_total" }, @@ -57377,7 +58142,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L84", - "community": 186, + "community": 502, "norm_label": ".test_limit_equals_max()", "id": "tests_test_pagination_testpaginationparams_test_limit_equals_max" }, @@ -57800,7 +58565,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L494", - "community": 577, + "community": 605, "norm_label": "replacenan handles direct float nan values (line 34).", "id": "tests_test_stocks_api_coverage_rationale_494" }, @@ -57809,7 +58574,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L508", - "community": 566, + "community": 614, "norm_label": "non-json-dict/list string is left as-is.", "id": "tests_test_stocks_api_coverage_rationale_508" }, @@ -57827,7 +58592,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L526", - "community": 162, + "community": 511, "norm_label": "regression: is_string_dtype fails when column has strings + none (pandas 2.x).", "id": "tests_test_stocks_api_coverage_rationale_526" }, @@ -57845,7 +58610,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L573", - "community": 162, + "community": 511, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_573" }, @@ -57953,7 +58718,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L906", - "community": 17, + "community": 39, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_906" }, @@ -57980,7 +58745,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L945", - "community": 39, + "community": 17, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_945" }, @@ -57998,7 +58763,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L961", - "community": 17, + "community": 39, "norm_label": "len(daterange) == 1 -> single date filter.", "id": "tests_test_stocks_api_coverage_rationale_961" }, @@ -58214,7 +58979,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L898", - "community": 17, + "community": 39, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_898" }, @@ -58241,7 +59006,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L937", - "community": 39, + "community": 17, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_937" }, @@ -58313,7 +59078,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L935", - "community": 39, + "community": 17, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_935" }, @@ -58331,7 +59096,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L951", - "community": 17, + "community": 39, "norm_label": "len(daterange) == 1 -> single date filter.", "id": "tests_test_stocks_api_coverage_rationale_951" }, @@ -58340,7 +59105,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/generation.py", "source_location": "L20", - "community": 29, + "community": 566, "norm_label": "thread-safe proxy that delegates to per-thread sessions.", "id": "prometheus_generation_rationale_20" }, @@ -58448,7 +59213,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L850", - "community": 17, + "community": 39, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_850" }, @@ -58466,7 +59231,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L889", - "community": 39, + "community": 17, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_889" }, @@ -58484,7 +59249,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L8", - "community": 621, + "community": 629, "norm_label": "checkmysqlconnection \u2014 success, errors, engine=none paths.", "id": "tests_test_connectivity_coverage_rationale_8" }, @@ -58493,7 +59258,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L105", - "community": 618, + "community": 625, "norm_label": "checkserviceconnection \u2014 success, not found, errors.", "id": "tests_test_connectivity_coverage_rationale_105" }, @@ -58610,7 +59375,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L851", - "community": 17, + "community": 39, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_851" }, @@ -58637,7 +59402,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L890", - "community": 39, + "community": 17, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_890" }, @@ -58700,7 +59465,7 @@ "file_type": "code", "source_file": "main/utils/errors.py", "source_location": "L65", - "community": 498, + "community": 120, "norm_label": "register_error_handlers()", "id": "utils_errors_register_error_handlers" }, @@ -58727,7 +59492,7 @@ "file_type": "rationale", "source_file": "main/utils/http_session.py", "source_location": "L23", - "community": 627, + "community": 603, "norm_label": "close the main thread's session at interpreter shutdown.", "id": "utils_http_session_rationale_23" }, @@ -59159,7 +59924,7 @@ "file_type": "code", "source_file": "main/service/user_service.py", "source_location": "L35", - "community": 536, + "community": 628, "norm_label": "inactivesessionsscheduler()", "id": "service_user_service_inactivesessionsscheduler" }, @@ -59510,7 +60275,7 @@ "file_type": "rationale", "source_file": "main/utils/errors.py", "source_location": "L68", - "community": 498, + "community": 120, "norm_label": "register exception handlers on the fastapi app. note: httpexception and r", "id": "utils_errors_rationale_68" }, @@ -59600,7 +60365,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L489", - "community": 577, + "community": 605, "norm_label": "replacenan handles direct float nan values (line 34).", "id": "tests_test_stocks_api_coverage_rationale_489" }, @@ -59609,7 +60374,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L503", - "community": 566, + "community": 614, "norm_label": "non-json-dict/list string is left as-is.", "id": "tests_test_stocks_api_coverage_rationale_503" }, @@ -59627,7 +60392,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L522", - "community": 162, + "community": 511, "norm_label": "tests covering query.py lines 50-67.", "id": "tests_test_stocks_api_coverage_rationale_522" }, @@ -59726,7 +60491,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L845", - "community": 17, + "community": 39, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_845" }, @@ -59762,7 +60527,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L900", - "community": 17, + "community": 39, "norm_label": "len(daterange) == 1 -> single date filter.", "id": "tests_test_stocks_api_coverage_rationale_900" }, @@ -60167,7 +60932,7 @@ "file_type": "rationale", "source_file": "main/utils/errors.py", "source_location": "L67", - "community": 498, + "community": 120, "norm_label": "register exception handlers on the fastapi app. note: httpexception and r", "id": "utils_errors_rationale_67" }, @@ -60338,7 +61103,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L135", - "community": 572, + "community": 613, "norm_label": "testqueryoptimization", "id": "tests_test_stocks_cache_testqueryoptimization" }, @@ -60347,7 +61112,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L138", - "community": 572, + "community": 613, "norm_label": ".test_all_optimizations_present()", "id": "tests_test_stocks_cache_testqueryoptimization_test_all_optimizations_present" }, @@ -60356,7 +61121,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L153", - "community": 572, + "community": 613, "norm_label": ".test_query_filter_uses_optimization()", "id": "tests_test_stocks_cache_testqueryoptimization_test_query_filter_uses_optimization" }, @@ -60428,7 +61193,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L299", - "community": 613, + "community": 588, "norm_label": "testfilterbysearchterms", "id": "tests_test_stocks_cache_testfilterbysearchterms" }, @@ -60437,7 +61202,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L302", - "community": 613, + "community": 588, "norm_label": ".test_filter_with_tickerindex()", "id": "tests_test_stocks_cache_testfilterbysearchterms_test_filter_with_tickerindex" }, @@ -60608,7 +61373,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L136", - "community": 572, + "community": 613, "norm_label": "integration tests for all query optimizations", "id": "tests_test_stocks_cache_rationale_136" }, @@ -60617,7 +61382,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L139", - "community": 572, + "community": 613, "norm_label": "all optimizations should be implemented", "id": "tests_test_stocks_cache_rationale_139" }, @@ -60626,7 +61391,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L154", - "community": 572, + "community": 613, "norm_label": "query filter should use ticker index", "id": "tests_test_stocks_cache_rationale_154" }, @@ -60698,7 +61463,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L300", - "community": 613, + "community": 588, "norm_label": "tests for optimized search filtering", "id": "tests_test_stocks_cache_rationale_300" }, @@ -60707,7 +61472,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L303", - "community": 613, + "community": 588, "norm_label": "filter should use ticker index for o(1) lookup", "id": "tests_test_stocks_cache_rationale_303" }, @@ -60896,7 +61661,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L138", - "community": 572, + "community": 613, "norm_label": "integration tests for all query optimizations", "id": "tests_test_stocks_cache_rationale_138" }, @@ -60905,7 +61670,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L141", - "community": 572, + "community": 613, "norm_label": "all optimizations should be implemented", "id": "tests_test_stocks_cache_rationale_141" }, @@ -60914,7 +61679,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L156", - "community": 572, + "community": 613, "norm_label": "query filter should use ticker index", "id": "tests_test_stocks_cache_rationale_156" }, @@ -60986,7 +61751,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L302", - "community": 613, + "community": 588, "norm_label": "tests for optimized search filtering", "id": "tests_test_stocks_cache_rationale_302" }, @@ -60995,7 +61760,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L305", - "community": 613, + "community": 588, "norm_label": "filter should use ticker index for o(1) lookup", "id": "tests_test_stocks_cache_rationale_305" }, @@ -61085,7 +61850,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L304", - "community": 613, + "community": 588, "norm_label": ".test_filter_with_tickerindex()", "id": "tests_test_stocks_cache_testfilterbysearchterms_test_filter_with_tickerIndex" }, @@ -61103,7 +61868,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L17", - "community": 42, + "community": 497, "norm_label": "testtickerindex", "id": "tests_test_stocks_optimization_testtickerindex" }, @@ -61112,7 +61877,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L20", - "community": 42, + "community": 497, "norm_label": ".test_tickerindex_built_after_cache_load()", "id": "tests_test_stocks_optimization_testtickerindex_test_tickerIndex_built_after_cache_load" }, @@ -61121,7 +61886,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L28", - "community": 42, + "community": 497, "norm_label": ".test_tickerindex_contains_all_tickers()", "id": "tests_test_stocks_optimization_testtickerindex_test_tickerIndex_contains_all_tickers" }, @@ -61130,7 +61895,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L38", - "community": 42, + "community": 497, "norm_label": ".test_tickerindex_case_insensitive()", "id": "tests_test_stocks_optimization_testtickerindex_test_tickerIndex_case_insensitive" }, @@ -61139,7 +61904,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L47", - "community": 42, + "community": 497, "norm_label": ".test_ticker_lookup_returns_valid_index()", "id": "tests_test_stocks_optimization_testtickerindex_test_ticker_lookup_returns_valid_index" }, @@ -61148,7 +61913,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L58", - "community": 42, + "community": 497, "norm_label": ".test_tickerindex_rebuilt_on_cache_refresh()", "id": "tests_test_stocks_optimization_testtickerindex_test_tickerIndex_rebuilt_on_cache_refresh" }, @@ -61157,7 +61922,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L72", - "community": 101, + "community": 586, "norm_label": "testquerycaching", "id": "tests_test_stocks_optimization_testquerycaching" }, @@ -61166,7 +61931,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L75", - "community": 101, + "community": 586, "norm_label": ".test_cache_manager_has_caches_method()", "id": "tests_test_stocks_optimization_testquerycaching_test_cache_manager_has_caches_method" }, @@ -61175,7 +61940,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L83", - "community": 101, + "community": 586, "norm_label": ".test_querycache_ttl_configuration()", "id": "tests_test_stocks_optimization_testquerycaching_test_queryCache_ttl_configuration" }, @@ -61184,7 +61949,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L91", - "community": 101, + "community": 586, "norm_label": ".test_get_cached_stocks_respects_columns_parameter()", "id": "tests_test_stocks_optimization_testquerycaching_test_get_cached_stocks_respects_columns_parameter" }, @@ -61193,7 +61958,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L101", - "community": 101, + "community": 586, "norm_label": ".test_different_queries_not_cached()", "id": "tests_test_stocks_optimization_testquerycaching_test_different_queries_not_cached" }, @@ -61202,7 +61967,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L105", - "community": 101, + "community": 586, "norm_label": ".test_cache_expiry_after_ttl()", "id": "tests_test_stocks_optimization_testquerycaching_test_cache_expiry_after_ttl" }, @@ -61229,7 +61994,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L123", - "community": 63, + "community": 586, "norm_label": "testlazydeserialization", "id": "tests_test_stocks_optimization_testlazydeserialization" }, @@ -61238,7 +62003,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L126", - "community": 63, + "community": 586, "norm_label": ".test_query_manager_has_deserialize_method()", "id": "tests_test_stocks_optimization_testlazydeserialization_test_query_manager_has_deserialize_method" }, @@ -61247,7 +62012,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L137", - "community": 586, + "community": 592, "norm_label": "testqueryoptimization", "id": "tests_test_stocks_optimization_testqueryoptimization" }, @@ -61256,7 +62021,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L140", - "community": 586, + "community": 592, "norm_label": ".test_all_optimizations_present()", "id": "tests_test_stocks_optimization_testqueryoptimization_test_all_optimizations_present" }, @@ -61265,7 +62030,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L155", - "community": 586, + "community": 592, "norm_label": ".test_query_filter_uses_optimization()", "id": "tests_test_stocks_optimization_testqueryoptimization_test_query_filter_uses_optimization" }, @@ -61355,7 +62120,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L310", - "community": 586, + "community": 610, "norm_label": "testqueryperformance", "id": "tests_test_stocks_optimization_testqueryperformance" }, @@ -61364,7 +62129,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L313", - "community": 586, + "community": 610, "norm_label": ".test_query_response_time_under_1_second()", "id": "tests_test_stocks_optimization_testqueryperformance_test_query_response_time_under_1_second" }, @@ -61373,7 +62138,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L18", - "community": 42, + "community": 497, "norm_label": "tests for dynamic ticker index feature", "id": "tests_test_stocks_optimization_rationale_18" }, @@ -61382,7 +62147,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L21", - "community": 42, + "community": 497, "norm_label": "ticker index should be built when cache is loaded", "id": "tests_test_stocks_optimization_rationale_21" }, @@ -61391,7 +62156,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L29", - "community": 42, + "community": 497, "norm_label": "ticker index should contain all tickers from cache", "id": "tests_test_stocks_optimization_rationale_29" }, @@ -61400,7 +62165,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L39", - "community": 42, + "community": 497, "norm_label": "ticker index should be case-insensitive", "id": "tests_test_stocks_optimization_rationale_39" }, @@ -61409,7 +62174,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L48", - "community": 42, + "community": 497, "norm_label": "looking up ticker should return valid row index", "id": "tests_test_stocks_optimization_rationale_48" }, @@ -61418,7 +62183,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L59", - "community": 42, + "community": 497, "norm_label": "ticker index should be rebuilt when cache refreshes", "id": "tests_test_stocks_optimization_rationale_59" }, @@ -61427,7 +62192,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L73", - "community": 101, + "community": 586, "norm_label": "tests for query result caching", "id": "tests_test_stocks_optimization_rationale_73" }, @@ -61436,7 +62201,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L76", - "community": 101, + "community": 586, "norm_label": "cachemanager should track cached queries", "id": "tests_test_stocks_optimization_rationale_76" }, @@ -61445,7 +62210,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L84", - "community": 101, + "community": 586, "norm_label": "query cache should have configurable ttl", "id": "tests_test_stocks_optimization_rationale_84" }, @@ -61454,7 +62219,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L92", - "community": 101, + "community": 586, "norm_label": "getcachedstocks should support column filtering", "id": "tests_test_stocks_optimization_rationale_92" }, @@ -61463,7 +62228,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L102", - "community": 101, + "community": 586, "norm_label": "different query parameters should not share cache", "id": "tests_test_stocks_optimization_rationale_102" }, @@ -61472,7 +62237,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L106", - "community": 101, + "community": 586, "norm_label": "cache should expire after ttl", "id": "tests_test_stocks_optimization_rationale_106" }, @@ -61499,7 +62264,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L124", - "community": 63, + "community": 586, "norm_label": "tests for lazy json deserialization", "id": "tests_test_stocks_optimization_rationale_124" }, @@ -61508,7 +62273,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L127", - "community": 63, + "community": 586, "norm_label": "query manager should have deserialize method", "id": "tests_test_stocks_optimization_rationale_127" }, @@ -61517,7 +62282,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L138", - "community": 586, + "community": 592, "norm_label": "integration tests for all query optimizations", "id": "tests_test_stocks_optimization_rationale_138" }, @@ -61526,7 +62291,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L141", - "community": 586, + "community": 592, "norm_label": "all optimizations should be implemented", "id": "tests_test_stocks_optimization_rationale_141" }, @@ -61535,7 +62300,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L156", - "community": 586, + "community": 592, "norm_label": "query filter should use ticker index", "id": "tests_test_stocks_optimization_rationale_156" }, @@ -61625,7 +62390,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L311", - "community": 586, + "community": 610, "norm_label": "performance tests for query operations", "id": "tests_test_stocks_optimization_rationale_311" }, @@ -61634,7 +62399,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L314", - "community": 586, + "community": 610, "norm_label": "query should respond within 1 second", "id": "tests_test_stocks_optimization_rationale_314" }, @@ -61670,7 +62435,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L182", - "community": 586, + "community": 610, "norm_label": "performance tests for query operations", "id": "tests_test_stocks_optimization_rationale_182" }, @@ -61679,7 +62444,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L185", - "community": 586, + "community": 610, "norm_label": "query should respond within 1 second", "id": "tests_test_stocks_optimization_rationale_185" }, @@ -61962,7 +62727,7 @@ "label": "FastAPI", "file_type": "rationale", "source_file": "README.md", - "community": 152, + "community": 528, "norm_label": "fastapi", "id": "fastapi" }, @@ -62002,7 +62767,7 @@ "label": "Authentication System", "file_type": "document", "source_file": "docs/authentication.md", - "community": 538, + "community": 107, "norm_label": "authentication system", "id": "authentication" }, @@ -62010,7 +62775,7 @@ "label": "JWT Authentication", "file_type": "rationale", "source_file": "docs/authentication.md", - "community": 538, + "community": 107, "norm_label": "jwt authentication", "id": "jwt" }, @@ -62018,7 +62783,7 @@ "label": "Google OAuth", "file_type": "rationale", "source_file": "docs/authentication.md", - "community": 538, + "community": 107, "norm_label": "google oauth", "id": "google_oauth" }, @@ -62106,7 +62871,7 @@ "label": "Pytest Testing", "file_type": "rationale", "source_file": "pyproject.toml", - "community": 491, + "community": 577, "norm_label": "pytest testing", "id": "pytest" }, @@ -62730,6 +63495,26 @@ "source": "server_config_config", "target": "scraper_b3_scraper_b3scraper" }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L9", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_market_data_marketdatamanager", + "target": "server_config_config" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/positions.py", + "source_location": "L8", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_positions_positionsmanager", + "target": "server_config_config" + }, { "relation": "uses", "confidence": "INFERRED", @@ -68467,6 +69252,17 @@ "source": "orunmila_agent_orunmila_streammessage", "target": "orunmila_memory_extract" }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/agent.py", + "source_location": "L370", + "weight": 1.0, + "source": "orunmila_agent_orunmila_streammessage", + "target": "tools_init_dispatchtoolcall" + }, { "relation": "calls", "context": "call", @@ -70304,10 +71100,10 @@ "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "main/app/orunmila/tools.py", - "source_location": "L169", + "source_file": "main/controller/orunmila_controller.py", + "source_location": "L185", "weight": 1.0, - "source": "orunmila_tools_serve_file", + "source": "controller_orunmila_controller_downloadworkspacefile", "target": "orunmila_sandbox_hostpath" }, { @@ -70315,10 +71111,10 @@ "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "main/controller/orunmila_controller.py", - "source_location": "L185", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L169", "weight": 1.0, - "source": "controller_orunmila_controller_downloadworkspacefile", + "source": "orunmila_tools_serve_file", "target": "orunmila_sandbox_hostpath" }, { @@ -70648,367 +71444,6 @@ "source": "orunmila_stream_bus_streambus_streamresponse", "target": "orunmila_stream_bus_streambus_eventgenerator" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L7", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_orunmila_tools_py", - "target": "fastapi" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L20", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_orunmila_tools_py", - "target": "orunmila_tools_search_memory" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L51", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_orunmila_tools_py", - "target": "orunmila_tools_save_memory" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L93", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_orunmila_tools_py", - "target": "orunmila_tools_execute_code" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L114", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_orunmila_tools_py", - "target": "orunmila_tools_read_file" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L128", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_orunmila_tools_py", - "target": "orunmila_tools_write_file" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L144", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_orunmila_tools_py", - "target": "orunmila_tools_list_files" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L157", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_orunmila_tools_py", - "target": "orunmila_tools_serve_file" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L183", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_orunmila_tools_py", - "target": "orunmila_tools_narrate_positions" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L190", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_orunmila_tools_py", - "target": "orunmila_tools_dispatchtoolcall" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L22", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_22", - "target": "orunmila_tools_search_memory" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L21", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_21", - "target": "orunmila_tools_search_memory" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L53", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_53", - "target": "orunmila_tools_save_memory" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/orunmila/tools.py", - "source_location": "L70", - "weight": 1.0, - "source": "orunmila_tools_save_memory", - "target": "orunmila_vector_embed" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L52", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_52", - "target": "orunmila_tools_save_memory" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L95", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_95", - "target": "orunmila_tools_execute_code" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L94", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_94", - "target": "orunmila_tools_execute_code" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L116", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_116", - "target": "orunmila_tools_read_file" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L115", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_115", - "target": "orunmila_tools_read_file" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L130", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_130", - "target": "orunmila_tools_write_file" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L129", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_129", - "target": "orunmila_tools_write_file" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L146", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_146", - "target": "orunmila_tools_list_files" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L145", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_145", - "target": "orunmila_tools_list_files" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L159", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_159", - "target": "orunmila_tools_serve_file" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L158", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_158", - "target": "orunmila_tools_serve_file" - }, - { - "relation": "rationale_for", - "confidence": "EXTRACTED", - "source_file": "main/app/orunmila/tools.py", - "source_location": "L184", - "weight": 1.0, - "confidence_score": 1.0, - "source": "orunmila_tools_rationale_184", - "target": "orunmila_tools_narrate_positions" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/orunmila/tools.py", - "source_location": "L208", - "weight": 1.0, - "source": "orunmila_tools_narrate_positions", - "target": "wallet_wallets_getwallet" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/orunmila/tools.py", - "source_location": "L212", - "weight": 1.0, - "source": "orunmila_tools_narrate_positions", - "target": "wallet_positions_getpositions" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/orunmila/tools.py", - "source_location": "L217", - "weight": 1.0, - "source": "orunmila_tools_narrate_positions", - "target": "wallet_summary_getsummary" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/orunmila/tools.py", - "source_location": "L224", - "weight": 1.0, - "source": "orunmila_tools_narrate_positions", - "target": "wallet_earnings_listearnings" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/orunmila/tools.py", - "source_location": "L205", - "weight": 1.0, - "source": "orunmila_tools_narrate_positions", - "target": "wallet_wallets_getownedwallet" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/orunmila/tools.py", - "source_location": "L205", - "weight": 1.0, - "source": "orunmila_tools_narrate_positions", - "target": "wallet_wallet_service_getownedwallet" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/orunmila/tools.py", - "source_location": "L212", - "weight": 1.0, - "source": "orunmila_tools_narrate_positions", - "target": "wallet_wallet_service_getpositions" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/orunmila/tools.py", - "source_location": "L217", - "weight": 1.0, - "source": "orunmila_tools_narrate_positions", - "target": "wallet_wallet_service_getsummary" - }, - { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/orunmila/tools.py", - "source_location": "L224", - "weight": 1.0, - "source": "orunmila_tools_narrate_positions", - "target": "wallet_wallet_service_listearnings" - }, { "relation": "contains", "confidence": "EXTRACTED", @@ -71111,6 +71546,580 @@ "source": "orunmila_vector_embed", "target": "models_loader_getembeddingmodel" }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L70", + "weight": 1.0, + "source": "orunmila_tools_save_memory", + "target": "orunmila_vector_embed" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/context.py", + "source_location": "L7", + "weight": 1.0, + "source": "main_app_orunmila_tools_context_py", + "target": "tools_context_popauthsession", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/context.py", + "source_location": "L24", + "weight": 1.0, + "source": "main_app_orunmila_tools_context_py", + "target": "tools_context_closeownsession", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/context.py", + "source_location": "L8", + "weight": 1.0, + "source": "tools_context_rationale_8", + "target": "tools_context_popauthsession", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L16", + "weight": 1.0, + "source": "tools_memory_search_memory", + "target": "tools_context_popauthsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L42", + "weight": 1.0, + "source": "tools_memory_save_memory", + "target": "tools_context_popauthsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L35", + "weight": 1.0, + "source": "tools_wallet_get_wallet_positions", + "target": "tools_context_popauthsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L60", + "weight": 1.0, + "source": "tools_wallet_get_wallet_summary", + "target": "tools_context_popauthsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L86", + "weight": 1.0, + "source": "tools_wallet_get_wallet_allocation", + "target": "tools_context_popauthsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L113", + "weight": 1.0, + "source": "tools_wallet_list_wallet_earnings", + "target": "tools_context_popauthsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L161", + "weight": 1.0, + "source": "tools_wallet_get_wallet_performance", + "target": "tools_context_popauthsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L195", + "weight": 1.0, + "source": "tools_wallet_get_wallet_rebalance", + "target": "tools_context_popauthsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L29", + "weight": 1.0, + "source": "tools_memory_search_memory", + "target": "tools_context_closeownsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L62", + "weight": 1.0, + "source": "tools_memory_save_memory", + "target": "tools_context_closeownsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L49", + "weight": 1.0, + "source": "tools_wallet_get_wallet_positions", + "target": "tools_context_closeownsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L74", + "weight": 1.0, + "source": "tools_wallet_get_wallet_summary", + "target": "tools_context_closeownsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L101", + "weight": 1.0, + "source": "tools_wallet_get_wallet_allocation", + "target": "tools_context_closeownsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L145", + "weight": 1.0, + "source": "tools_wallet_list_wallet_earnings", + "target": "tools_context_closeownsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L184", + "weight": 1.0, + "source": "tools_wallet_get_wallet_performance", + "target": "tools_context_closeownsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L209", + "weight": 1.0, + "source": "tools_wallet_get_wallet_rebalance", + "target": "tools_context_closeownsession" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L7", + "weight": 1.0, + "source": "main_app_orunmila_tools_memory_py", + "target": "tools_memory_search_memory", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L32", + "weight": 1.0, + "source": "main_app_orunmila_tools_memory_py", + "target": "tools_memory_save_memory", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L8", + "weight": 1.0, + "source": "tools_memory_rationale_8", + "target": "tools_memory_search_memory", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L33", + "weight": 1.0, + "source": "tools_memory_rationale_33", + "target": "tools_memory_save_memory", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L11", + "weight": 1.0, + "source": "main_app_orunmila_tools_sandbox_py", + "target": "tools_sandbox_execute_code", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L32", + "weight": 1.0, + "source": "main_app_orunmila_tools_sandbox_py", + "target": "tools_sandbox_read_file", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L46", + "weight": 1.0, + "source": "main_app_orunmila_tools_sandbox_py", + "target": "tools_sandbox_write_file", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L62", + "weight": 1.0, + "source": "main_app_orunmila_tools_sandbox_py", + "target": "tools_sandbox_list_files", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L75", + "weight": 1.0, + "source": "main_app_orunmila_tools_sandbox_py", + "target": "tools_sandbox_serve_file", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L12", + "weight": 1.0, + "source": "tools_sandbox_rationale_12", + "target": "tools_sandbox_execute_code", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L33", + "weight": 1.0, + "source": "tools_sandbox_rationale_33", + "target": "tools_sandbox_read_file", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L47", + "weight": 1.0, + "source": "tools_sandbox_rationale_47", + "target": "tools_sandbox_write_file", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L63", + "weight": 1.0, + "source": "tools_sandbox_rationale_63", + "target": "tools_sandbox_list_files", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L76", + "weight": 1.0, + "source": "tools_sandbox_rationale_76", + "target": "tools_sandbox_serve_file", + "confidence_score": 1.0 + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L4", + "weight": 1.0, + "source": "main_app_orunmila_tools_wallet_py", + "target": "fastapi", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L15", + "weight": 1.0, + "source": "main_app_orunmila_tools_wallet_py", + "target": "tools_wallet_ensureownership", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L27", + "weight": 1.0, + "source": "main_app_orunmila_tools_wallet_py", + "target": "tools_wallet_get_wallet_positions", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L52", + "weight": 1.0, + "source": "main_app_orunmila_tools_wallet_py", + "target": "tools_wallet_get_wallet_summary", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L77", + "weight": 1.0, + "source": "main_app_orunmila_tools_wallet_py", + "target": "tools_wallet_get_wallet_allocation", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L104", + "weight": 1.0, + "source": "main_app_orunmila_tools_wallet_py", + "target": "tools_wallet_list_wallet_earnings", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L148", + "weight": 1.0, + "source": "main_app_orunmila_tools_wallet_py", + "target": "tools_wallet_get_wallet_performance", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L187", + "weight": 1.0, + "source": "main_app_orunmila_tools_wallet_py", + "target": "tools_wallet_get_wallet_rebalance", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L40", + "weight": 1.0, + "source": "tools_wallet_get_wallet_positions", + "target": "tools_wallet_ensureownership", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L65", + "weight": 1.0, + "source": "tools_wallet_get_wallet_summary", + "target": "tools_wallet_ensureownership", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L91", + "weight": 1.0, + "source": "tools_wallet_get_wallet_allocation", + "target": "tools_wallet_ensureownership", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L118", + "weight": 1.0, + "source": "tools_wallet_list_wallet_earnings", + "target": "tools_wallet_ensureownership", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L172", + "weight": 1.0, + "source": "tools_wallet_get_wallet_performance", + "target": "tools_wallet_ensureownership", + "confidence_score": 1.0 + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L200", + "weight": 1.0, + "source": "tools_wallet_get_wallet_rebalance", + "target": "tools_wallet_ensureownership", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L28", + "weight": 1.0, + "source": "tools_wallet_rationale_28", + "target": "tools_wallet_get_wallet_positions", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L53", + "weight": 1.0, + "source": "tools_wallet_rationale_53", + "target": "tools_wallet_get_wallet_summary", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L78", + "weight": 1.0, + "source": "tools_wallet_rationale_78", + "target": "tools_wallet_get_wallet_allocation", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L105", + "weight": 1.0, + "source": "tools_wallet_rationale_105", + "target": "tools_wallet_list_wallet_earnings", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L151", + "weight": 1.0, + "source": "tools_wallet_rationale_151", + "target": "tools_wallet_get_wallet_performance", + "confidence_score": 1.0 + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L188", + "weight": 1.0, + "source": "tools_wallet_rationale_188", + "target": "tools_wallet_get_wallet_rebalance", + "confidence_score": 1.0 + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/__init__.py", + "source_location": "L39", + "weight": 1.0, + "source": "main_app_orunmila_tools_init_py", + "target": "tools_init_dispatchtoolcall", + "confidence_score": 1.0 + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -75440,6 +76449,16 @@ "source": "user_user_getroleslist", "target": "user_user_hasrole" }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/earnings.py", + "source_location": "L24", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_earnings_py", + "target": "wallet_earnings_earningsmanager" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -75460,6 +76479,97 @@ "source": "main_app_wallet_earnings_py", "target": "wallet_earnings_listearnings" }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/earnings.py", + "source_location": "L7", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_earnings_earningsmanager", + "target": "wallet_entries_entriesmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/earnings.py", + "source_location": "L8", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_earnings_earningsmanager", + "target": "wallet_market_data_marketdatamanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/earnings.py", + "source_location": "L9", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_earnings_earningsmanager", + "target": "wallet_wallets_walletsmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/earnings.py", + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_earnings_earningsmanager", + "target": "models_wallet_earning" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/earnings.py", + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_earnings_earningsmanager", + "target": "models_wallet_holding" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/earnings.py", + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_earnings_earningsmanager", + "target": "models_wallet_transaction" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_walletcreate", + "target": "wallet_earnings_earningsmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_earningssync", + "target": "wallet_earnings_earningsmanager" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/earnings.py", + "source_location": "L80", + "weight": 1.0, + "source": "wallet_earnings_syncearnings", + "target": "models_wallet_earning" + }, { "relation": "calls", "context": "call", @@ -75499,21 +76609,21 @@ "confidence": "INFERRED", "confidence_score": 0.8, "source_file": "main/app/wallet/earnings.py", - "source_location": "L80", + "source_location": "L25", "weight": 1.0, "source": "wallet_earnings_syncearnings", - "target": "models_wallet_earning" + "target": "wallet_wallets_getownedwallet" }, { "relation": "calls", "context": "call", "confidence": "INFERRED", "confidence_score": 0.8, - "source_file": "main/app/wallet/earnings.py", - "source_location": "L25", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L333", "weight": 1.0, - "source": "wallet_earnings_syncearnings", - "target": "wallet_wallets_getownedwallet" + "source": "orunmila_tools_list_wallet_earnings", + "target": "wallet_earnings_listearnings" }, { "relation": "calls", @@ -75526,6 +76636,17 @@ "source": "wallet_earnings_listearnings", "target": "wallet_wallets_getwallet" }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L224", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_earnings_listearnings" + }, { "relation": "calls", "context": "call", @@ -75568,6 +76689,16 @@ "source": "main_app_wallet_entries_py", "target": "wallet_entries_entryupdate" }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L33", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_entries_py", + "target": "wallet_entries_entriesmanager" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -75638,6 +76769,26 @@ "source": "main_app_wallet_entries_py", "target": "wallet_entries_positionatdate" }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L71", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_entries_entrycreate", + "target": "wallet_positions_positionsmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L9", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_entries_entrycreate", + "target": "wallet_wallets_walletsmanager" + }, { "relation": "uses", "confidence": "INFERRED", @@ -75678,6 +76829,26 @@ "source": "controller_wallet_controller_earningssync", "target": "wallet_entries_entrycreate" }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L71", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_entries_entryupdate", + "target": "wallet_positions_positionsmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L9", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_entries_entryupdate", + "target": "wallet_wallets_walletsmanager" + }, { "relation": "uses", "confidence": "INFERRED", @@ -75718,6 +76889,76 @@ "source": "controller_wallet_controller_earningssync", "target": "wallet_entries_entryupdate" }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L71", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_entries_entriesmanager", + "target": "wallet_positions_positionsmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L9", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_entries_entriesmanager", + "target": "wallet_wallets_walletsmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_entries_entriesmanager", + "target": "models_wallet_holding" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/entries.py", + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_entries_entriesmanager", + "target": "models_wallet_transaction" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/performance.py", + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_performance_performancemanager", + "target": "wallet_entries_entriesmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L13", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_walletcreate", + "target": "wallet_entries_entriesmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L13", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_earningssync", + "target": "wallet_entries_entriesmanager" + }, { "relation": "calls", "context": "call", @@ -75801,10 +77042,10 @@ "confidence": "INFERRED", "confidence_score": 0.8, "source_file": "main/app/wallet/entries.py", - "source_location": "L82", + "source_location": "L88", "weight": 1.0, "source": "wallet_entries_addentry", - "target": "wallet_wallets_getwallet" + "target": "models_wallet_transaction" }, { "relation": "calls", @@ -75812,10 +77053,10 @@ "confidence": "INFERRED", "confidence_score": 0.8, "source_file": "main/app/wallet/entries.py", - "source_location": "L88", + "source_location": "L82", "weight": 1.0, "source": "wallet_entries_addentry", - "target": "models_wallet_transaction" + "target": "wallet_wallets_getwallet" }, { "relation": "calls", @@ -75898,21 +77139,21 @@ "relation": "contains", "confidence": "EXTRACTED", "source_file": "main/app/wallet/market_data.py", - "source_location": "L25", + "source_location": "L14", "weight": 1.0, "confidence_score": 1.0, "source": "main_app_wallet_market_data_py", - "target": "wallet_market_data_fetchliveprices" + "target": "wallet_market_data_marketdatamanager" }, { "relation": "contains", "confidence": "EXTRACTED", "source_file": "main/app/wallet/market_data.py", - "source_location": "L50", + "source_location": "L25", "weight": 1.0, "confidence_score": 1.0, "source": "main_app_wallet_market_data_py", - "target": "wallet_market_data_fetchcachedclose" + "target": "wallet_market_data_fetchliveprices" }, { "relation": "contains", @@ -75934,6 +77175,16 @@ "source": "main_app_wallet_market_data_py", "target": "wallet_market_data_fetchpadraocloses" }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L50", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_market_data_py", + "target": "wallet_market_data_fetchcachedclose" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -75955,48 +77206,54 @@ "target": "wallet_market_data_stocksapiheaders" }, { - "relation": "calls", - "context": "call", + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/performance.py", + "source_location": "L11", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_performance_performancemanager", + "target": "wallet_market_data_marketdatamanager" + }, + { + "relation": "uses", "confidence": "INFERRED", - "confidence_score": 0.8, "source_file": "main/app/wallet/positions.py", - "source_location": "L61", - "weight": 1.0, - "source": "wallet_positions_pricepass", - "target": "wallet_market_data_fetchliveprices" + "source_location": "L9", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_positions_positionsmanager", + "target": "wallet_market_data_marketdatamanager" }, { - "relation": "calls", - "context": "call", + "relation": "uses", "confidence": "INFERRED", - "confidence_score": 0.8, "source_file": "main/app/wallet/summary.py", - "source_location": "L35", - "weight": 1.0, - "source": "wallet_summary_getsummary", - "target": "wallet_market_data_fetchliveprices" + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_targetupsert", + "target": "wallet_market_data_marketdatamanager" }, { - "relation": "calls", - "context": "call", + "relation": "uses", "confidence": "INFERRED", - "confidence_score": 0.8, "source_file": "main/app/wallet/summary.py", - "source_location": "L93", - "weight": 1.0, - "source": "wallet_summary_getallocation", - "target": "wallet_market_data_fetchliveprices" + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_ratingupsert", + "target": "wallet_market_data_marketdatamanager" }, { - "relation": "calls", - "context": "call", + "relation": "uses", "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/wallet/positions.py", - "source_location": "L84", - "weight": 1.0, - "source": "wallet_positions_getpositions", - "target": "wallet_market_data_fetchliveprices" + "source_file": "main/app/wallet/summary.py", + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_summarymanager", + "target": "wallet_market_data_marketdatamanager" }, { "relation": "calls", @@ -76004,10 +77261,10 @@ "confidence": "INFERRED", "confidence_score": 0.8, "source_file": "main/app/wallet/positions.py", - "source_location": "L64", + "source_location": "L61", "weight": 1.0, "source": "wallet_positions_pricepass", - "target": "wallet_market_data_fetchcachedclose" + "target": "wallet_market_data_fetchliveprices" }, { "relation": "calls", @@ -76015,10 +77272,10 @@ "confidence": "INFERRED", "confidence_score": 0.8, "source_file": "main/app/wallet/summary.py", - "source_location": "L39", + "source_location": "L35", "weight": 1.0, "source": "wallet_summary_getsummary", - "target": "wallet_market_data_fetchcachedclose" + "target": "wallet_market_data_fetchliveprices" }, { "relation": "calls", @@ -76026,10 +77283,10 @@ "confidence": "INFERRED", "confidence_score": 0.8, "source_file": "main/app/wallet/summary.py", - "source_location": "L96", + "source_location": "L93", "weight": 1.0, "source": "wallet_summary_getallocation", - "target": "wallet_market_data_fetchcachedclose" + "target": "wallet_market_data_fetchliveprices" }, { "relation": "calls", @@ -76037,32 +77294,10 @@ "confidence": "INFERRED", "confidence_score": 0.8, "source_file": "main/app/wallet/positions.py", - "source_location": "L87", + "source_location": "L84", "weight": 1.0, "source": "wallet_positions_getpositions", - "target": "wallet_market_data_fetchcachedclose" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/market_data.py", - "source_location": "L53", - "weight": 1.0, - "confidence_score": 1.0, - "source": "wallet_market_data_fetchcachedclose", - "target": "wallet_market_data_stocksapibase" - }, - { - "relation": "calls", - "context": "call", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/market_data.py", - "source_location": "L55", - "weight": 1.0, - "confidence_score": 1.0, - "source": "wallet_market_data_fetchcachedclose", - "target": "wallet_market_data_stocksapiheaders" + "target": "wallet_market_data_fetchliveprices" }, { "relation": "calls", @@ -76119,6 +77354,16 @@ "source": "wallet_market_data_fetchpadraocloses", "target": "wallet_market_data_stocksapiheaders" }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/performance.py", + "source_location": "L20", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_performance_py", + "target": "wallet_performance_performancemanager" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -76139,6 +77384,56 @@ "source": "main_app_wallet_performance_py", "target": "wallet_performance_getperformance" }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/performance.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_performance_performancemanager", + "target": "wallet_wallets_walletsmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/performance.py", + "source_location": "L13", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_performance_performancemanager", + "target": "models_wallet_earning" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/performance.py", + "source_location": "L13", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_performance_performancemanager", + "target": "models_wallet_transaction" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L14", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_walletcreate", + "target": "wallet_performance_performancemanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L14", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_earningssync", + "target": "wallet_performance_performancemanager" + }, { "relation": "calls", "context": "call", @@ -76150,6 +77445,17 @@ "source": "wallet_performance_getperformance", "target": "wallet_performance_cachedperformance" }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L401", + "weight": 1.0, + "source": "orunmila_tools_get_wallet_performance", + "target": "wallet_performance_getperformance" + }, { "relation": "calls", "context": "call", @@ -76172,6 +77478,16 @@ "source": "wallet_performance_getperformance", "target": "wallet_wallets_getownedwallet" }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/positions.py", + "source_location": "L16", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_positions_py", + "target": "wallet_positions_positionsmanager" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -76188,9 +77504,9 @@ "source_file": "main/app/wallet/positions.py", "source_location": "L49", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_wallet_positions_py", - "target": "wallet_positions_weightof", - "confidence_score": 1.0 + "target": "wallet_positions_weightof" }, { "relation": "contains", @@ -76198,9 +77514,9 @@ "source_file": "main/app/wallet/positions.py", "source_location": "L53", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_wallet_positions_py", - "target": "wallet_positions_pricepass", - "confidence_score": 1.0 + "target": "wallet_positions_pricepass" }, { "relation": "contains", @@ -76208,9 +77524,9 @@ "source_file": "main/app/wallet/positions.py", "source_location": "L75", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_wallet_positions_py", - "target": "wallet_positions_rebalancedeltas", - "confidence_score": 1.0 + "target": "wallet_positions_rebalancedeltas" }, { "relation": "contains", @@ -76228,9 +77544,9 @@ "source_file": "main/app/wallet/positions.py", "source_location": "L138", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_wallet_positions_py", - "target": "wallet_positions_getrebalance", - "confidence_score": 1.0 + "target": "wallet_positions_getrebalance" }, { "relation": "contains", @@ -76242,6 +77558,66 @@ "source": "main_app_wallet_positions_py", "target": "wallet_positions_scorebuyflag" }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/positions.py", + "source_location": "L10", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_positions_positionsmanager", + "target": "wallet_wallets_walletsmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/positions.py", + "source_location": "L11", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_positions_positionsmanager", + "target": "models_wallet_holding" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/positions.py", + "source_location": "L11", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_positions_positionsmanager", + "target": "models_wallet_target" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L15", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_walletcreate", + "target": "wallet_positions_positionsmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L15", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_earningssync", + "target": "wallet_positions_positionsmanager" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/positions.py", + "source_location": "L19", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_positions_rationale_19", + "target": "wallet_positions_fetchxangoscores" + }, { "relation": "rationale_for", "confidence": "EXTRACTED", @@ -76280,9 +77656,9 @@ "source_file": "main/app/wallet/positions.py", "source_location": "L79", "weight": 1.0, + "confidence_score": 1.0, "source": "wallet_positions_rebalancedeltas", - "target": "wallet_positions_weightof", - "confidence_score": 1.0 + "target": "wallet_positions_weightof" }, { "relation": "calls", @@ -76291,9 +77667,9 @@ "source_file": "main/app/wallet/positions.py", "source_location": "L141", "weight": 1.0, + "confidence_score": 1.0, "source": "wallet_positions_getrebalance", - "target": "wallet_positions_weightof", - "confidence_score": 1.0 + "target": "wallet_positions_weightof" }, { "relation": "calls", @@ -76302,9 +77678,9 @@ "source_file": "main/app/wallet/positions.py", "source_location": "L94", "weight": 1.0, + "confidence_score": 1.0, "source": "wallet_positions_getpositions", - "target": "wallet_positions_pricepass", - "confidence_score": 1.0 + "target": "wallet_positions_pricepass" }, { "relation": "calls", @@ -76313,19 +77689,30 @@ "source_file": "main/app/wallet/positions.py", "source_location": "L139", "weight": 1.0, + "confidence_score": 1.0, "source": "wallet_positions_getrebalance", - "target": "wallet_positions_pricepass", - "confidence_score": 1.0 + "target": "wallet_positions_pricepass" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/positions.py", + "source_location": "L64", + "weight": 1.0, + "source": "wallet_positions_pricepass", + "target": "wallet_market_data_fetchcachedclose" }, { "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "main/app/wallet/positions.py", - "source_location": "L56", + "source_location": "L57", "weight": 1.0, - "source": "wallet_positions_rationale_56", - "target": "wallet_positions_pricepass", - "confidence_score": 1.0 + "confidence_score": 1.0, + "source": "wallet_positions_rationale_57", + "target": "wallet_positions_pricepass" }, { "relation": "calls", @@ -76338,6 +77725,16 @@ "source": "wallet_positions_pricepass", "target": "wallet_wallets_getwallet" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/positions.py", + "source_location": "L56", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_positions_rationale_56", + "target": "wallet_positions_pricepass" + }, { "relation": "calls", "context": "call", @@ -76345,9 +77742,9 @@ "source_file": "main/app/wallet/positions.py", "source_location": "L95", "weight": 1.0, + "confidence_score": 1.0, "source": "wallet_positions_getpositions", - "target": "wallet_positions_rebalancedeltas", - "confidence_score": 1.0 + "target": "wallet_positions_rebalancedeltas" }, { "relation": "calls", @@ -76356,9 +77753,19 @@ "source_file": "main/app/wallet/positions.py", "source_location": "L140", "weight": 1.0, + "confidence_score": 1.0, "source": "wallet_positions_getrebalance", - "target": "wallet_positions_rebalancedeltas", - "confidence_score": 1.0 + "target": "wallet_positions_rebalancedeltas" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/positions.py", + "source_location": "L79", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_positions_rationale_79", + "target": "wallet_positions_rebalancedeltas" }, { "relation": "rationale_for", @@ -76366,9 +77773,42 @@ "source_file": "main/app/wallet/positions.py", "source_location": "L78", "weight": 1.0, + "confidence_score": 1.0, "source": "wallet_positions_rationale_78", - "target": "wallet_positions_rebalancedeltas", - "confidence_score": 1.0 + "target": "wallet_positions_rebalancedeltas" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L213", + "weight": 1.0, + "source": "orunmila_tools_get_wallet_positions", + "target": "wallet_positions_getpositions" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/positions.py", + "source_location": "L87", + "weight": 1.0, + "source": "wallet_positions_getpositions", + "target": "wallet_market_data_fetchcachedclose" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L212", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_positions_getpositions" }, { "relation": "calls", @@ -76403,6 +77843,17 @@ "source": "wallet_positions_getpositions", "target": "wallet_wallets_getownedwallet" }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L443", + "weight": 1.0, + "source": "orunmila_tools_get_wallet_rebalance", + "target": "wallet_positions_getrebalance" + }, { "relation": "imports_from", "context": "import", @@ -76434,6 +77885,16 @@ "source": "main_app_wallet_summary_py", "target": "wallet_summary_ratingupsert" }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L30", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_summary_py", + "target": "wallet_summary_summarymanager" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -76474,6 +77935,16 @@ "source": "main_app_wallet_summary_py", "target": "wallet_summary_set_rating" }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L11", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_targetupsert", + "target": "wallet_wallets_walletsmanager" + }, { "relation": "uses", "confidence": "INFERRED", @@ -76524,6 +77995,16 @@ "source": "controller_wallet_controller_earningssync", "target": "wallet_summary_targetupsert" }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L11", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_ratingupsert", + "target": "wallet_wallets_walletsmanager" + }, { "relation": "uses", "confidence": "INFERRED", @@ -76574,6 +78055,88 @@ "source": "controller_wallet_controller_earningssync", "target": "wallet_summary_ratingupsert" }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L11", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_summarymanager", + "target": "wallet_wallets_walletsmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_summarymanager", + "target": "models_wallet_holding" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_summarymanager", + "target": "models_wallet_snapshot" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/summary.py", + "source_location": "L12", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_summary_summarymanager", + "target": "models_wallet_target" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L16", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_walletcreate", + "target": "wallet_summary_summarymanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L16", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_earningssync", + "target": "wallet_summary_summarymanager" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L252", + "weight": 1.0, + "source": "orunmila_tools_get_wallet_summary", + "target": "wallet_summary_getsummary" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L39", + "weight": 1.0, + "source": "wallet_summary_getsummary", + "target": "wallet_market_data_fetchcachedclose" + }, { "relation": "calls", "context": "call", @@ -76585,6 +78148,17 @@ "source": "wallet_summary_getsummary", "target": "wallet_wallets_getwallet" }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L217", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_summary_getsummary" + }, { "relation": "calls", "context": "call", @@ -76596,6 +78170,28 @@ "source": "wallet_summary_getsummary", "target": "wallet_wallets_getownedwallet" }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L292", + "weight": 1.0, + "source": "orunmila_tools_get_wallet_allocation", + "target": "wallet_summary_getallocation" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/summary.py", + "source_location": "L96", + "weight": 1.0, + "source": "wallet_summary_getallocation", + "target": "wallet_market_data_fetchcachedclose" + }, { "relation": "calls", "context": "call", @@ -76624,10 +78220,10 @@ "confidence": "INFERRED", "confidence_score": 0.8, "source_file": "main/app/wallet/summary.py", - "source_location": "L119", + "source_location": "L131", "weight": 1.0, "source": "wallet_summary_upserttarget", - "target": "wallet_wallets_getwallet" + "target": "models_wallet_target" }, { "relation": "calls", @@ -76635,10 +78231,10 @@ "confidence": "INFERRED", "confidence_score": 0.8, "source_file": "main/app/wallet/summary.py", - "source_location": "L131", + "source_location": "L119", "weight": 1.0, "source": "wallet_summary_upserttarget", - "target": "models_wallet_target" + "target": "wallet_wallets_getwallet" }, { "relation": "calls", @@ -76684,6 +78280,16 @@ "source": "main_app_wallet_wallets_py", "target": "fastapi" }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L11", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallets_py", + "target": "wallet_wallets_walletsmanager" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -76724,6 +78330,113 @@ "source": "main_app_wallet_wallets_py", "target": "wallet_wallets_getownedwallet" }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/app/wallet/wallets.py", + "source_location": "L6", + "weight": 0.8, + "confidence_score": 0.5, + "source": "wallet_wallets_walletsmanager", + "target": "models_wallet_wallet" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L17", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_walletcreate", + "target": "wallet_wallets_walletsmanager" + }, + { + "relation": "uses", + "confidence": "INFERRED", + "source_file": "main/controller/wallet_controller.py", + "source_location": "L17", + "weight": 0.8, + "confidence_score": 0.5, + "source": "controller_wallet_controller_earningssync", + "target": "wallet_wallets_walletsmanager" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L206", + "weight": 1.0, + "source": "orunmila_tools_get_wallet_positions", + "target": "wallet_wallets_getwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L245", + "weight": 1.0, + "source": "orunmila_tools_get_wallet_summary", + "target": "wallet_wallets_getwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L285", + "weight": 1.0, + "source": "orunmila_tools_get_wallet_allocation", + "target": "wallet_wallets_getwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L326", + "weight": 1.0, + "source": "orunmila_tools_list_wallet_earnings", + "target": "wallet_wallets_getwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L394", + "weight": 1.0, + "source": "orunmila_tools_get_wallet_performance", + "target": "wallet_wallets_getwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L436", + "weight": 1.0, + "source": "orunmila_tools_get_wallet_rebalance", + "target": "wallet_wallets_getwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L208", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_wallets_getwallet" + }, { "relation": "calls", "context": "call", @@ -76735,6 +78448,327 @@ "source": "wallet_wallets_createwallet", "target": "models_wallet_wallet" }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L13", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "fastapi" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L36", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchxangoscores" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L48", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_scorebuyflag" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L32", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_createwallet" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L40", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_listwallets" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L44", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_entrycreate" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L55", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_entryupdate" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L62", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getownedwallet" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L72", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_applyentries" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L88", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_recalcholding" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L112", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_addentry" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L138", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_listentries" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L150", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_updateentry" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L172", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_deleteentry" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L193", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_stocksapibase" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L197", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_stocksapiheaders" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L202", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchliveprices" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L227", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchcachedclose" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L247", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getpositions" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L306", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_targetupsert" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L313", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_ratingupsert" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L319", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getsummary" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L370", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getallocation" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L396", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_upserttarget" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L422", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_set_rating" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L433", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_positionatdate" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L440", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchmarketdividends" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L458", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_syncearnings" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L525", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_listearnings" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L536", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchpadraocloses" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L559", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_cachedperformance" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L662", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getperformance" + }, { "relation": "imports_from", "context": "import", @@ -78181,9 +80215,9 @@ "source_file": "main/controller/wallet_controller.py", "source_location": "L119", "weight": 1.0, + "confidence_score": 1.0, "source": "main_controller_wallet_controller_py", - "target": "controller_wallet_controller_get_rebalance_route", - "confidence_score": 1.0 + "target": "controller_wallet_controller_get_rebalance_route" }, { "relation": "contains", @@ -91709,440 +93743,767 @@ "target": "specs_2026_09_29_nginx_scaling_design_codeblock_1" }, { - "relation": "rationale_for", + "relation": "imports_from", + "context": "import", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/positions.py", - "source_location": "L59", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L7", "weight": 1.0, "confidence_score": 1.0, - "source": "wallet_positions_rationale_59", - "target": "wallet_positions_scorebuyflag" + "source": "main_app_orunmila_tools_py", + "target": "fastapi" }, { - "relation": "rationale_for", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/positions.py", - "source_location": "L36", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L20", "weight": 1.0, "confidence_score": 1.0, - "source": "wallet_positions_rationale_36", - "target": "wallet_positions_scorebuyflag" + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_search_memory" }, { - "relation": "imports_from", - "context": "import", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/auth.py", - "source_location": "L3", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L51", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_auth_py", - "target": "fastapi" + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_save_memory" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/auth.py", - "source_location": "L13", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L93", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_auth_py", - "target": "wallet_auth_resolverawtoken" + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_execute_code" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/auth.py", - "source_location": "L26", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L114", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_auth_py", - "target": "wallet_auth_getwalletidentity" + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_read_file" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/auth.py", - "source_location": "L30", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L128", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_auth_py", - "target": "wallet_auth_requirewalletuser" + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_write_file" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/auth.py", - "source_location": "L36", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L144", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_auth_py", - "target": "wallet_auth_requirewalletownership" + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_list_files" }, { - "relation": "calls", - "context": "call", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/auth.py", - "source_location": "L27", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L157", "weight": 1.0, "confidence_score": 1.0, - "source": "wallet_auth_getwalletidentity", - "target": "wallet_auth_resolverawtoken" + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_serve_file" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/wallet/wallets.py", - "source_location": "L17", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L184", "weight": 1.0, - "source": "wallet_wallets_getownedwallet", - "target": "wallet_auth_requirewalletownership" + "confidence_score": 1.0, + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_get_wallet_positions" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L68", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L223", "weight": 1.0, - "source": "wallet_wallet_service_getownedwallet", - "target": "wallet_auth_requirewalletownership" + "confidence_score": 1.0, + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_get_wallet_summary" }, { - "relation": "calls", - "context": "call", - "confidence": "INFERRED", - "confidence_score": 0.8, - "source_file": "main/service/wallet_service.py", - "source_location": "L50", + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L262", "weight": 1.0, - "source": "service_wallet_service_get_owned_wallet", - "target": "wallet_auth_requirewalletownership" + "confidence_score": 1.0, + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_get_wallet_allocation" }, { - "relation": "imports_from", - "context": "import", + "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L13", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L303", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "fastapi" + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_list_wallet_earnings" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L36", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L361", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_fetchxangoscores" + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_get_wallet_performance" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L48", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L414", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_scorebuyflag" + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_get_wallet_rebalance" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L32", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L190", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_createwallet" + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_dispatchtoolcall" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L40", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L183", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_listwallets" + "source": "main_app_orunmila_tools_py", + "target": "orunmila_tools_narrate_positions" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L44", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L28", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_entrycreate" + "source": "orunmila_tools_rationale_28", + "target": "orunmila_tools_search_memory" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L55", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L23", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_entryupdate" + "source": "orunmila_tools_rationale_23", + "target": "orunmila_tools_search_memory" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L62", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L22", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_getownedwallet" + "source": "orunmila_tools_rationale_22", + "target": "orunmila_tools_search_memory" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L72", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L21", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_applyentries" + "source": "orunmila_tools_rationale_21", + "target": "orunmila_tools_search_memory" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L88", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L59", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_recalcholding" + "source": "orunmila_tools_rationale_59", + "target": "orunmila_tools_save_memory" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L112", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L54", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_addentry" + "source": "orunmila_tools_rationale_54", + "target": "orunmila_tools_save_memory" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L138", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L53", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_listentries" + "source": "orunmila_tools_rationale_53", + "target": "orunmila_tools_save_memory" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L150", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L52", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_updateentry" + "source": "orunmila_tools_rationale_52", + "target": "orunmila_tools_save_memory" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L172", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L101", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_deleteentry" + "source": "orunmila_tools_rationale_101", + "target": "orunmila_tools_execute_code" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L193", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L96", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_stocksapibase" + "source": "orunmila_tools_rationale_96", + "target": "orunmila_tools_execute_code" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L197", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L95", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_stocksapiheaders" + "source": "orunmila_tools_rationale_95", + "target": "orunmila_tools_execute_code" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L202", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L94", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_fetchliveprices" + "source": "orunmila_tools_rationale_94", + "target": "orunmila_tools_execute_code" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L227", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L122", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_fetchcachedclose" + "source": "orunmila_tools_rationale_122", + "target": "orunmila_tools_read_file" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L247", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L117", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_getpositions" + "source": "orunmila_tools_rationale_117", + "target": "orunmila_tools_read_file" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L306", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L116", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_targetupsert" + "source": "orunmila_tools_rationale_116", + "target": "orunmila_tools_read_file" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L313", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L115", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_ratingupsert" + "source": "orunmila_tools_rationale_115", + "target": "orunmila_tools_read_file" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L319", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L136", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_getsummary" + "source": "orunmila_tools_rationale_136", + "target": "orunmila_tools_write_file" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L370", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L131", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_getallocation" + "source": "orunmila_tools_rationale_131", + "target": "orunmila_tools_write_file" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L396", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L130", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_upserttarget" + "source": "orunmila_tools_rationale_130", + "target": "orunmila_tools_write_file" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L422", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L129", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_set_rating" + "source": "orunmila_tools_rationale_129", + "target": "orunmila_tools_write_file" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L433", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L152", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_positionatdate" + "source": "orunmila_tools_rationale_152", + "target": "orunmila_tools_list_files" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L440", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L147", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_fetchmarketdividends" + "source": "orunmila_tools_rationale_147", + "target": "orunmila_tools_list_files" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L458", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L146", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_syncearnings" + "source": "orunmila_tools_rationale_146", + "target": "orunmila_tools_list_files" }, { - "relation": "contains", + "relation": "rationale_for", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L525", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L145", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", + "source": "orunmila_tools_rationale_145", + "target": "orunmila_tools_list_files" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L165", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_165", + "target": "orunmila_tools_serve_file" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L160", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_160", + "target": "orunmila_tools_serve_file" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L159", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_159", + "target": "orunmila_tools_serve_file" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L158", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_158", + "target": "orunmila_tools_serve_file" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L190", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_190", + "target": "orunmila_tools_get_wallet_positions" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L185", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_185", + "target": "orunmila_tools_get_wallet_positions" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L226", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_226", + "target": "orunmila_tools_get_wallet_summary" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L224", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_224", + "target": "orunmila_tools_get_wallet_summary" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L262", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_262", + "target": "orunmila_tools_get_wallet_allocation" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L263", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_263", + "target": "orunmila_tools_get_wallet_allocation" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L300", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_300", + "target": "orunmila_tools_list_wallet_earnings" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L304", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_304", + "target": "orunmila_tools_list_wallet_earnings" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L357", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_357", + "target": "orunmila_tools_get_wallet_performance" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L364", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_364", + "target": "orunmila_tools_get_wallet_performance" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L405", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_405", + "target": "orunmila_tools_get_wallet_rebalance" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L415", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_415", + "target": "orunmila_tools_get_wallet_rebalance" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L53", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_market_data_fetchcachedclose", + "target": "wallet_market_data_stocksapibase" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/market_data.py", + "source_location": "L55", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_market_data_fetchcachedclose", + "target": "wallet_market_data_stocksapiheaders" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools.py", + "source_location": "L184", + "weight": 1.0, + "confidence_score": 1.0, + "source": "orunmila_tools_rationale_184", + "target": "orunmila_tools_narrate_positions" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L205", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_wallets_getownedwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L205", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_wallet_service_getownedwallet" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L212", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_wallet_service_getpositions" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L217", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", + "target": "wallet_wallet_service_getsummary" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools.py", + "source_location": "L224", + "weight": 1.0, + "source": "orunmila_tools_narrate_positions", "target": "wallet_wallet_service_listearnings" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/positions.py", + "source_location": "L59", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_positions_rationale_59", + "target": "wallet_positions_scorebuyflag" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/positions.py", + "source_location": "L36", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_positions_rationale_36", + "target": "wallet_positions_scorebuyflag" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/auth.py", + "source_location": "L3", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_auth_py", + "target": "fastapi" + }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L536", + "source_file": "main/app/wallet/auth.py", + "source_location": "L13", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_fetchpadraocloses" + "source": "main_app_wallet_auth_py", + "target": "wallet_auth_resolverawtoken" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L559", + "source_file": "main/app/wallet/auth.py", + "source_location": "L26", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_cachedperformance" + "source": "main_app_wallet_auth_py", + "target": "wallet_auth_getwalletidentity" }, { "relation": "contains", "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L662", + "source_file": "main/app/wallet/auth.py", + "source_location": "L30", "weight": 1.0, "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_getperformance" + "source": "main_app_wallet_auth_py", + "target": "wallet_auth_requirewalletuser" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/auth.py", + "source_location": "L36", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_auth_py", + "target": "wallet_auth_requirewalletownership" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/auth.py", + "source_location": "L27", + "weight": 1.0, + "confidence_score": 1.0, + "source": "wallet_auth_getwalletidentity", + "target": "wallet_auth_resolverawtoken" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/wallets.py", + "source_location": "L17", + "weight": 1.0, + "source": "wallet_wallets_getownedwallet", + "target": "wallet_auth_requirewalletownership" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L68", + "weight": 1.0, + "source": "wallet_wallet_service_getownedwallet", + "target": "wallet_auth_requirewalletownership" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/service/wallet_service.py", + "source_location": "L50", + "weight": 1.0, + "source": "service_wallet_service_get_owned_wallet", + "target": "wallet_auth_requirewalletownership" }, { "relation": "calls", @@ -158424,5 +160785,5 @@ "label": "User Authentication & Authorization" } ], - "built_at_commit": "5f6a9589ec29c6af12d284a4fe1d2a4ef4aab7d5" + "built_at_commit": "638e52b716b1186d9bce437f5bd20779731f6217" } \ No newline at end of file diff --git a/graphify-out/manifest.json b/graphify-out/manifest.json index 6b766be3..0235c3ae 100644 --- a/graphify-out/manifest.json +++ b/graphify-out/manifest.json @@ -269,16 +269,36 @@ "ast_hash": "18123062622096d1ed80c8d6c41b0169", "semantic_hash": "" }, - "D:\\Repositories\\server\\main\\app\\orunmila\\tools.py": { - "mtime": 1790824053.1540968, - "ast_hash": "faaac4998b77bd459dc1011925652a9c", - "semantic_hash": "" - }, "D:\\Repositories\\server\\main\\app\\orunmila\\vector.py": { "mtime": 1789266824.606479, "ast_hash": "dd0df7ede0dd28d74c307a7aea6ba04b", "semantic_hash": "" }, + "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\context.py": { + "mtime": 1790832493.312804, + "ast_hash": "c47a06369cfe9aea8cada08f7942f480", + "semantic_hash": "" + }, + "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\memory.py": { + "mtime": 1790832553.07237, + "ast_hash": "0a02b1d417ed1b9929dcbbd471d32461", + "semantic_hash": "" + }, + "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\sandbox.py": { + "mtime": 1790832926.2121358, + "ast_hash": "669b63ebbe26e8c507d8f539a758ff33", + "semantic_hash": "" + }, + "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\wallet.py": { + "mtime": 1790832579.4839613, + "ast_hash": "07262619e8d45c8971a5479e9c86af76", + "semantic_hash": "" + }, + "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\__init__.py": { + "mtime": 1790832588.690746, + "ast_hash": "6240a2e38d2557732056f384f7601566", + "semantic_hash": "" + }, "D:\\Repositories\\server\\main\\app\\scraper_b3\\scraper.py": { "mtime": 1790821091.8922184, "ast_hash": "7bd8236b3758b54442a88eaf8c8c761b", @@ -320,8 +340,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\stocks_api\\sync_cache.py": { - "mtime": 1790821091.8932161, - "ast_hash": "f32f01784a16b03442fcd6a1662e1e47", + "mtime": 1790830784.8927202, + "ast_hash": "e0a923a48bb5e5a756bc8ffab03ead56", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\stocks_api\\util.py": { @@ -335,38 +355,43 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\wallet\\earnings.py": { - "mtime": 1790824458.9011092, - "ast_hash": "2e772942089dbed00a2bd81f69d67ee8", + "mtime": 1790828547.1383233, + "ast_hash": "8664068a2fda25f6f5cb3977b2c709eb", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\wallet\\entries.py": { - "mtime": 1790826311.012261, - "ast_hash": "7df758c815bfa3e1507cbb6b87d85147", + "mtime": 1790829999.0547588, + "ast_hash": "7275551a4d39fb1d22b7614c5f804f5b", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\wallet\\market_data.py": { - "mtime": 1790825185.0532987, - "ast_hash": "fd5e532592b3f274c8df7725152028a1", + "mtime": 1790830194.744553, + "ast_hash": "43828a93b9fd151772081885cbc20ab6", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\wallet\\performance.py": { - "mtime": 1790824052.8533888, - "ast_hash": "61593cfecc93cd23fff7f63dd2c6b1de", + "mtime": 1790830223.6296313, + "ast_hash": "c332a654033ce98e7f8a31df3faea5ea", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\wallet\\positions.py": { - "mtime": 1790826385.2914288, - "ast_hash": "032c229aa8753ac32ed73b4f14e8cc19", + "mtime": 1790830807.8044558, + "ast_hash": "382c223221315fa71edb000746126111", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\wallet\\summary.py": { - "mtime": 1790826317.3061473, - "ast_hash": "9a0d79a453dad99ffdcfe8c19a147b75", + "mtime": 1790830238.410782, + "ast_hash": "3d1a0ee9db7d69b8f8ce324b3946182f", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\wallet\\wallets.py": { - "mtime": 1790825037.0556405, - "ast_hash": "468ae0aa9392477efa4a5c6b4990b049", + "mtime": 1790828492.4487593, + "ast_hash": "f52f4d29d146953b6659e346e906da26", + "semantic_hash": "" + }, + "D:\\Repositories\\server\\main\\app\\wallet\\wallet_service.py": { + "mtime": 1790828956.056157, + "ast_hash": "0596d4a054b5ab48baeb9af24511af41", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\controller\\authentication_controller.py": { @@ -390,8 +415,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\controller\\wallet_controller.py": { - "mtime": 1790826317.3061473, - "ast_hash": "11201d1c6b1580e76f2e2ad752cd9c9b", + "mtime": 1790829290.2056398, + "ast_hash": "3597af9fe73c2985dbb7763ead8a0f66", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\models\\base.py": { @@ -785,8 +810,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\frontend\\mock-wallet.html": { - "mtime": 1790826015.8223977, - "ast_hash": "b855d9b9d7adb55abf60a4228763ad2a", + "mtime": 1790828329.3471212, + "ast_hash": "842c72edefd8f4c47baf0cf55f8a955e", "semantic_hash": "" }, "D:\\Repositories\\server\\frontend\\pnpm-workspace.yaml": { diff --git a/main/app/orunmila/tools/__init__.py b/main/app/orunmila/tools/__init__.py index cefabf80..6738e09d 100644 --- a/main/app/orunmila/tools/__init__.py +++ b/main/app/orunmila/tools/__init__.py @@ -1,20 +1,9 @@ import logging from typing import Any -from main.app.orunmila.memory import OrunmilaMemory -from main.app.orunmila.sandbox import SandboxManager, hostPath -from main.app.orunmila.tools.context import closeOwnSession, popAuthSession from main.app.orunmila.tools.memory import save_memory, search_memory from main.app.orunmila.tools.sandbox import execute_code, list_files, read_file, serve_file, write_file -from main.app.orunmila.tools.wallet import ( - get_wallet_allocation, - get_wallet_performance, - get_wallet_positions, - get_wallet_rebalance, - get_wallet_summary, - list_wallet_earnings, -) -from main.app.orunmila.vector import embed +from main.app.orunmila.tools.wallet import wallet_allocation, wallet_performance, wallet_positions, wallet_rebalance, wallet_summary, list_wallet_earnings logger = logging.getLogger(__name__) @@ -27,12 +16,12 @@ "write_file": write_file, "list_files": list_files, "serve_file": serve_file, - "get_wallet_positions": get_wallet_positions, - "get_wallet_summary": get_wallet_summary, - "get_wallet_allocation": get_wallet_allocation, + "wallet_positions": wallet_positions, + "wallet_summary": wallet_summary, + "wallet_allocation": wallet_allocation, "list_wallet_earnings": list_wallet_earnings, - "get_wallet_performance": get_wallet_performance, - "get_wallet_rebalance": get_wallet_rebalance, + "wallet_performance": wallet_performance, + "wallet_rebalance": wallet_rebalance, } diff --git a/main/app/orunmila/tools/memory.py b/main/app/orunmila/tools/memory.py index c69e510c..a492feb5 100644 --- a/main/app/orunmila/tools/memory.py +++ b/main/app/orunmila/tools/memory.py @@ -1,6 +1,7 @@ import asyncio -import main.app.orunmila.tools as toolsPkg +from main.app.orunmila.memory import OrunmilaMemory +from main.app.orunmila.vector import embed from main.app.orunmila.tools.context import closeOwnSession, popAuthSession @@ -18,7 +19,7 @@ async def search_memory(query: str, limit: int = 10, **_) -> dict: return authError try: results = await asyncio.to_thread( - toolsPkg.OrunmilaMemory.search, + OrunmilaMemory.search, db, # type: ignore[arg-type] user["userId"], query, @@ -43,9 +44,9 @@ async def save_memory(key: str, value: str, type: str, **_) -> dict: if authError is not None: return authError try: - embedding = toolsPkg.embed([value])[0] + embedding = embed([value])[0] result = await asyncio.to_thread( - toolsPkg.OrunmilaMemory.upsertMemory, + OrunmilaMemory.upsertMemory, db, # type: ignore[arg-type] user["userId"], key=key, diff --git a/main/app/orunmila/tools/sandbox.py b/main/app/orunmila/tools/sandbox.py index dffbd048..22ba231e 100644 --- a/main/app/orunmila/tools/sandbox.py +++ b/main/app/orunmila/tools/sandbox.py @@ -3,7 +3,7 @@ from forgevm.exceptions import SandboxNotFound -import main.app.orunmila.tools as toolsPkg +from main.app.orunmila.sandbox import SandboxManager logger = logging.getLogger(__name__) @@ -21,7 +21,7 @@ async def execute_code(code: str, timeout: int = 30, **_) -> dict: if not sandboxId: return {"error": "No sandbox available"} try: - return await toolsPkg.SandboxManager.execute(userId, code, sandboxId, timeout=timeout) + return await SandboxManager.execute(userId, code, sandboxId, timeout=timeout) except SandboxNotFound: return {"error": "Sandbox could not be respawned. Try again."} except Exception as e: @@ -37,7 +37,7 @@ async def read_file(path: str, **_) -> dict: """ userId = _.get("userId", 0) try: - content = toolsPkg.SandboxManager.read_file(userId, path) + content = SandboxManager.read_file(userId, path) except ValueError: return {"error": "Invalid workspace path"} return {"content": content} @@ -53,7 +53,7 @@ async def write_file(path: str, content: str, **_) -> dict: """ userId = _.get("userId", 0) try: - ok = toolsPkg.SandboxManager.write_file(userId, path, content) + ok = SandboxManager.write_file(userId, path, content) except ValueError: return {"error": "Invalid workspace path"} return {"success": ok} @@ -67,7 +67,7 @@ async def list_files(path: str = "/workspace", **_) -> dict: """ userId = _.get("userId", 0) try: - return toolsPkg.SandboxManager.list_files(userId, path) + return SandboxManager.list_files(userId, path) except ValueError: return {"error": "Invalid workspace path"} @@ -84,7 +84,7 @@ async def serve_file(path: str, **_) -> dict: """ userId = _.get("userId", 0) try: - host = toolsPkg.hostPath(userId, path) + host = SandboxManager.hostPath(userId, path) except ValueError: return {"error": "Invalid workspace path"} if not host.exists() or not host.is_file(): diff --git a/main/app/orunmila/tools/wallet.py b/main/app/orunmila/tools/wallet.py index b957c2c9..f61142ae 100644 --- a/main/app/orunmila/tools/wallet.py +++ b/main/app/orunmila/tools/wallet.py @@ -24,7 +24,7 @@ def ensureOwnership(db: Session | None, walletId: int, userId: int) -> dict | No return None -async def get_wallet_positions(wallet_id: int, **_) -> dict: +async def wallet_positions(wallet_id: int, **_) -> dict: """List wallet holdings with live prices, equity, allocation, and buy signals. Read-only: never mutates wallet state. @@ -49,7 +49,7 @@ async def get_wallet_positions(wallet_id: int, **_) -> dict: closeOwnSession(db, ownSession) -async def get_wallet_summary(wallet_id: int, **_) -> dict: +async def wallet_summary(wallet_id: int, **_) -> dict: """Summarize applied capital, equity, and variation for a wallet. Read-only: never mutates wallet state. @@ -74,7 +74,7 @@ async def get_wallet_summary(wallet_id: int, **_) -> dict: closeOwnSession(db, ownSession) -async def get_wallet_allocation(wallet_id: int, group_by: str = "ticker", **_) -> dict: +async def wallet_allocation(wallet_id: int, group_by: str = "ticker", **_) -> dict: """Break wallet equity down by ticker or asset type. Read-only: never mutates wallet state. @@ -145,7 +145,7 @@ async def list_wallet_earnings(wallet_id: int, status: Optional[str] = "A Recebe closeOwnSession(db, ownSession) -async def get_wallet_performance( +async def wallet_performance( wallet_id: int, from_date: str, to_date: str, ticker: Optional[str] = None, **_ ) -> dict: """Compute time-weighted return, volatility, and dividends for a wallet or ticker. @@ -184,7 +184,7 @@ async def get_wallet_performance( closeOwnSession(db, ownSession) -async def get_wallet_rebalance(wallet_id: int, **_) -> dict: +async def wallet_rebalance(wallet_id: int, **_) -> dict: """Show weight-share rebalance deltas per ticker (buy/sell/hold). Read-only: never mutates wallet state. From 7979daf26f28a2515c9df48977583bcf52c0af4d Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 03:03:34 -0300 Subject: [PATCH 29/34] weight round --- graphify-out/.graphify_labels.json | 5 - graphify-out/GRAPH_REPORT.md | 364 +++--- graphify-out/graph.json | 1775 +++++++++++++++++----------- graphify-out/manifest.json | 16 +- main/app/wallet/positions.py | 14 +- main/app/wallet/summary.py | 4 - 6 files changed, 1265 insertions(+), 913 deletions(-) diff --git a/graphify-out/.graphify_labels.json b/graphify-out/.graphify_labels.json index de158443..038ac20f 100644 --- a/graphify-out/.graphify_labels.json +++ b/graphify-out/.graphify_labels.json @@ -631,15 +631,10 @@ "629": "Community 629", "630": "Community 630", "631": "Community 631", - "632": "Community 632", - "633": "Community 633", "634": "Community 634", - "635": "Community 635", - "636": "Community 636", "637": "Community 637", "638": "Community 638", "639": "Community 639", - "643": "Community 643", "648": "Community 648", "649": "Community 649", "650": "Community 650" diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md index d6f44e99..6eaa8f10 100644 --- a/graphify-out/GRAPH_REPORT.md +++ b/graphify-out/GRAPH_REPORT.md @@ -1,16 +1,16 @@ # Graph Report - server (2026-10-01) ## Corpus Check -- 158 files · ~123,274 words +- 158 files · ~123,258 words - Verdict: corpus is large enough that graph structure adds value. ## Summary -- 6991 nodes · 9562 edges · 644 communities (394 shown, 250 thin omitted) -- Extraction: 84% EXTRACTED · 16% INFERRED · 0% AMBIGUOUS · INFERRED: 1551 edges (avg confidence: 0.68) +- 6998 nodes · 9590 edges · 639 communities (397 shown, 242 thin omitted) +- Extraction: 84% EXTRACTED · 16% INFERRED · 0% AMBIGUOUS · INFERRED: 1562 edges (avg confidence: 0.68) - Token cost: 0 input · 0 output ## Graph Freshness -- Built from commit: `638e52b7` +- Built from commit: `81d7224b` - Run `git rev-parse HEAD` and compare to check if the graph is stale. - Run `graphify update .` after code changes (no API cost). @@ -140,6 +140,7 @@ - [[_COMMUNITY_Community 122|Community 122]] - [[_COMMUNITY_Community 123|Community 123]] - [[_COMMUNITY_Community 124|Community 124]] +- [[_COMMUNITY_Community 125|Community 125]] - [[_COMMUNITY_Community 126|Community 126]] - [[_COMMUNITY_Community 127|Community 127]] - [[_COMMUNITY_Community 128|Community 128]] @@ -632,15 +633,10 @@ - [[_COMMUNITY_Community 629|Community 629]] - [[_COMMUNITY_Community 630|Community 630]] - [[_COMMUNITY_Community 631|Community 631]] -- [[_COMMUNITY_Community 632|Community 632]] -- [[_COMMUNITY_Community 633|Community 633]] - [[_COMMUNITY_Community 634|Community 634]] -- [[_COMMUNITY_Community 635|Community 635]] -- [[_COMMUNITY_Community 636|Community 636]] - [[_COMMUNITY_Community 637|Community 637]] - [[_COMMUNITY_Community 638|Community 638]] - [[_COMMUNITY_Community 639|Community 639]] -- [[_COMMUNITY_Community 643|Community 643]] - [[_COMMUNITY_Community 648|Community 648]] - [[_COMMUNITY_Community 649|Community 649]] - [[_COMMUNITY_Community 650|Community 650]] @@ -677,7 +673,7 @@ - **Configuration & Database Infrastructure** — config_Config, config_engine, config_stocksEngine [INFERRED] - **User Authentication & Authorization** — user_service, authentication, user_roles, permission_system [INFERRED] -## Communities (644 total, 250 thin omitted) +## Communities (639 total, 242 thin omitted) ### Community 0 - "Stocks API Endpoints" Cohesion: 0.0 @@ -692,8 +688,8 @@ Cohesion: 0.13 Nodes (21): Thin async wrapper around the CubeSandbox/E2B HTTP API. All methods are sta, SandboxManager, _mock_forgevm(), Unit tests for SandboxManager — HTTP calls mocked via a fake client class., Wire up mock forgevm AsyncClient that returns sandbox with all methods., Wire up mock forgevm AsyncClient that returns sandbox with all methods., test_create_sandbox(), test_destroy_sandbox() (+13 more) ### Community 3 - "Prometheus Agent" -Cohesion: 0.11 -Nodes (12): _make_stocks_df(), Return a small DataFrame with the columns the query module expects., Return a small DataFrame with the columns the query module expects., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48. (+4 more) +Cohesion: 0.1 +Nodes (16): _make_stocks_df(), Return a small DataFrame with the columns the query module expects., Return a small DataFrame with the columns the query module expects., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48. (+8 more) ### Community 4 - "Data Models & Types" Cohesion: 0.11 @@ -712,16 +708,16 @@ Cohesion: 0.07 Nodes (29): Algorithmic Compression (`compact.py`) Implementation Plan, code:python (# main/app/prometheus/compact.py), code:python (# Before:), code:python (# Before:), code:python (# Before:), code:bash (pytest tests/ -k "prometheus" -v), code:bash (git add main/app/prometheus/agent.py), code:bash (git mv main/app/prometheus/summarizer.py main/app/prometheus) (+21 more) ### Community 8 - "Device Detection" -Cohesion: 0.06 -Nodes (15): HarnessState, Retrieve a value from state. Returns default if key not found., Return a copy of the current state., Format state as a string for injection into the LLM context., Check if state changed since last reset., Reset the changed flag. Returns the previous state., Clear all state data., In-memory state dict that persists across loop iterations within a single reques (+7 more) +Cohesion: 0.05 +Nodes (16): HarnessState, Retrieve a value from state. Returns default if key not found., Return a copy of the current state., Format state as a string for injection into the LLM context., Check if state changed since last reset., Reset the changed flag. Returns the previous state., Clear all state data., In-memory state dict that persists across loop iterations within a single reques (+8 more) ### Community 9 - "Server Configuration" Cohesion: 0.11 Nodes (17): code:python (def filterCotationColumn(series: pd.Series, startDate, endDa), code:bash (git add -A), code:bash (git add main/app/stocks_api/query.py), code:python (def buildCotationDateIndex(df: pd.DataFrame, col: str = "COT), code:python (def filterCotationColumn(series: pd.Series, startDate, endDa), code:bash (git add main/app/stocks_api/cache.py main/app/stocks_api/que), code:python (PARQUET_PATH = Path(__file__).parent / "stocks_cache.parquet), code:bash (git add main/app/stocks_api/cache.py) (+9 more) ### Community 10 - "Prometheus Memory" -Cohesion: 0.05 -Nodes (35): Tests for queryCotations and /stocks/cotations., 2 tickers x 2 rows. Rows 0,2 are 2024-01-15; rows 1,3 are 2024-06-15. M, Tests for queryCotations and /stocks/cotations., 4 rows for 2 tickers -> 2 results, one per ticker, both with latest TIME., 4 rows for 2 tickers -> 2 results, one per ticker, both with latest TIME., 2 tickers x 2 rows. Rows 0,2 are 2024-01-15; rows 1,3 are 2024-06-15. M, dates="2016-12-02" should keep only the 02-12-2016 entry in each JSON list., dates="2016-12-02" should keep only the 02-12-2016 entry in each JSON list. (+27 more) +Cohesion: 0.06 +Nodes (27): Tests for queryCotations and /stocks/cotations., 2 tickers x 2 rows. Rows 0,2 are 2024-01-15; rows 1,3 are 2024-06-15. M, Tests for queryCotations and /stocks/cotations., 4 rows for 2 tickers -> 2 results, one per ticker, both with latest TIME., 4 rows for 2 tickers -> 2 results, one per ticker, both with latest TIME., 2 tickers x 2 rows. Rows 0,2 are 2024-01-15; rows 1,3 are 2024-06-15. M, dates="2016-12-02" should keep only the 02-12-2016 entry in each JSON list., dates="2016-12-02" should keep only the 02-12-2016 entry in each JSON list. (+19 more) ### Community 11 - "Auth Utilities & SSO" Cohesion: 0.05 @@ -736,16 +732,16 @@ Cohesion: 0.06 Nodes (31): code:python ("""Measure whether the stocks query hot path is GIL-bound.), code:bash (git add main/utils/migrator.py tests/test_migrator_guard.py), code:python (import importlib), code:python (DB_POOL_SIZE = int(os.getenv("DB_POOL_SIZE", "20"))), code:bash (git add config.py tests/test_config_pools.py), code:python (import importlib), code:python (if __name__ == "__main__":), code:python (if len(instances) > 1 and fcntl is None: # pragma: no cover) (+23 more) ### Community 14 - "User Roles & Permissions" -Cohesion: 0.05 -Nodes (36): _make_stocksapi_client(), Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental. (+28 more) +Cohesion: 0.08 +Nodes (24): _make_stocksapi_client(), Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont, Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont, Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont, Covers lines 52-53: user without GENERATE_API_KEYS permission gets 403., Covers lines 52-53: user without GENERATE_API_KEYS permission gets 403., Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont, Covers lines 52-53: user without GENERATE_API_KEYS permission gets 403. (+16 more) ### Community 15 - "Community 15" Cohesion: 0.05 Nodes (38): code:block1 (User 123: "Analyze PETR4 vs VALE3 correlation"), code:python (from main.app.prometheus.sandbox import SandboxManager), code:python (TOOL_REGISTRY: dict[str, Any] = {), code:bash (git add main/app/prometheus/tools.py tests/test_sandbox_tool), code:python (import pytest), code:python (from main.app.prometheus.sandbox import SandboxManager), code:python (async def streamMessage(self, query=None, sessionId=None, db), code:python (## Code Sandbox (On-Demand)) (+30 more) ### Community 17 - "Community 17" -Cohesion: 0.11 -Nodes (17): Multiple search terms with tickerIndex., Multiple search terms with tickerIndex., Multiple search terms with tickerIndex., Search with no index match falls back to string startswith., Search with no index match falls back to string startswith., Search with no index match falls back to string startswith., Multiple search terms with tickerIndex., Multiple search terms with tickerIndex. (+9 more) +Cohesion: 0.08 +Nodes (23): search.strip() == '' should still dedup (line 181)., search.strip() == '' should still dedup (line 181)., search.strip() == '' should still dedup (line 181)., DataFrame without TIME column., Invalid date -> inner 400 caught by outer except -> 500., DataFrame without TIME column., DataFrame without TIME column., search.strip() == '' should still dedup (line 181). (+15 more) ### Community 18 - "Community 18" Cohesion: 0.07 @@ -764,36 +760,36 @@ Cohesion: 0.14 Nodes (13): benchOnce(), main(), batchCosineSimilarity(), decodeEmbeddings(), normalizeRows(), Empty matrix → empty array., Single row matches cosine_similarity., Multiple rows ranked correctly. (+5 more) ### Community 22 - "Community 22" -Cohesion: 0.1 -Nodes (13): filterCotationColumn(), Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., GET /cotations without search returns 422., GET /cotations without search returns 422. (+5 more) +Cohesion: 0.14 +Nodes (7): filterCotationColumn(), Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., TestQueryLiveCotation ### Community 23 - "Community 23" Cohesion: 0.07 Nodes (35): Admin Access, API endpoints, API keys (Stocks API), code:bash (curl http://localhost:3200/user/health), code:mermaid (graph TD), code:bash (curl -X DELETE -H "Authorization: Bearer " http://loc), code:json ({), code:bash (curl -X POST -H "Authorization: Bearer " http://local) (+27 more) ### Community 24 - "Community 24" -Cohesion: 0.06 -Nodes (6): Tests for agent <-> persistent sandbox integration (Task 3)., Verify the agent uses getOrCreate + syncToSandbox/syncFromSandbox., Test the premium gating logic used in streamMessage., TestAgentSandboxIntegration, TestPersistentSandboxLifecycle, TestPremiumCheck +Cohesion: 0.09 +Nodes (5): Tests for agent <-> persistent sandbox integration (Task 3)., Verify the agent uses getOrCreate + syncToSandbox/syncFromSandbox., Test the premium gating logic used in streamMessage., TestPersistentSandboxLifecycle, TestPremiumCheck ### Community 25 - "Community 25" -Cohesion: 0.1 -Nodes (9): Tests for input validation via HTTP endpoints. Validation is now inline via Bod, PUT /prometheus/sessions/{sessionId} — validates title via Body(...), POST /prometheus/chat/stream — validates query via Body(...), Test that endpoints reject requests with missing required fields., POST /prometheus/sessions — validates title via Body(...), TestChatValidation, TestMissingBody, TestPrometheusSessionValidation (+1 more) +Cohesion: 0.06 +Nodes (13): Tests for input validation via HTTP endpoints. Validation is now inline via Bod, PUT /prometheus/sessions/{sessionId} — validates title via Body(...), POST /prometheus/chat/stream — validates query via Body(...), POST /auth/register — validates username, email, password via Body(...), Test that endpoints reject requests with missing required fields., POST /auth/login — validates username, password via Body(...), POST /prometheus/sessions — validates title via Body(...), TestChatValidation (+5 more) ### Community 26 - "Community 26" -Cohesion: 0.12 -Nodes (20): createKey(), _hash_key(), hashKey(), Return SHA-256 hex digest of the given key., Test that concurrent requests are properly serialized at DB level. Th, Test edge case: request exactly at quota limit., Test edge case: request exactly at quota limit., Test that increment works from zero usage. (+12 more) +Cohesion: 0.08 +Nodes (27): _hash_key(), hashKey(), Return SHA-256 hex digest of the given key., dbSession(), Tests for atomic API key quota enforcement (race condition fix). Verifies tha, Test that concurrent requests are properly serialized at DB level. Th, Test edge case: request exactly at quota limit., Test edge case: request exactly at quota limit. (+19 more) ### Community 27 - "Community 27" Cohesion: 0.15 Nodes (15): getUserMemories(), getRelevanceScore(), _FakeMemory, A memory with no lastAccessedAt should use baseScore as-is., Scores are deterministic — no cron mutation needed., Same memory at different points in time yields different scores., A memory accessed 10x (baseScore 1.0) should still outrank a memory acce, A rarely-used old memory should lose to a popular fresh one. (+7 more) ### Community 28 - "Community 28" -Cohesion: 0.05 -Nodes (42): Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Pass field name WITHOUT year (how categorizeColumns returns them)., Pass field name WITHOUT year (how categorizeColumns returns them)., No historical data columns -> inner 400 caught by outer except -> 500., Pass field name WITHOUT year (how categorizeColumns returns them). (+34 more) +Cohesion: 0.06 +Nodes (34): Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Pass field name WITHOUT year (how categorizeColumns returns them)., Pass field name WITHOUT year (how categorizeColumns returns them)., No historical data columns -> inner 400 caught by outer except -> 500., Pass field name WITHOUT year (how categorizeColumns returns them). (+26 more) ### Community 29 - "Community 29" -Cohesion: 0.09 -Nodes (15): PrometheusGenerator, _make_generator(), Tests to increase coverage for: - main/app/prometheus/generation.py - main/a, test_execute_workflow_basic_no_history(), test_execute_workflow_global_request_api_error(), test_execute_workflow_global_request_status_not_200(), test_execute_workflow_global_request_with_api_key(), test_execute_workflow_session_db_exception() (+7 more) +Cohesion: 0.04 +Nodes (42): SessionManager, PrometheusChatManager, PrometheusGenerator, Thread-safe proxy that delegates to per-thread sessions., SessionProxy, _make_generator(), Tests to increase coverage for: - main/app/prometheus/generation.py - main/a, Cover getGoogleSSO (lines 6-14). (+34 more) ### Community 30 - "Community 30" Cohesion: 0.07 @@ -832,8 +828,8 @@ Cohesion: 0.07 Nodes (27): code:json ([), code:javascript (const loadHistory = async (sid) => {), code:jsx (export default function MessageList({ messages, toolEvents, ), code:javascript (const loadHistory = async (sid) => {), code:jsx (export default function AgentLoop({ toolEvents, turnMetrics ), code:bash (git add frontend/src/App.jsx frontend/src/components/Message), code:bash (docker-compose up -d --build), code:sql (SELECT COUNT(*) FROM prometheus WHERE JSON_CONTAINS_PATH(his) (+19 more) ### Community 39 - "Community 39" -Cohesion: 0.05 -Nodes (40): Invalid date -> inner 400 passes through (not wrapped as 500)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., search.strip() == '' should still dedup (line 181)., search.strip() == '' should still dedup (line 181)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500. (+32 more) +Cohesion: 0.07 +Nodes (25): Two dates in the range, both valid., Two dates in the range, both valid., Two dates in the range, both valid., Search with no index match falls back to string startswith., Search with no index match falls back to string startswith., search.strip() == '' should still dedup (line 181)., Search with no index match falls back to string startswith., Two dates in the range, both valid. (+17 more) ### Community 40 - "Community 40" Cohesion: 0.12 @@ -848,32 +844,32 @@ Cohesion: 0.09 Nodes (16): StocksCacheManager, Tests for dynamic ticker index feature, Ticker index should be built when cache is loaded, Ticker index should contain all tickers from cache, Ticker index should be case-insensitive, Looking up ticker should return valid row index, Ticker index should be rebuilt when cache refreshes, TestTickerIndex (+8 more) ### Community 43 - "Community 43" -Cohesion: 0.13 -Nodes (7): authenticateUser(), createUserAccount(), createAccessToken(), hashPassword(), verifyPassword(), TestAuthUtil, TestAuthUtilEdgeCases +Cohesion: 0.12 +Nodes (6): authenticateUser(), createUserAccount(), hashPassword(), verifyPassword(), TestAuthUtil, TestAuthUtilEdgeCases ### Community 44 - "Community 44" -Cohesion: 0.14 -Nodes (3): UserSession, TestSessionExpiration, TestUserSessionModel +Cohesion: 0.08 +Nodes (8): createSession(), getSessionById(), parseDeviceFields(), revokeSession(), validateSession(), UserSession, TestSessionExpiration, TestUserSessionModel ### Community 45 - "Community 45" -Cohesion: 0.06 -Nodes (36): AuthenticationManager, IntFlag, Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 28: GET /auth/health. (+28 more) +Cohesion: 0.03 +Nodes (89): AuthenticationManager, IntFlag, OrunmilaMemory, Orunmila, OrunmilaChatManager, MemoryCandidate, OrunmilaMemory, Covers line 28: GET /auth/health. (+81 more) ### Community 46 - "Community 46" Cohesion: 0.09 Nodes (21): Regression: queryFundamental must not mutate the shared cache TIME column., Regression: queryFundamental must not mutate the shared cache TIME column., Regression: queryFundamental must not mutate the shared cache TIME column., Single invalid date -> inner 400 passes through., Single invalid date -> inner 400 caught by outer except -> 500., Single invalid date -> inner 400 caught by outer except -> 500., Single invalid date -> inner 400 caught by outer except -> 500., Invalid fields now raise 400 with actionable error message. (+13 more) ### Community 47 - "Community 47" -Cohesion: 0.1 -Nodes (17): _make_user_client(), Return (client, app) with user router and mocked deps., Covers line 24: GET /user/me returns currentUser., Covers line 24: GET /user/me returns currentUser., Covers line 24: GET /user/me returns currentUser., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise. (+9 more) +Cohesion: 0.14 +Nodes (12): _make_user_client(), Return (client, app) with user router and mocked deps., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise., Covers lines 53-54, 56: admin access granted / denied., Covers lines 53-54, 56: admin access granted / denied., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise. (+4 more) ### Community 48 - "Community 48" Cohesion: 0.06 Nodes (34): Backend (COMMIT), code:bash (cd frontend && pnpm add @openuidev/react-lang), code:bash (rm frontend/src/components/MdocMessage.jsx), code:python ("""OpenUI Lang system prompt section for Prometheus agent.), code:block12, code:block13, code:block14, code:block15 (+26 more) ### Community 49 - "Community 49" -Cohesion: 0.07 -Nodes (30): dispatchToolCall(), TDD tests: verify memory tools are wired into the Prometheus agent. RED: Thes, dispatchToolCall must route memory tool names via TOOL_REGISTRY., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., dispatchToolCall must route memory tool names to executeMemoryTool. (+22 more) +Cohesion: 0.11 +Nodes (20): dispatchToolCall(), Pytest Testing, TDD tests: verify memory tools are wired into the Prometheus agent. RED: Thes, test_memory_tool_skipped_without_user(), test_non_memory_tool_not_routed_to_executeMemoryTool(), test_non_registry_tool_not_routed(), test_save_memory_routed_to_executeMemoryTool(), test_save_memory_routed_via_registry() (+12 more) ### Community 50 - "Community 50" Cohesion: 0.07 @@ -908,24 +904,28 @@ Cohesion: 0.09 Nodes (15): Performance benchmark tests for stocks API, Performance benchmark tests for stocks API, Ticker index lookup should be O(1) - very fast, Ticker index lookup should be O(1) - very fast, Prefix scan should be much slower than index lookup, Prefix scan should be much slower than index lookup, Index lookup should be significantly faster than scan, Index lookup should be significantly faster than scan (+7 more) ### Community 58 - "Community 58" -Cohesion: 0.21 -Nodes (12): googleCallback(), isSecureScheme(), issueSessionCookie(), login(), logout(), register(), requireServiceToken(), resolveCookieDomain() (+4 more) +Cohesion: 0.15 +Nodes (17): getGoogleSSO(), createAccessToken(), googleCallback(), googleLogin(), isSecureScheme(), issueSessionCookie(), login(), logout() (+9 more) ### Community 59 - "Community 59" Cohesion: 0.17 Nodes (20): Tests for main/utils/connectivity.py — covers all branches., test_both_engines_ok(), test_connection_error(), test_generic_exception(), test_non_200_status(), test_non_stocks_prefix(), test_request_exception(), test_service_not_found() (+12 more) ### Community 60 - "Community 60" -Cohesion: 0.09 -Nodes (7): Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., TestSessionManager +Cohesion: 0.06 +Nodes (19): Exercises the tzinfo-is-None branch (line 144-148)., Exercises the tzinfo-is-None branch (line 144-148)., Exercises the expiresAt-is-None branch (line 143)., Exercises the expiresAt-is-None branch (line 143)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154). (+11 more) + +### Community 61 - "Community 61" +Cohesion: 0.13 +Nodes (4): PrometheusSession, User, TestPrometheusSessionModel, TestUserModel ### Community 62 - "Community 62" Cohesion: 0.1 Nodes (20): architectures, attention_probs_dropout_prob, gradient_checkpointing, hidden_act, hidden_dropout_prob, hidden_size, initializer_range, intermediate_size (+12 more) ### Community 63 - "Community 63" -Cohesion: 0.13 -Nodes (13): Covers lines 100-104, 106: GET /user/sessions/current., Covers lines 100-104, 106: GET /user/sessions/current., Covers lines 100-104, 106: session found., Covers lines 100-104, 106: session found., Covers lines 100-104, 106: GET /user/sessions/current., Covers lines 100-104, 106: session found., Covers line 104: session not found., Covers line 104: session not found. (+5 more) +Cohesion: 0.09 +Nodes (19): Covers lines 66, 68-72, 74: full sessions listing., Covers lines 66, 68-72, 74: full sessions listing., Covers lines 66, 68-72, 74: full sessions listing., Covers lines 66, 68-72, 74: full sessions listing., Covers lines 100-104, 106: session found., Covers lines 100-104, 106: session found., Covers lines 100-104, 106: session found., Covers line 104: session not found. (+11 more) ### Community 64 - "Community 64" Cohesion: 0.06 @@ -940,12 +940,12 @@ Cohesion: 0.1 Nodes (19): 1. Explore Agent — Prometheus Architecture, 2. MySQL Vector Storage (Researcher), 3. Memory Patterns (Researcher), A. Vector Embedding Integration, B. Pandas-First Vector Cache, C. Search Upgrade, code:python (class MemoryCache:), code:python (def searchMemories(cls, db, userId, query, embedding=None, l) (+11 more) ### Community 67 - "Community 67" -Cohesion: 0.06 -Nodes (34): execute_code(), get_wallet_positions(), get_wallet_rebalance(), get_wallet_summary(), list_files(), Execute Python code in an isolated sandbox. Use for quantitative analysis,, Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e. (+26 more) +Cohesion: 0.07 +Nodes (29): execute_code(), get_wallet_allocation(), get_wallet_performance(), get_wallet_summary(), list_files(), Execute Python code in an isolated sandbox. Use for quantitative analysis,, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri (+21 more) ### Community 68 - "Community 68" -Cohesion: 0.14 -Nodes (30): narrate_positions(), Narrate the user's wallet positions in plain language. Read-only summary, addEntry(), applyEntries(), cachedPerformance(), createWallet(), deleteEntry(), fetchCachedClose() (+22 more) +Cohesion: 0.15 +Nodes (28): addEntry(), applyEntries(), cachedPerformance(), createWallet(), deleteEntry(), fetchCachedClose(), fetchLivePrices(), fetchMarketDividends() (+20 more) ### Community 69 - "Community 69" Cohesion: 0.2 @@ -960,12 +960,12 @@ Cohesion: 0.11 Nodes (19): API Key System, B3 Scraper, Fundamental Data, Gemini Model, Historical Data, Ma'at Stock Algorithm, Mansa Server, MySQL Database (+11 more) ### Community 72 - "Community 72" -Cohesion: 0.17 -Nodes (4): POST /memories rejects missing key., POST /memories rejects missing value., Full integration tests using mocked MemoryManager., TestMemoryEndpointsIntegration +Cohesion: 0.09 +Nodes (10): Verify memory endpoints exist and are wired correctly., GET /prometheus/memories exists., POST /memories rejects missing key., POST /memories rejects missing value., POST /prometheus/memories exists., DELETE /prometheus/memories/{id} exists., GET /memories requires authentication., Full integration tests using mocked MemoryManager. (+2 more) ### Community 73 - "Community 73" -Cohesion: 0.16 -Nodes (7): _parse_date(), parseDate(), parseDateEnd(), parseDateRange(), parseDateStart(), TestParseDateRange, TestParseDateRange +Cohesion: 0.13 +Nodes (11): autoAbbreviate(), dedupAbbrev(), detectNestedFields(), generateAbbreviations(), _parse_date(), parseDate(), parseDateEnd(), parseDateRange() (+3 more) ### Community 74 - "Community 74" Cohesion: 0.11 @@ -1000,7 +1000,7 @@ Cohesion: 0.14 Nodes (14): getLiveCotation(), Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th (+6 more) ### Community 82 - "Community 82" -Cohesion: 0.08 +Cohesion: 0.09 Nodes (27): buildFeatherCache(), Feather build / read helpers for the stocks cache. Owns the on-disk layout (CAC, Return (engine, featherPath, nestedPath), preferring live values on the cach, Return (engine, featherPath, nestedPath), preferring live values on the cach, readFeatherDataFrame(), _runtimeConf(), tryBuildLock(), arrowTypeFor() (+19 more) ### Community 83 - "Community 83" @@ -1020,12 +1020,12 @@ Cohesion: 0.08 Nodes (24): code:python (def test_build_requests_presorted_rows(monkeypatch, tmp_path), code:python (def test_read_feather_dataframe_uses_arrow_backed_columns(tm), code:python (from pyarrow import feather), code:python (def readFeatherDataFrame(path) -> tuple[pd.DataFrame, bool]:), code:python (df, presorted = readFeatherDataFrame(CACHE_FEATHER_PATH)), code:bash (git add main/app/stocks_api/cache.py tests/test_stocks_cache), code:python (def test_deserialize_jsoncolumns_handles_arrowdtype_binary()), code:python (if col in JSON_COLUMNS and (df[col].dtype == "object" or pd.) (+16 more) ### Community 87 - "Community 87" -Cohesion: 0.1 -Nodes (19): countTokens(), getTokenizer(), PrometheusSummarizer, Summarize conversation history into episode summaries., Check if accumulated tokens exceed episode threshold., Get messages since the last episode for summarization., Check if accumulated tokens exceed episode threshold., Check if accumulated tokens exceed episode threshold. (+11 more) +Cohesion: 0.12 +Nodes (16): countTokens(), getTokenizer(), PrometheusSummarizer, Summarize conversation history into episode summaries., Check if accumulated tokens exceed episode threshold., Get messages since the last episode for summarization., Check if accumulated tokens exceed episode threshold., Check if accumulated tokens exceed episode threshold. (+8 more) ### Community 88 - "Community 88" -Cohesion: 0.12 -Nodes (7): Cover all methods in authentication.py (lines 13-75)., Cover all methods in authentication.py (lines 13-75)., Cover all methods in authentication.py (lines 13-75)., Cover all methods in authentication.py (lines 13-75)., Cover all methods in authentication.py (lines 13-75)., Cover all methods in authentication.py (lines 13-75)., TestAuthenticationManager +Cohesion: 0.18 +Nodes (20): countMemories(), deleteMemory(), extract(), findSimilarKey(), fullTextSearch(), getClient(), getMatrix(), getMemoryLimit() (+12 more) ### Community 89 - "Community 89" Cohesion: 0.08 @@ -1044,8 +1044,8 @@ Cohesion: 0.09 Nodes (21): aliases, components, hooks, lib, ui, utils, iconLibrary, menuAccent (+13 more) ### Community 93 - "Community 93" -Cohesion: 0.14 -Nodes (10): _get_client(), getClient(), Prometheus, Lazy module-level singleton so the genai client is created once, not per request, System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about harness state usage., TestSendMessageStateIntegration (+2 more) +Cohesion: 0.12 +Nodes (10): System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about harness state usage., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., TestSendMessageStateIntegration (+2 more) ### Community 94 - "Community 94" Cohesion: 0.12 @@ -1068,19 +1068,19 @@ Cohesion: 0.28 Nodes (6): extractTokenPayload(), Tests for extractTokenPayload — the standalone token extraction dependency., Create a mock Starlette Request with given headers., Authorization: Bearer (empty) — no token after Bearer., Authorization: Basic xxx — not Bearer, so no token found., TestExtractTokenPayload ### Community 99 - "Community 99" -Cohesion: 0.05 -Nodes (34): _make_prometheus_client(), Generic Exception in chat propagates to FastAPI's default 500 handler., Generic Exception in chat propagates to FastAPI's default 500 handler., Generic Exception in chat propagates to FastAPI's default 500 handler., Generic Exception in chat propagates via SSE error event., Covers line 125, 126-128: generic Exception in chat., Return (client, app) with prometheus router and mocked deps., Covers lines 33-36: GET /prometheus/sessions. (+26 more) +Cohesion: 0.09 +Nodes (19): _make_prometheus_client(), Return (client, app) with prometheus router and mocked deps., Covers lines 62-63, 65-68: PUT /prometheus/sessions/{sessionId}., Covers lines 62-63, 65-68: PUT /prometheus/sessions/{sessionId}., Covers lines 65-68: title updated successfully., Covers lines 65-68: title updated successfully., Covers lines 62-63, 65-68: PUT /prometheus/sessions/{sessionId}., Covers lines 65-68: title updated successfully. (+11 more) ### Community 100 - "Community 100" -Cohesion: 0.06 -Nodes (14): _assert_gemini_safe(), Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Regression: HarnessState must never leak into tool signatures., Regression: HarnessState must never leak into tool signatures., Assert a tool function has only Gemini-compatible parameter types., Assert a tool function has only Gemini-compatible parameter types., test_get_state_no_state_returns_error() (+6 more) +Cohesion: 0.09 +Nodes (13): _assert_gemini_safe(), Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Regression: HarnessState must never leak into tool signatures., Regression: HarnessState must never leak into tool signatures., Assert a tool function has only Gemini-compatible parameter types., Assert a tool function has only Gemini-compatible parameter types., test_get_state_no_state_returns_error() (+5 more) ### Community 101 - "Community 101" -Cohesion: 0.17 -Nodes (20): closeOwnSession(), popAuthSession(), Shared auth-guard + own-SessionLocal convention every tool repeats. Returns, Store a memory about the user's preferences, analysis results, or feedback., Search user's saved memories, preferences, and past analysis context. Use t, save_memory(), search_memory(), ensureOwnership() (+12 more) +Cohesion: 0.23 +Nodes (21): closeOwnSession(), popAuthSession(), Shared auth-guard + own-SessionLocal convention every tool repeats. Returns, ensureOwnership(), get_wallet_allocation(), get_wallet_performance(), get_wallet_positions(), get_wallet_rebalance() (+13 more) ### Community 102 - "Community 102" -Cohesion: 0.12 +Cohesion: 0.11 Nodes (11): BaseSettings, BaseMansaSettings, DiscordSettings, MysqlSettings, OrunmilaSettings, PrometheusSettings, ScraperSettings, StocksApiSettings (+3 more) ### Community 103 - "Community 103" @@ -1099,10 +1099,6 @@ Nodes (5): buildClient(), connect(), ensureFastmcp(), MCPClientPool, _parseServe Cohesion: 0.22 Nodes (3): parseYearInput(), TestParseYearInput, TestParseYearInput -### Community 107 - "Community 107" -Cohesion: 0.22 -Nodes (4): Authentication System, Google OAuth, JWT Authentication, TestSessionExpiryConfig - ### Community 108 - "Community 108" Cohesion: 0.14 Nodes (13): all-MiniLM-L6-v2, Background, code:block1 (pip install -U sentence-transformers), code:python (from sentence_transformers import SentenceTransformer), code:python (from transformers import AutoTokenizer, AutoModel), Fine-tuning, Hyper parameters, Intended uses (+5 more) @@ -1120,7 +1116,7 @@ Cohesion: 0.14 Nodes (13): code:python (import pytest), code:python (import logging), code:bash (git add main/app/prometheus/state.py tests/test_harness_stat), File Map, Global Constraints, Phase 1: HarnessState (In-Memory Agent Scratchpad), Prometheus Harness — Master Implementation Plan (v2: CubeSandbox + On-Demand), Relationship to Existing Systems (+5 more) ### Community 112 - "Community 112" -Cohesion: 0.11 +Cohesion: 0.1 Nodes (16): Calling with all None returns 400., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Calling with all None returns 400. (+8 more) ### Community 113 - "Community 113" @@ -1136,8 +1132,8 @@ Cohesion: 0.17 Nodes (11): dateOnly(), EditDividendDialog(), EditLotDialog(), fmtBRL(), fmtMoney(), KIND_STYLES, lotTitle(), deleteDividend() (+3 more) ### Community 116 - "Community 116" -Cohesion: 0.15 -Nodes (13): _build_system_prompt(), buildSystemPrompt(), chatSession(), _execute_memory_tool(), executeMemoryTool(), _get_memory_tools(), openMCPClients(), persistEvent() (+5 more) +Cohesion: 0.12 +Nodes (16): _build_system_prompt(), buildSystemPrompt(), chatSession(), _execute_memory_tool(), executeMemoryTool(), _get_client(), _get_memory_tools(), getClient() (+8 more) ### Community 117 - "Community 117" Cohesion: 0.15 @@ -1152,8 +1148,8 @@ Cohesion: 0.07 Nodes (26): code:python ("""Tests for SandboxManager file mutation helpers (delete_fi), code:python (from main.app.prometheus.sandbox import SandboxManager, host), code:python (@router.post("/workspace/upload")), code:bash (git add main/controller/prometheus_controller.py tests/test_), code:python (from unittest.mock import patch, MagicMock), code:python (from main.app.prometheus.sandbox import SandboxManager, host), code:python (async def serve_file(path: str, **_) -> dict:), code:python ("serve_file": serve_file,) (+18 more) ### Community 120 - "Community 120" -Cohesion: 0.1 -Nodes (32): _make_auth_client(), Tests to cover uncovered lines across controllers, UserManager, and auth util., Covers lines 44-54, 63, 66-71: register success, ValueError, generic Exception., Covers lines 44-54, 63, 66-71: register success, ValueError, generic Exception., Return (client, app) with auth + user routers and mocked getSession., Covers lines 107, 109-130, 133: logout token extraction and revocation., Covers lines 111-113: token extracted from Authorization Bearer header., Covers lines 155-156, 158, 160-168, 170-177, 179-184, 186, 190-204: googleCallba (+24 more) +Cohesion: 0.16 +Nodes (20): _make_auth_client(), Tests to cover uncovered lines across controllers, UserManager, and auth util., Return (client, app) with auth + user routers and mocked getSession., test_callback_existing_user(), test_callback_generic_exception(), test_callback_new_user(), test_callback_no_user_info(), test_callback_with_state_redirect() (+12 more) ### Community 121 - "Community 121" Cohesion: 0.21 @@ -1216,8 +1212,8 @@ Cohesion: 0.09 Nodes (23): _getDb(), Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use (+15 more) ### Community 137 - "Community 137" -Cohesion: 0.05 -Nodes (50): buildSystemPrompt(), getClient(), persistEvent(), buildSummary(), countTokens(), dedup(), extractDecisions(), extractMetrics() (+42 more) +Cohesion: 0.18 +Nodes (15): buildSummary(), countTokens(), dedup(), extractDecisions(), extractMetrics(), extractSnapshots(), extractTickers(), extractToolCalls() (+7 more) ### Community 138 - "Community 138" Cohesion: 0.18 @@ -1228,8 +1224,8 @@ Cohesion: 0.24 Nodes (6): Dataset, produce_data(), Train script for a single file Need to set the TPU address first: export XRT_TP, A class that handles the reddit data files, A class that handles one dataset, RedditDataset ### Community 140 - "Community 140" -Cohesion: 0.09 -Nodes (31): PrometheusMemory, PrometheusMemory, MemoryManager, PrometheusMemory, All memory operations. Stateless class methods., PrometheusService, TestDifferentKeysNoMerge, TestExactSameKeyUpdates (+23 more) +Cohesion: 0.05 +Nodes (49): PrometheusMemory, PrometheusMemory, Prometheus, MemoryManager, PrometheusMemory, All memory operations. Stateless class methods., PrometheusService, _count_memories() (+41 more) ### Community 141 - "Community 141" Cohesion: 0.24 @@ -1260,20 +1256,20 @@ Cohesion: 0.23 Nodes (3): categorizeColumns(), TestCategorizeColumns, TestCategorizeColumns ### Community 148 - "Community 148" -Cohesion: 0.09 -Nodes (19): Covers lines 114-115, 117-120, 122, 125: POST /prometheus/chat., Covers lines 114-115, 117-120, 122, 125: POST /prometheus/chat., Covers lines 111-112: sessionId is None, new session created., Covers lines 111-112: sessionId is None, new session created., Covers lines 109-136: POST /prometheus/chat/stream (SSE)., Covers lines 118-119: sessionId is None, new session created., Covers lines 114-115, 117-120, 122: existing session with verified ownership., Covers lines 114-115, 117-120, 122: existing session with verified ownership. (+11 more) +Cohesion: 0.07 +Nodes (24): Covers lines 114-115, 117-120, 122, 125: POST /prometheus/chat., Covers lines 114-115, 117-120, 122, 125: POST /prometheus/chat., Covers lines 111-112: sessionId is None, new session created., Covers lines 111-112: sessionId is None, new session created., Covers lines 109-136: POST /prometheus/chat/stream (SSE)., Covers lines 118-119: sessionId is None, new session created., Covers lines 114-115, 117-120, 122: existing session with verified ownership., Covers lines 114-115, 117-120, 122: existing session with verified ownership. (+16 more) ### Community 149 - "Community 149" -Cohesion: 0.18 -Nodes (5): createSession(), getSessionById(), parseDeviceFields(), revokeSession(), validateSession() +Cohesion: 0.15 +Nodes (12): Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., save_memory(), embed(), Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback. (+4 more) ### Community 151 - "Community 151" Cohesion: 0.2 Nodes (3): MEMORY_TOOLS must be defined as a Tool wrapping FunctionDeclarations., MEMORY_TOOLS must be a list of callables with proper signatures., TestMemoryToolsDefinition ### Community 152 - "Community 152" -Cohesion: 0.13 -Nodes (26): get_wallet_allocation(), get_wallet_performance(), list_wallet_earnings(), Break wallet equity down by ticker or asset type. Read-only: never mutate, Break wallet equity down by ticker or asset type. Read-only: never mutate, List accrued earnings (dividends, JSCP) for a wallet. Read-only: never mu, List accrued earnings (dividends, JSCP) for a wallet. Read-only: never mu, Compute time-weighted return, volatility, and dividends for a wallet or ticker. (+18 more) +Cohesion: 0.16 +Nodes (21): list_wallet_earnings(), narrate_positions(), Narrate the user's wallet positions in plain language. Read-only summary, List accrued earnings (dividends, JSCP) for a wallet. Read-only: never mu, List accrued earnings (dividends, JSCP) for a wallet. Read-only: never mu, listEarnings(), syncEarnings(), addEntry() (+13 more) ### Community 153 - "Community 153" Cohesion: 0.11 @@ -1292,8 +1288,8 @@ Cohesion: 0.22 Nodes (8): API Endpoints, code:env (#), code:bash (python __init__.py), code:mermaid (graph TD), License, Prometheus, Usage, Workflow ### Community 157 - "Community 157" -Cohesion: 0.15 -Nodes (13): getFundamental(), Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret (+5 more) +Cohesion: 0.1 +Nodes (16): getFundamental(), JSONBytesResponse, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret (+8 more) ### Community 158 - "Community 158" Cohesion: 0.22 @@ -1324,8 +1320,8 @@ Cohesion: 0.2 Nodes (9): AccordionItem, BarChart, ContentCard, DataTable, Divider, ProgressFill, StatCard, TabGroup (+1 more) ### Community 165 - "Community 165" -Cohesion: 0.29 -Nodes (6): Exercises the expiresAt-is-None branch (line 143)., Exercises the expiresAt-is-None branch (line 143)., Exercises the expiresAt-is-None branch (line 143)., Exercises the expiresAt-is-None branch (line 143)., Exercises the expiresAt-is-None branch (line 143)., Exercises the expiresAt-is-None branch (line 143). +Cohesion: 0.18 +Nodes (6): buildSystemPrompt(), getClient(), persistEvent(), newTokenCache(), dispatchToolCall(), dispatchToolCall() ### Community 166 - "Community 166" Cohesion: 0.22 @@ -1348,8 +1344,8 @@ Cohesion: 0.25 Nodes (8): padding, direction, pad_id, pad_to_multiple_of, pad_token, pad_type_id, strategy, Fixed ### Community 172 - "Community 172" -Cohesion: 0.13 -Nodes (18): SessionManager, PrometheusChatManager, Cover getGoogleSSO (lines 6-14)., Cover getGoogleSSO (lines 6-14)., Cover __init__ and updateDates., Cover __init__ and updateDates (lines 22-37)., Cover streamMessage in agent.py., Cover sendMessage and streamMessage in agent.py. (+10 more) +Cohesion: 0.17 +Nodes (7): Different query parameters should not share cache, Cache should expire after TTL, Tests for query result caching, CacheManager should track cached queries, Query cache should have configurable TTL, getCachedStocks should support column filtering, TestQueryCaching ### Community 173 - "Community 173" Cohesion: 0.25 @@ -1400,8 +1396,8 @@ Cohesion: 0.38 Nodes (7): code:python (import pytest), code:python (from __future__ import annotations), code:bash (git add main/app/prometheus/context.py tests/test_context.py), Phase 4: ToolContext (Bundled Dispatch Dependencies), Phase 4: ToolContext (Replace God Function), Task 5: ToolContext — Dataclass for Agent Use, Task 5: ToolContext — Single Dispatch Object ### Community 186 - "Community 186" -Cohesion: 0.1 -Nodes (15): generateKey(), JSONBytesResponse, listFields(), Sends pre-serialized JSON bytes without re-encoding (cache-friendly)., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental. (+7 more) +Cohesion: 0.13 +Nodes (20): listFields(), Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental. (+12 more) ### Community 187 - "Community 187" Cohesion: 0.25 @@ -1416,8 +1412,8 @@ Cohesion: 0.33 Nodes (3): buildClient(), connect(), MCPClientPool ### Community 190 - "Community 190" -Cohesion: 0.29 -Nodes (6): Exercises the tzinfo-is-None branch (line 144-148)., Exercises the tzinfo-is-None branch (line 144-148)., Exercises the tzinfo-is-None branch (line 144-148)., Exercises the tzinfo-is-None branch (line 144-148)., Exercises the tzinfo-is-None branch (line 144-148)., Exercises the tzinfo-is-None branch (line 144-148). +Cohesion: 0.2 +Nodes (9): Invalid date -> inner 400 passes through (not wrapped as 500)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Two dates in the range, both valid. (+1 more) ### Community 191 - "Community 191" Cohesion: 0.33 @@ -1432,8 +1428,8 @@ Cohesion: 0.33 Nodes (6): normalizer, clean_text, handle_chinese_chars, lowercase, strip_accents, type ### Community 194 - "Community 194" -Cohesion: 0.08 -Nodes (23): Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers line 16: empty password raises ValueError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers line 16: empty password raises ValueError., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 45-51: verifyAccessToken with expired and invalid tokens. (+15 more) +Cohesion: 0.29 +Nodes (6): Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError. ### Community 195 - "Community 195" Cohesion: 0.33 @@ -1540,8 +1536,8 @@ Cohesion: 0.11 Nodes (21): execute_code(), Store a value in the harness state for this session. Use this to save inter, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Execute Python code in an isolated sandbox. Use for quantitative analysis,, Read a file from the workspace. Args: path: Path to the file (e. (+13 more) ### Community 222 - "Community 222" -Cohesion: 0.27 -Nodes (8): initialize(), P5: register memory maintenance on the shared scheduler. Kept in this ser, registerMemoryMaintenanceJob(), getSharedScheduler(), P5: single shared BackgroundScheduler for all services. Replaces the 4 per-serv, Return the process-wide scheduler, starting it on first use., Register func on the shared scheduler (replaces any same-id job). trigger i, registerJob() +Cohesion: 0.14 +Nodes (12): initialize(), P5: register memory maintenance on the shared scheduler. Kept in this ser, registerMemoryMaintenanceJob(), initialize(), P5: register the session-cleanup job on the shared scheduler. Kept in thi, registerSessionCleanupJobs(), UserService, getSharedScheduler() (+4 more) ### Community 223 - "Community 223" Cohesion: 0.4 @@ -1575,10 +1571,6 @@ Nodes (5): code:python (import pytest), code:python (import hashlib), code:bash Cohesion: 0.18 Nodes (11): 2.2.1 Complexity hotspots table (H1–H17 condensed to P0/P1/P2), 2.2.2 Blob inventory (LOC table + SRP evidence), 2.2.3 Mass data loads, 2.2.4 Phased fix roadmap (P0/P1/P2), §2.2 CODE EFFICIENCY — O(n²), Complexity & Blob Anti-Patterns, code:block4 (scraper.py:44 671 LOC — mass loads: SELECT * fetchma), code:powershell (ruff check . && ruff format --check .), code:powershell (pytest tests/test_stocks_cache_concurrency.py -v # ThreadPo) (+3 more) -### Community 231 - "Community 231" -Cohesion: 0.17 -Nodes (7): OrunmilaMemory, OrunmilaSession, Orunmila, createSession(), OrunmilaChatManager, MemoryCandidate, OrunmilaMemory - ### Community 232 - "Community 232" Cohesion: 0.4 Nodes (5): Bucket A: Security Fixes (quick wins, 30 min), Bucket B: DB Session Cleanup (medium, 1-2 hrs), Bucket C: Testing (medium, 2-3 hrs), Bucket D: Infrastructure (large, 4+ hrs), Recommended Delegation Buckets @@ -1588,8 +1580,8 @@ Cohesion: 0.4 Nodes (5): 8. Build Sequence (4 phases, each independently shippable), Phase 0 — Sandbox foundation (1-2 days, no user-facing change), Phase 1 — MCP exposure of STOCKS_API (1 day), Phase 2 — Refactor PROMETHEUS to agentic (3-5 days, the big one), Phase 3 — Hardening (1-2 days, can ship incrementally) ### Community 234 - "Community 234" -Cohesion: 0.1 -Nodes (27): chat_stream(), downloadWorkspaceFile(), getHistory(), resumeChatStream(), updateSessionTitle(), verifySessionOwnsership(), OrunmilaSandbox, create() (+19 more) +Cohesion: 0.11 +Nodes (25): chat_stream(), downloadWorkspaceFile(), getHistory(), resumeChatStream(), updateSessionTitle(), verifySessionOwnsership(), create(), delete_file() (+17 more) ### Community 236 - "Community 236" Cohesion: 0.5 @@ -1713,7 +1705,7 @@ Nodes (4): code:python (def test_session_scoped_memory(db_session, sample_user): ### Community 482 - "Community 482" Cohesion: 0.14 -Nodes (22): fetchCachedClose(), fetchLivePrices(), fetchMarketDividends(), fetchPadraoCloses(), stocksApiBase(), stocksApiHeaders(), fetchXangoScores(), getPositions() (+14 more) +Nodes (20): get_wallet_positions(), List wallet holdings with live prices, equity, allocation, and buy signals., List wallet holdings with live prices, equity, allocation, and buy signals., fetchLivePrices(), fetchXangoScores(), getPositions(), getRebalance(), pricePass() (+12 more) ### Community 483 - "Community 483" Cohesion: 0.5 @@ -1744,16 +1736,16 @@ Cohesion: 0.22 Nodes (8): API Endpoints, code:env (ORUNMILA_ENABLED=TRUE), code:bash (python run.py), code:mermaid (graph TD), License, Orunmila, Usage, Workflow ### Community 491 - "Community 491" -Cohesion: 0.09 -Nodes (5): Tests for main/utils/roles.py — covers requirePermission and edge cases., TestCheckAccess, TestPermissionAll, TestRequirePermission, TestRolesHierarchy +Cohesion: 0.1 +Nodes (4): Tests for main/utils/roles.py — covers requirePermission and edge cases., TestCheckAccess, TestRequirePermission, TestRolesHierarchy ### Community 492 - "Community 492" Cohesion: 0.33 Nodes (5): Baseline (lane 4), Export recipe, Move triggers (any one fires the migration), Options, Vector Scale-Up Runbook ### Community 493 - "Community 493" -Cohesion: 0.29 -Nodes (6): GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422. +Cohesion: 0.1 +Nodes (16): GET /memories requires USE_PROMETHEUS (basic USER role denied)., GET /stocks/realtime-cotation without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422. (+8 more) ### Community 495 - "Community 495" Cohesion: 0.05 @@ -1764,24 +1756,24 @@ Cohesion: 0.17 Nodes (7): Tests for dynamic ticker index feature, Ticker index should be built when cache is loaded, Ticker index should contain all tickers from cache, Ticker index should be case-insensitive, Looking up ticker should return valid row index, Ticker index should be rebuilt when cache refreshes, TestTickerIndex ### Community 498 - "Community 498" -Cohesion: 0.06 -Nodes (27): Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 126, 131, 135-136., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 127-129: session not found., Covers lines 127-129: session not found. (+19 more) +Cohesion: 0.1 +Nodes (17): Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 126, 131, 135-136., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 127-129: session not found., Covers lines 127-129: session not found. (+9 more) ### Community 499 - "Community 499" Cohesion: 0.2 Nodes (9): code:python (import numpy as np), code:python (def normalizeRows(matrix: np.ndarray) -> np.ndarray:), code:bash (git add main/app/prometheus/vector.py tests/test_vector_norm), code:python ("""One-shot: renormalize stored embeddings to unit norm. Usa), code:bash (git add scripts/backfill_normalize_embeddings.py), Global Constraints, Lane 1: Normalized Embeddings + Dot-Product Search Implementation Plan, Task 1: Normalize on encode + row-normalize helper (+1 more) ### Community 500 - "Community 500" -Cohesion: 0.16 -Nodes (17): createStoredApiKey(), hashApiKey(), initVerifyClient(), isValidStoredKey(), _serviceToken(), verifyAPIKey(), _verifyUrl(), Tests to increase coverage for query.py, key.py, and cache.py in stocks_api. (+9 more) +Cohesion: 0.13 +Nodes (21): generateKey(), createKey(), createStoredApiKey(), hashApiKey(), initVerifyClient(), isValidStoredKey(), _serviceToken(), verifyAPIKey() (+13 more) ### Community 501 - "Community 501" Cohesion: 0.22 Nodes (3): getCurrentSession(), getSessions(), sessionToDict() ### Community 503 - "Community 503" -Cohesion: 0.15 -Nodes (18): executeStateTool(), get_state(), Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, test_dispatch_get_state(), test_dispatch_set_state() (+10 more) +Cohesion: 0.16 +Nodes (17): executeStateTool(), get_state(), Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, test_dispatch_set_state(), test_get_state_all() (+9 more) ### Community 505 - "Community 505" Cohesion: 0.33 @@ -1812,33 +1804,29 @@ Cohesion: 0.18 Nodes (11): 2.0 Grounding: what the code actually does, 2.1 Hypotheses, 2.3 Scenarios, 2.4 Protocol, 2.5 Metrics, 2.6 Acceptance thresholds — **ALL PROPOSED, freeze after first real run**, 2.7 Results doc layout, 2.8 Feeding `/status` (TODO 14) (+3 more) ### Community 517 - "Community 517" -Cohesion: 0.28 +Cohesion: 0.26 Nodes (4): Shared query pipeline for historical and fundamental endpoints., Fetch live prices for B3 tickers via yfinance. B3 tickers must match, sanitizeNanValues(), StocksQueryManager ### Community 518 - "Community 518" -Cohesion: 0.1 -Nodes (15): create_memories(), Decay happens first, then archive check with new scores., Decay happens first, then archive check with new scores., Score that decays to >= threshold stays alive. 0.11 * 0.95 = 0.1045 >= 0.1., Score that decays to >= threshold stays alive. 0.12 * 0.90 = 0.108 >= 0.1., 89 days with low score → not archived (need > 90)., 89 days with low score → not archived (need > 90)., Helper to create memories with controlled baseScore, lastAccessedAt, accessCount (+7 more) +Cohesion: 0.42 +Nodes (7): fetchCachedClose(), fetchMarketDividends(), fetchPadraoCloses(), stocksApiBase(), stocksApiHeaders(), cachedPerformance(), getPerformance() ### Community 519 - "Community 519" Cohesion: 0.57 Nodes (6): addRole(), addRoleToUser(), getCurrentUser(), getRolesList(), hasRole(), toDict() ### Community 520 - "Community 520" -Cohesion: 0.16 -Nodes (9): pd.NA is not a string, so lambda returns it unchanged., All four SPECIAL_COLS should parse correctly when mixed with None., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., All four SPECIAL_COLS should parse correctly when mixed with None., All four SPECIAL_COLS should parse correctly when mixed with None. (+1 more) +Cohesion: 0.33 +Nodes (5): pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged. ### Community 521 - "Community 521" -Cohesion: 0.15 -Nodes (11): _count_memories(), _create_memory(), _get_memory(), Keys with Jaccard > 0.8 should merge., Keys with Jaccard > 0.8 should merge., Keys with low similarity should not merge., Keys with low similarity should not merge., Keys with low similarity should not merge. (+3 more) +Cohesion: 0.22 +Nodes (8): Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false. ### Community 522 - "Community 522" Cohesion: 0.18 Nodes (11): 2.0 Grounding: what the code actually does, 2.1 Hypotheses, 2.3 Scenarios, 2.4 Protocol, 2.5 Metrics, 2.6 Acceptance thresholds — **ALL PROPOSED, freeze after first real run**, 2.7 Results doc layout, 2.8 Feeding `/status` (TODO 14) (+3 more) -### Community 523 - "Community 523" -Cohesion: 0.14 -Nodes (15): Store a value in state. Marks state as changed for context injection., compactCotations(), compactRow(), compactValue(), compressResponse(), fixHeaders(), getAbbr(), getNest() (+7 more) - ### Community 524 - "Community 524" Cohesion: 0.36 Nodes (4): countTokens(), getTokenizer(), PrometheusSummarizer, smartTruncate() @@ -1853,11 +1841,11 @@ Nodes (7): buildKey(), clearAll(), getMatrix(), invalidateUser(), runAwait(), ma ### Community 528 - "Community 528" Cohesion: 0.17 -Nodes (6): FastAPI, PaginationParams, getWalletIdentity(), requireWalletOwnership(), resolveRawToken(), createWallet() +Nodes (10): Authentication System, introspectToken(), verifyAccessToken(), introspect(), FastAPI, Google OAuth, JWT Authentication, getWalletIdentity() (+2 more) ### Community 529 - "Community 529" -Cohesion: 0.07 -Nodes (26): Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 17, 22-27: user found, role not present, role added. (+18 more) +Cohesion: 0.18 +Nodes (9): Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails. (+1 more) ### Community 530 - "Community 530" Cohesion: 0.2 @@ -1880,8 +1868,8 @@ Cohesion: 0.13 Nodes (13): Covers lines 95-98: session deleted., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 95-98: DELETE /prometheus/sessions/{sessionId}., Covers lines 95-98: session deleted., Covers lines 96-97: session not found., Covers lines 95-98: DELETE /prometheus/sessions/{sessionId}. (+5 more) ### Community 536 - "Community 536" -Cohesion: 0.18 -Nodes (9): AuthenticationService, initialize(), initialize(), MCPDetectMiddleware, StocksAPIService, initialize(), getApp(), runAll() (+1 more) +Cohesion: 0.12 +Nodes (10): initialize(), initialize(), memoryMaintenance(), OrunmilaService, initialize(), MCPDetectMiddleware, StocksAPIService, initialize() (+2 more) ### Community 539 - "Community 539" Cohesion: 0.22 @@ -1892,8 +1880,8 @@ Cohesion: 0.29 Nodes (6): code:python (import argparse), code:bash (git add bench/bench_memory_vector.py), Global Constraints, Lane 4: Before/After Bench Implementation Plan, Task 1: Bench script with synthetic scale sweep, Task 2: Record baseline and post-lane numbers ### Community 541 - "Community 541" -Cohesion: 0.2 -Nodes (9): Covers lines 66, 68-72, 74: GET /user/sessions., Covers lines 66, 68-72, 74: GET /user/sessions., Covers lines 66, 68-72, 74: full sessions listing., Covers lines 66, 68-72, 74: full sessions listing., Covers lines 66, 68-72, 74: GET /user/sessions., Covers lines 66, 68-72, 74: full sessions listing., Covers lines 66, 68-72, 74: GET /user/sessions., Covers lines 66, 68-72, 74: full sessions listing. (+1 more) +Cohesion: 0.22 +Nodes (8): Historical query with a year range., Historical query with a year range., Historical query with a year range., Historical query with a year range., Historical query with a year range., Historical query with a year range., Historical query with a year range., Historical query with a year range. ### Community 542 - "Community 542" Cohesion: 0.5 @@ -1964,8 +1952,8 @@ Cohesion: 0.5 Nodes (4): code:python (import pytest), code:python (import logging), code:bash (git add main/app/wallet/prices.py tests/test_wallet_prices.p), Task 6: Price client — one batched STOCKS_API fetch per snapshot ### Community 560 - "Community 560" -Cohesion: 0.28 -Nodes (7): create_memory(), createMemory(), _downloadModel(), embed(), getEmbeddingModel(), initialize(), OrunmilaService +Cohesion: 0.47 +Nodes (5): create_memory(), createMemory(), _downloadModel(), embed(), getEmbeddingModel() ### Community 561 - "Community 561" Cohesion: 0.09 @@ -1976,25 +1964,29 @@ Cohesion: 0.18 Nodes (10): execute_code(), list_files(), Execute Python code in an isolated sandbox. Use for quantitative analysis, s, Read a file from the workspace. Args: path: Path to the file (e.g.,, Write a file to the workspace. Use this to save data files (CSV, JSON, scrip, List files in the workspace directory. Args: path: Directory path t, Get a download link for a workspace file to share with the user. Use this w, read_file() (+2 more) ### Community 563 - "Community 563" -Cohesion: 0.07 -Nodes (27): Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval. (+19 more) +Cohesion: 0.2 +Nodes (9): Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval. (+1 more) ### Community 564 - "Community 564" -Cohesion: 0.3 -Nodes (31): Base, BaseModel, EarningsSync, WalletCreate, Earning, Holding, Snapshot, Target (+23 more) +Cohesion: 0.25 +Nodes (35): Base, BaseModel, EarningsSync, WalletCreate, OrunmilaSandbox, Earning, Holding, Snapshot (+27 more) ### Community 565 - "Community 565" Cohesion: 0.33 Nodes (6): Tests covering key.py lines 48-66., Tests covering key.py lines 48-66., Tests covering key.py lines 48-66., Tests covering key.py lines 48-66., Tests covering key.py lines 48-66., TestCreateKey ### Community 566 - "Community 566" -Cohesion: 0.22 -Nodes (5): PrometheusSession, createSession(), Thread-safe proxy that delegates to per-thread sessions., SessionProxy, TestPrometheusSessionModel +Cohesion: 0.29 +Nodes (6): Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., TestStocksApiHealth ### Community 567 - "Community 567" Cohesion: 0.14 Nodes (11): Integration tests for the verifyAPIKey function., Test successful API key verification., Integration tests for the verifyAPIKey function., Test API key verification when quota is exceeded., Test API key verification with invalid key., Test API key verification with missing key., Test API key verification with invalid key., Test that API key system can be disabled. (+3 more) +### Community 568 - "Community 568" +Cohesion: 0.08 +Nodes (6): Store a value in state. Marks state as changed for context injection., Verify the actual async tool functions have correct signatures., TOOL_REGISTRY pattern must work correctly., TestMemoryToolFunctions, TestToolRegistry, TestMemoryToolFunctions + ### Community 569 - "Community 569" Cohesion: 0.39 Nodes (8): _build_error_response(), buildErrorResponse(), generic_exception_handler(), genericExceptionHandler(), http_exception_handler(), httpExceptionHandler(), validation_exception_handler(), validationExceptionHandler() @@ -2016,13 +2008,17 @@ Cohesion: 0.29 Nodes (6): Global Constraints, Goal 3 — P3+ assist + narration (starts only after Goal 2 complete), Mansa Wallet Implementation Plan (P1 + P2 + P3+), Task P3-0: Write the P3+ detailed plan (required before P3-1/P3-2), Task P3-1: Ratings-assist tuning (gated on the P3+ plan), Task P3-2: Orunmila narration tools (gated on the P3+ plan) ### Community 574 - "Community 574" -Cohesion: 0.11 -Nodes (15): memoryMaintenance(), Zero access but score still above threshold → not archived., Even with low score, if accessed → not archived., Even with low score, if accessed → not archived., Already archived memories are skipped., Already archived memories are skipped., Score below threshold + accessCount=0 + 90+ days → archived., Score below threshold + accessCount=0 + 90+ days → archived. (+7 more) +Cohesion: 0.06 +Nodes (30): memoryMaintenance(), create_memories(), Zero access but score still above threshold → not archived., Even with low score, if accessed → not archived., Even with low score, if accessed → not archived., Already archived memories are skipped., Already archived memories are skipped., Decay happens first, then archive check with new scores. (+22 more) ### Community 575 - "Community 575" Cohesion: 0.13 Nodes (8): create_entry_route(), delete_entry_route(), list_earnings_route(), list_entries_route(), serialize_earning(), serialize_entry(), serialize_holding(), update_entry_route() +### Community 577 - "Community 577" +Cohesion: 0.29 +Nodes (6): Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., TestStocksApiHistorical + ### Community 578 - "Community 578" Cohesion: 0.29 Nodes (7): code:python (def make_wallet_client(mock_identity=None, db=None):), code:python (import main.models.wallet # noqa: F401), code:python (def test_list_wallets_returns_only_mine(dbSession):), code:python (from sqlalchemy.orm import Session), code:python (from fastapi import APIRouter, Depends), code:bash (git add main/controller/wallet_controller.py main/service/wa), Task 5: Wallets CRUD + mount + `make_wallet_client` @@ -2053,23 +2049,27 @@ Nodes (5): Environment, Standing rules (do not re-derive), Swarm protocol (all t ### Community 586 - "Community 586" Cohesion: 0.07 -Nodes (18): Different query parameters should not share cache, Cache should expire after TTL, Tests for connection pool configuration, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Query manager should have deserialize method, Tests for optimized search filtering, Filter should use ticker index for O(1) lookup (+10 more) +Nodes (20): Tests for connection pool configuration, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Query manager should have deserialize method, Integration tests for all query optimizations, All optimizations should be implemented, Query filter should use ticker index, Tests for optimized search filtering (+12 more) + +### Community 587 - "Community 587" +Cohesion: 0.29 +Nodes (6): Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404., Covers lines 19-20: user not found raises 404. ### Community 588 - "Community 588" Cohesion: 0.33 Nodes (5): Tests for optimized search filtering, Tests for optimized search filtering, Filter should use ticker index for O(1) lookup, Filter should use ticker index for O(1) lookup, TestFilterBySearchTerms ### Community 589 - "Community 589" -Cohesion: 0.27 -Nodes (4): Test that invalid API key returns zero rows affected., Test that multiple API keys have independent quotas., Test that invalid API key returns zero rows affected., Test that multiple API keys have independent quotas. +Cohesion: 0.29 +Nodes (6): Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers line 16: empty password raises ValueError. ### Community 591 - "Community 591" Cohesion: 0.4 Nodes (4): 0. Purpose and constraints, Next actions (not in scope here), nginx Scaling Plan — reverse proxy + response cache for `/stocks`, and the multi-server evolution, Open decisions (blocking or product-owned) ### Community 592 - "Community 592" -Cohesion: 0.33 -Nodes (4): Integration tests for all query optimizations, All optimizations should be implemented, Query filter should use ticker index, TestQueryOptimization +Cohesion: 0.29 +Nodes (6): Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 48-49: jwt.ExpiredSignatureError. ### Community 593 - "Community 593" Cohesion: 0.5 @@ -2109,7 +2109,7 @@ Nodes (5): code:python (import requests), code:python (import os), code:python ( ### Community 602 - "Community 602" Cohesion: 0.29 -Nodes (6): dbSession(), Tests for atomic API key quota enforcement (race condition fix). Verifies tha, Sample API key data for tests., Create an in-memory SQLite database for testing., Sample API key data for tests., sampleKeyData() +Nodes (6): Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation. ### Community 603 - "Community 603" Cohesion: 0.47 @@ -2137,7 +2137,7 @@ Nodes (4): code:python (from main.models.wallet import Earning), code:python (cl ### Community 610 - "Community 610" Cohesion: 0.33 -Nodes (5): Performance tests for query operations, Query should respond within 1 second, Performance tests for query operations, Query should respond within 1 second, TestQueryPerformance +Nodes (6): Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., TestStocksApiFundamental ### Community 611 - "Community 611" Cohesion: 0.5 @@ -2156,20 +2156,24 @@ Cohesion: 0.33 Nodes (5): Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is. ### Community 616 - "Community 616" -Cohesion: 0.2 -Nodes (9): Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148., Covers lines 143, 145, 147-148: POST /user/sessions/revoke-all., Covers lines 143, 145, 147-148. (+1 more) +Cohesion: 0.33 +Nodes (6): Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., TestAddRoleToUser ### Community 617 - "Community 617" -Cohesion: 0.4 -Nodes (4): System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state., System prompt should instruct LLM about memory vs state. +Cohesion: 0.33 +Nodes (5): Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added., Covers lines 17, 22-27: user found, role not present, role added. ### Community 618 - "Community 618" Cohesion: 0.2 Nodes (16): baseFrame(), deserializeJsonColumns(), envelope(), fetchLivePayload(), filterBySearchTerms(), _filterCotationByDate(), filterCotationData(), finalize() (+8 more) +### Community 620 - "Community 620" +Cohesion: 0.33 +Nodes (5): Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 48-49: jwt.ExpiredSignatureError. + ### Community 621 - "Community 621" -Cohesion: 0.67 -Nodes (3): introspectToken(), verifyAccessToken(), introspect() +Cohesion: 0.33 +Nodes (6): dispatchToolCall must route memory tool names via TOOL_REGISTRY., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., dispatchToolCall must route memory tool names to executeMemoryTool., TestDispatchRoutesMemoryTools ### Community 623 - "Community 623" Cohesion: 0.5 @@ -2179,36 +2183,44 @@ Nodes (4): code:python ("""add wallet_holdings and wallet_lots tables), code:pyt Cohesion: 0.67 Nodes (3): checkServiceConnection — success, not found, errors., checkServiceConnection — success, not found, errors., TestCheckServiceConnection -### Community 628 - "Community 628" +### Community 627 - "Community 627" Cohesion: 0.33 -Nodes (4): initialize(), P5: register the session-cleanup job on the shared scheduler. Kept in thi, registerSessionCleanupJobs(), UserService +Nodes (6): makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., TestMakeChatIncludesMemoryTools + +### Community 628 - "Community 628" +Cohesion: 0.4 +Nodes (5): Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., read_file() ### Community 629 - "Community 629" Cohesion: 0.67 Nodes (3): checkMySqlConnection — success, errors, engine=None paths., checkMySqlConnection — success, errors, engine=None paths., TestCheckMySqlConnection +### Community 630 - "Community 630" +Cohesion: 0.67 +Nodes (3): countTokens(), _get_tokenizer(), Count tokens using Gemini's local tokenizer. Accurate for Portuguese. + +### Community 631 - "Community 631" +Cohesion: 0.67 +Nodes (3): get_wallet_rebalance(), Show weight-share rebalance deltas per ticker (buy/sell/hold). Read-only:, Show weight-share rebalance deltas per ticker (buy/sell/hold). Read-only: + ### Community 634 - "Community 634" Cohesion: 0.4 Nodes (5): Category 8: Testing Gaps (MEDIUM), Issue 8.1 — No integration tests for full request lifecycle, Issue 8.2 — No tests for scraper, stocks query, or cache, Issue 8.3 — No tests for Google OAuth callback, Issue 8.4 — No tests for session cleanup -### Community 643 - "Community 643" -Cohesion: 0.4 -Nodes (4): getGoogleSSO(), googleLogin(), test_get_google_sso_default_redirect(), test_get_google_sso_with_redirect() - ## Knowledge Gaps -- **3493 isolated node(s):** `$schema`, `style`, `rsc`, `tsx`, `config` (+3488 more) +- **3490 isolated node(s):** `$schema`, `style`, `rsc`, `tsx`, `config` (+3485 more) These have ≤1 connection - possible missing edges or undocumented components. -- **250 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. +- **242 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. ## Suggested Questions _Questions this graph is uniquely positioned to answer:_ -- **Why does `FastAPI` connect `Community 528` to `Community 129`, `Community 519`, `Community 18`, `Community 147`, `Community 536`, `Community 152`, `Community 33`, `Community 34`, `Community 40`, `Community 43`, `Community 54`, `Community 569`, `Community 186`, `Community 58`, `Community 572`, `Community 575`, `Community 67`, `Community 68`, `Community 71`, `Community 584`, `Community 73`, `Community 84`, `Community 602`, `Community 477`, `Community 101`, `Community 504`, `Community 618`, `Community 107`, `Community 234`, `Community 621`, `Community 491`, `Community 500`, `Community 501`, `Community 502`, `Community 120`?** +- **Why does `FastAPI` connect `Community 528` to `Community 129`, `Community 519`, `Community 18`, `Community 147`, `Community 536`, `Community 152`, `Community 26`, `Community 157`, `Community 33`, `Community 34`, `Community 40`, `Community 43`, `Community 54`, `Community 569`, `Community 58`, `Community 572`, `Community 575`, `Community 576`, `Community 67`, `Community 68`, `Community 71`, `Community 584`, `Community 73`, `Community 84`, `Community 477`, `Community 101`, `Community 504`, `Community 618`, `Community 234`, `Community 491`, `Community 500`, `Community 501`, `Community 502`, `Community 120`?** _High betweenness centrality (0.060) - this node is a cross-community bridge._ -- **Why does `Pytest Testing` connect `Community 577` to `Authentication Core`, `Frontend Components`, `Community 129`, `Data Models & Types`, `Community 518`, `Community 135`, `Community 138`, `Community 140`, `Community 528`, `Community 18`, `Community 147`, `Community 21`, `Community 24`, `Community 25`, `Community 27`, `Community 29`, `Community 32`, `Community 33`, `Community 40`, `Community 44`, `Community 561`, `Community 49`, `Community 51`, `Community 566`, `Community 59`, `Community 188`, `Community 574`, `Community 72`, `Community 586`, `Community 590`, `Community 595`, `Community 599`, `Community 602`, `Community 93`, `Community 477`, `Community 100`, `Community 613`, `Community 102`, `Community 504`, `Community 107`, `Community 491`, `Community 500`, `Community 502`, `Community 503`, `Community 120`?** - _High betweenness centrality (0.055) - this node is a cross-community bridge._ -- **Why does `Config` connect `Community 564` to `Frontend Components`, `Community 137`, `Community 140`, `Community 524`, `Community 536`, `Community 538`, `Community 29`, `Community 45`, `Community 566`, `Community 189`, `Community 80`, `Community 87`, `Community 474`, `Community 604`, `Community 93`, `Community 102`, `Community 231`, `Community 105`, `Community 234`, `Community 122`?** - _High betweenness centrality (0.032) - this node is a cross-community bridge._ +- **Why does `Pytest Testing` connect `Community 49` to `Authentication Core`, `Frontend Components`, `Community 129`, `Data Models & Types`, `Community 135`, `Community 138`, `Community 140`, `Community 528`, `Community 18`, `Community 147`, `Community 21`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 29`, `Community 32`, `Community 33`, `Community 40`, `Community 44`, `Community 561`, `Community 51`, `Community 59`, `Community 188`, `Community 61`, `Community 574`, `Community 576`, `Community 72`, `Community 586`, `Community 590`, `Community 595`, `Community 599`, `Community 93`, `Community 477`, `Community 100`, `Community 613`, `Community 102`, `Community 504`, `Community 107`, `Community 491`, `Community 500`, `Community 503`, `Community 120`?** + _High betweenness centrality (0.059) - this node is a cross-community bridge._ +- **Why does `Config` connect `Community 564` to `Frontend Components`, `Community 102`, `Community 122`, `Community 137`, `Community 105`, `Community 140`, `Community 45`, `Community 524`, `Community 80`, `Community 29`, `Community 538`, `Community 87`, `Community 474`, `Community 604`, `Community 189`?** + _High betweenness centrality (0.034) - this node is a cross-community bridge._ - **Are the 72 inferred relationships involving `StocksCacheManager` (e.g. with `TestStocksCacheManager` and `TestVerifyAPIKey`) actually correct?** _`StocksCacheManager` has 72 INFERRED edges - model-reasoned connections that need verification._ - **Are the 52 inferred relationships involving `HarnessState` (e.g. with `Prometheus` and `.streamMessage()`) actually correct?** diff --git a/graphify-out/graph.json b/graphify-out/graph.json index 47668ac7..bb8a8c2e 100644 --- a/graphify-out/graph.json +++ b/graphify-out/graph.json @@ -2253,7 +2253,7 @@ "source_file": "main/app/authentication/introspect.py", "source_location": "L1", "id": "main_app_authentication_introspect_py", - "community": 621, + "community": 528, "norm_label": "introspect.py" }, { @@ -2262,7 +2262,7 @@ "source_file": "main/app/authentication/introspect.py", "source_location": "L14", "id": "authentication_introspect_introspecttoken", - "community": 621, + "community": 528, "norm_label": "introspecttoken()" }, { @@ -2271,7 +2271,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L1", "id": "main_app_authentication_session_py", - "community": 149, + "community": 44, "norm_label": "session.py" }, { @@ -2280,7 +2280,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L13", "id": "authentication_session_parsedevicefields", - "community": 149, + "community": 44, "norm_label": "parsedevicefields()" }, { @@ -2289,7 +2289,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L30", "id": "authentication_session_sessionmanager", - "community": 172, + "community": 29, "norm_label": "sessionmanager" }, { @@ -2298,7 +2298,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L32", "id": "authentication_session_createsession", - "community": 149, + "community": 44, "norm_label": "createsession()" }, { @@ -2307,7 +2307,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L68", "id": "authentication_session_getusersessions", - "community": 149, + "community": 44, "norm_label": "getusersessions()" }, { @@ -2316,7 +2316,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L73", "id": "authentication_session_getsessionbyid", - "community": 149, + "community": 44, "norm_label": "getsessionbyid()" }, { @@ -2325,7 +2325,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L80", "id": "authentication_session_getcurrentsession", - "community": 149, + "community": 44, "norm_label": "getcurrentsession()" }, { @@ -2334,7 +2334,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L92", "id": "authentication_session_revokesession", - "community": 149, + "community": 44, "norm_label": "revokesession()" }, { @@ -2343,7 +2343,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L109", "id": "authentication_session_revokeallsessions", - "community": 149, + "community": 44, "norm_label": "revokeallsessions()" }, { @@ -2352,7 +2352,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L122", "id": "authentication_session_revokeallexcept", - "community": 149, + "community": 44, "norm_label": "revokeallexcept()" }, { @@ -2361,7 +2361,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L132", "id": "authentication_session_updatelastactive", - "community": 149, + "community": 44, "norm_label": "updatelastactive()" }, { @@ -2370,7 +2370,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L142", "id": "authentication_session_validatesession", - "community": 149, + "community": 44, "norm_label": "validatesession()" }, { @@ -2379,7 +2379,7 @@ "source_file": "main/app/authentication/sso.py", "source_location": "L1", "id": "main_app_authentication_sso_py", - "community": 643, + "community": 58, "norm_label": "sso.py" }, { @@ -2388,7 +2388,7 @@ "source_file": "main/app/authentication/sso.py", "source_location": "L6", "id": "authentication_sso_getgooglesso", - "community": 643, + "community": 58, "norm_label": "getgooglesso()" }, { @@ -2397,7 +2397,7 @@ "source_file": "main/app/authentication/util.py", "source_location": "L1", "id": "main_app_authentication_util_py", - "community": 107, + "community": 528, "norm_label": "util.py" }, { @@ -2424,7 +2424,7 @@ "source_file": "main/app/authentication/util.py", "source_location": "L31", "id": "authentication_util_createaccesstoken", - "community": 43, + "community": 58, "norm_label": "createaccesstoken()" }, { @@ -2433,7 +2433,7 @@ "source_file": "main/app/authentication/util.py", "source_location": "L44", "id": "authentication_util_verifyaccesstoken", - "community": 621, + "community": 528, "norm_label": "verifyaccesstoken()" }, { @@ -2451,7 +2451,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L1", "id": "main_app_orunmila_agent_py", - "community": 137, + "community": 165, "norm_label": "agent.py" }, { @@ -2460,7 +2460,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L25", "id": "orunmila_agent_safefilter", - "community": 137, + "community": 165, "norm_label": "safefilter()" }, { @@ -2469,7 +2469,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L31", "id": "orunmila_agent_persistevent", - "community": 137, + "community": 165, "norm_label": "persistevent()" }, { @@ -2478,7 +2478,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L45", "id": "orunmila_agent_getclient", - "community": 137, + "community": 165, "norm_label": "getclient()" }, { @@ -2487,7 +2487,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L208", "id": "orunmila_agent_orunmila", - "community": 231, + "community": 45, "norm_label": "orunmila" }, { @@ -2496,7 +2496,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L209", "id": "orunmila_agent_orunmila_init", - "community": 137, + "community": 165, "norm_label": ".__init__()" }, { @@ -2505,7 +2505,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L213", "id": "orunmila_agent_buildsystemprompt", - "community": 137, + "community": 165, "norm_label": "buildsystemprompt()" }, { @@ -2514,7 +2514,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L242", "id": "orunmila_agent_orunmila_makechat", - "community": 137, + "community": 165, "norm_label": ".makechat()" }, { @@ -2523,7 +2523,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L253", "id": "orunmila_agent_orunmila_streammessage", - "community": 137, + "community": 165, "norm_label": ".streammessage()" }, { @@ -2541,7 +2541,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L13", "id": "orunmila_chat_orunmilachatmanager", - "community": 231, + "community": 45, "norm_label": "orunmilachatmanager" }, { @@ -2901,7 +2901,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L1", "id": "main_app_orunmila_memory_py", - "community": 137, + "community": 88, "norm_label": "memory.py" }, { @@ -2910,7 +2910,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L35", "id": "orunmila_memory_getmatrix", - "community": 137, + "community": 88, "norm_label": "getmatrix()" }, { @@ -2919,7 +2919,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L53", "id": "orunmila_memory_invalidateuser", - "community": 137, + "community": 88, "norm_label": "invalidateuser()" }, { @@ -2928,7 +2928,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L57", "id": "orunmila_memory_clearall", - "community": 137, + "community": 88, "norm_label": "clearall()" }, { @@ -2937,7 +2937,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L64", "id": "orunmila_memory_memorycandidate", - "community": 231, + "community": 45, "norm_label": "memorycandidate" }, { @@ -2955,7 +2955,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L90", "id": "orunmila_memory_newtokencache", - "community": 137, + "community": 165, "norm_label": "newtokencache()" }, { @@ -2964,7 +2964,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L97", "id": "orunmila_memory_getclient", - "community": 137, + "community": 88, "norm_label": "getclient()" }, { @@ -2973,7 +2973,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L104", "id": "orunmila_memory_minmax", - "community": 137, + "community": 88, "norm_label": "minmax()" }, { @@ -2982,7 +2982,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L113", "id": "orunmila_memory_normalizekey", - "community": 137, + "community": 88, "norm_label": "normalizekey()" }, { @@ -2991,7 +2991,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L120", "id": "orunmila_memory_findsimilarkey", - "community": 137, + "community": 88, "norm_label": "findsimilarkey()" }, { @@ -3000,7 +3000,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L140", "id": "orunmila_memory_scorerow", - "community": 137, + "community": 88, "norm_label": "scorerow()" }, { @@ -3009,7 +3009,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L152", "id": "orunmila_memory_scorerecency", - "community": 137, + "community": 88, "norm_label": "scorerecency()" }, { @@ -3018,7 +3018,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L162", "id": "orunmila_memory_scorecandidates", - "community": 137, + "community": 88, "norm_label": "scorecandidates()" }, { @@ -3036,7 +3036,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L194", "id": "orunmila_memory_orunmilamemory", - "community": 231, + "community": 45, "norm_label": "orunmilamemory" }, { @@ -3045,7 +3045,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L196", "id": "orunmila_memory_getmemorylimit", - "community": 137, + "community": 88, "norm_label": "getmemorylimit()" }, { @@ -3054,7 +3054,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L202", "id": "orunmila_memory_countmemories", - "community": 137, + "community": 88, "norm_label": "countmemories()" }, { @@ -3063,7 +3063,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L211", "id": "orunmila_memory_touch", - "community": 137, + "community": 88, "norm_label": "touch()" }, { @@ -3072,7 +3072,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L222", "id": "orunmila_memory_upsertmemory", - "community": 137, + "community": 88, "norm_label": "upsertmemory()" }, { @@ -3081,7 +3081,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L286", "id": "orunmila_memory_search", - "community": 137, + "community": 88, "norm_label": "search()" }, { @@ -3090,7 +3090,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L349", "id": "orunmila_memory_fulltextsearch", - "community": 137, + "community": 88, "norm_label": "fulltextsearch()" }, { @@ -3099,7 +3099,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L407", "id": "orunmila_memory_getusermemories", - "community": 137, + "community": 88, "norm_label": "getusermemories()" }, { @@ -3108,7 +3108,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L432", "id": "orunmila_memory_deletememory", - "community": 137, + "community": 88, "norm_label": "deletememory()" }, { @@ -3117,7 +3117,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L450", "id": "orunmila_memory_extract", - "community": 137, + "community": 88, "norm_label": "extract()" }, { @@ -3171,7 +3171,7 @@ "source_file": "main/app/orunmila/sandbox.py", "source_location": "L51", "id": "orunmila_sandbox_sandboxmanager", - "community": 234, + "community": 564, "norm_label": "sandboxmanager" }, { @@ -3396,7 +3396,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L1", "id": "main_app_orunmila_vector_py", - "community": 137, + "community": 609, "norm_label": "vector.py" }, { @@ -3405,7 +3405,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L10", "id": "orunmila_vector_normalizerows", - "community": 137, + "community": 609, "norm_label": "normalizerows()" }, { @@ -3414,7 +3414,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L15", "id": "orunmila_vector_embed", - "community": 137, + "community": 149, "norm_label": "embed()" }, { @@ -3423,7 +3423,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L19", "id": "orunmila_vector_decodeembeddings", - "community": 137, + "community": 609, "norm_label": "decodeembeddings()" }, { @@ -3432,7 +3432,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L41", "id": "orunmila_vector_batchcosinesimilarity", - "community": 137, + "community": 609, "norm_label": "batchcosinesimilarity()" }, { @@ -3441,7 +3441,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L51", "id": "orunmila_vector_contenthash", - "community": 137, + "community": 88, "norm_label": "contenthash()" }, { @@ -3450,7 +3450,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L55", "id": "orunmila_vector_tovectorstring", - "community": 137, + "community": 609, "norm_label": "tovectorstring()" }, { @@ -3459,7 +3459,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L59", "id": "orunmila_vector_fromvectorstring", - "community": 137, + "community": 609, "norm_label": "fromvectorstring()" }, { @@ -3468,7 +3468,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L71", "id": "orunmila_vector_getrelevancescore", - "community": 137, + "community": 88, "norm_label": "getrelevancescore()" }, { @@ -3513,43 +3513,43 @@ "source_file": "main/app/orunmila/tools/memory.py", "source_location": "L1", "id": "main_app_orunmila_tools_memory_py", - "community": 101, + "community": 149, "norm_label": "memory.py" }, { "label": "search_memory()", "file_type": "code", "source_file": "main/app/orunmila/tools/memory.py", - "source_location": "L7", + "source_location": "L8", "id": "tools_memory_search_memory", - "community": 101, + "community": 149, "norm_label": "search_memory()" }, { "label": "save_memory()", "file_type": "code", "source_file": "main/app/orunmila/tools/memory.py", - "source_location": "L32", + "source_location": "L33", "id": "tools_memory_save_memory", - "community": 101, + "community": 149, "norm_label": "save_memory()" }, { "label": "Search user's saved memories, preferences, and past analysis context. Use t", "file_type": "rationale", "source_file": "main/app/orunmila/tools/memory.py", - "source_location": "L8", - "id": "tools_memory_rationale_8", - "community": 101, + "source_location": "L9", + "id": "tools_memory_rationale_9", + "community": 149, "norm_label": "search user's saved memories, preferences, and past analysis context. use t" }, { "label": "Store a memory about the user's preferences, analysis results, or feedback.", "file_type": "rationale", "source_file": "main/app/orunmila/tools/memory.py", - "source_location": "L33", - "id": "tools_memory_rationale_33", - "community": 101, + "source_location": "L34", + "id": "tools_memory_rationale_34", + "community": 149, "norm_label": "store a memory about the user's preferences, analysis results, or feedback." }, { @@ -3670,31 +3670,31 @@ "norm_label": "ensureownership()" }, { - "label": "get_wallet_positions()", + "label": "wallet_positions()", "file_type": "code", "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L27", - "id": "tools_wallet_get_wallet_positions", + "id": "tools_wallet_wallet_positions", "community": 101, - "norm_label": "get_wallet_positions()" + "norm_label": "wallet_positions()" }, { - "label": "get_wallet_summary()", + "label": "wallet_summary()", "file_type": "code", "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L52", - "id": "tools_wallet_get_wallet_summary", + "id": "tools_wallet_wallet_summary", "community": 101, - "norm_label": "get_wallet_summary()" + "norm_label": "wallet_summary()" }, { - "label": "get_wallet_allocation()", + "label": "wallet_allocation()", "file_type": "code", "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L77", - "id": "tools_wallet_get_wallet_allocation", + "id": "tools_wallet_wallet_allocation", "community": 101, - "norm_label": "get_wallet_allocation()" + "norm_label": "wallet_allocation()" }, { "label": "list_wallet_earnings()", @@ -3706,22 +3706,22 @@ "norm_label": "list_wallet_earnings()" }, { - "label": "get_wallet_performance()", + "label": "wallet_performance()", "file_type": "code", "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L148", - "id": "tools_wallet_get_wallet_performance", + "id": "tools_wallet_wallet_performance", "community": 101, - "norm_label": "get_wallet_performance()" + "norm_label": "wallet_performance()" }, { - "label": "get_wallet_rebalance()", + "label": "wallet_rebalance()", "file_type": "code", "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L187", - "id": "tools_wallet_get_wallet_rebalance", + "id": "tools_wallet_wallet_rebalance", "community": 101, - "norm_label": "get_wallet_rebalance()" + "norm_label": "wallet_rebalance()" }, { "label": "List wallet holdings with live prices, equity, allocation, and buy signals.", @@ -3783,16 +3783,16 @@ "source_file": "main/app/orunmila/tools/__init__.py", "source_location": "L1", "id": "main_app_orunmila_tools_init_py", - "community": 137, + "community": 165, "norm_label": "__init__.py" }, { "label": "dispatchToolCall()", "file_type": "code", "source_file": "main/app/orunmila/tools/__init__.py", - "source_location": "L39", + "source_location": "L28", "id": "tools_init_dispatchtoolcall", - "community": 137, + "community": 165, "norm_label": "dispatchtoolcall()" }, { @@ -4080,7 +4080,7 @@ "source_file": "main/app/stocks_api/cache.py", "source_location": "L47", "id": "stocks_api_cache_stockscachemanager_cachescheduler", - "community": 82, + "community": 222, "norm_label": ".cachescheduler()" }, { @@ -4440,7 +4440,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L17", "id": "stocks_api_util_dedupabbrev", - "community": 523, + "community": 73, "norm_label": "dedupabbrev()" }, { @@ -4449,7 +4449,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L26", "id": "stocks_api_util_autoabbreviate", - "community": 523, + "community": 73, "norm_label": "autoabbreviate()" }, { @@ -4458,7 +4458,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L49", "id": "stocks_api_util_generateabbreviations", - "community": 523, + "community": 73, "norm_label": "generateabbreviations()" }, { @@ -4494,7 +4494,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L98", "id": "stocks_api_util_detectnestedfields", - "community": 523, + "community": 73, "norm_label": "detectnestedfields()" }, { @@ -4674,7 +4674,7 @@ "source_file": "main/app/wallet/market_data.py", "source_location": "L1", "id": "main_app_wallet_market_data_py", - "community": 482, + "community": 518, "norm_label": "market_data.py" }, { @@ -4701,7 +4701,7 @@ "source_file": "main/app/wallet/market_data.py", "source_location": "L48", "id": "wallet_market_data_fetchmarketdividends", - "community": 482, + "community": 518, "norm_label": "fetchmarketdividends()" }, { @@ -4710,7 +4710,7 @@ "source_file": "main/app/wallet/market_data.py", "source_location": "L68", "id": "wallet_market_data_fetchpadraocloses", - "community": 482, + "community": 518, "norm_label": "fetchpadraocloses()" }, { @@ -4719,7 +4719,7 @@ "source_file": "main/app/wallet/performance.py", "source_location": "L1", "id": "main_app_wallet_performance_py", - "community": 152, + "community": 518, "norm_label": "performance.py" }, { @@ -4737,7 +4737,7 @@ "source_file": "main/app/wallet/performance.py", "source_location": "L29", "id": "wallet_performance_cachedperformance", - "community": 152, + "community": 518, "norm_label": "cachedperformance()" }, { @@ -4746,7 +4746,7 @@ "source_file": "main/app/wallet/performance.py", "source_location": "L154", "id": "wallet_performance_getperformance", - "community": 152, + "community": 518, "norm_label": "getperformance()" }, { @@ -4917,7 +4917,7 @@ "source_file": "main/app/wallet/wallets.py", "source_location": "L1", "id": "main_app_wallet_wallets_py", - "community": 528, + "community": 152, "norm_label": "wallets.py" }, { @@ -4944,7 +4944,7 @@ "source_file": "main/app/wallet/wallets.py", "source_location": "L20", "id": "wallet_wallets_createwallet", - "community": 528, + "community": 152, "norm_label": "createwallet()" }, { @@ -4953,7 +4953,7 @@ "source_file": "main/app/wallet/wallets.py", "source_location": "L28", "id": "wallet_wallets_listwallets", - "community": 528, + "community": 152, "norm_label": "listwallets()" }, { @@ -5043,7 +5043,7 @@ "source_file": "main/controller/authentication_controller.py", "source_location": "L154", "id": "controller_authentication_controller_introspect", - "community": 621, + "community": 528, "norm_label": "introspect()" }, { @@ -5052,7 +5052,7 @@ "source_file": "main/controller/authentication_controller.py", "source_location": "L180", "id": "controller_authentication_controller_googlelogin", - "community": 643, + "community": 58, "norm_label": "googlelogin()" }, { @@ -5178,7 +5178,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L1", "id": "main_controller_stocksapi_controller_py", - "community": 186, + "community": 157, "norm_label": "stocksapi_controller.py" }, { @@ -5187,7 +5187,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L28", "id": "controller_stocksapi_controller_health", - "community": 186, + "community": 157, "norm_label": "health()" }, { @@ -5574,7 +5574,7 @@ "source_file": "main/models/memory.py", "source_location": "L8", "id": "models_memory_orunmilamemory", - "community": 231, + "community": 45, "norm_label": "orunmilamemory" }, { @@ -5619,7 +5619,7 @@ "source_file": "main/models/sandbox.py", "source_location": "L5", "id": "models_sandbox_orunmilasandbox", - "community": 234, + "community": 564, "norm_label": "orunmilasandbox" }, { @@ -5808,7 +5808,7 @@ "source_file": "main/service/authentication_service.py", "source_location": "L5", "id": "service_authentication_service_authenticationservice", - "community": 536, + "community": 564, "norm_label": "authenticationservice" }, { @@ -5826,7 +5826,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L1", "id": "main_service_orunmila_service_py", - "community": 560, + "community": 536, "norm_label": "orunmila_service.py" }, { @@ -5835,7 +5835,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L23", "id": "service_orunmila_service_memorymaintenance", - "community": 137, + "community": 536, "norm_label": "memorymaintenance()" }, { @@ -5844,7 +5844,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L65", "id": "service_orunmila_service_orunmilaservice", - "community": 560, + "community": 536, "norm_label": "orunmilaservice" }, { @@ -5853,7 +5853,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L67", "id": "service_orunmila_service_initialize", - "community": 560, + "community": 536, "norm_label": "initialize()" }, { @@ -5961,7 +5961,7 @@ "source_file": "main/service/user_service.py", "source_location": "L1", "id": "main_service_user_service_py", - "community": 628, + "community": 222, "norm_label": "user_service.py" }, { @@ -5970,7 +5970,7 @@ "source_file": "main/service/user_service.py", "source_location": "L17", "id": "service_user_service_removeinactivesessions", - "community": 628, + "community": 222, "norm_label": "removeinactivesessions()" }, { @@ -5979,7 +5979,7 @@ "source_file": "main/service/user_service.py", "source_location": "L42", "id": "service_user_service_userservice", - "community": 628, + "community": 222, "norm_label": "userservice" }, { @@ -5988,7 +5988,7 @@ "source_file": "main/service/user_service.py", "source_location": "L44", "id": "service_user_service_initialize", - "community": 628, + "community": 222, "norm_label": "initialize()" }, { @@ -6123,7 +6123,7 @@ "source_file": "main/utils/errors.py", "source_location": "L64", "id": "utils_errors_registererrorhandlers", - "community": 498, + "community": 493, "norm_label": "registererrorhandlers()" }, { @@ -6267,7 +6267,7 @@ "source_file": "main/utils/roles.py", "source_location": "L5", "id": "utils_roles_permission", - "community": 140, + "community": 45, "norm_label": "permission" }, { @@ -13713,6 +13713,69 @@ "community": 208, "norm_label": "10. plans and follow-ups" }, + { + "label": "Search user's saved memories, preferences, and past analysis context. Use t", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L8", + "community": 149, + "norm_label": "search user's saved memories, preferences, and past analysis context. use t", + "id": "tools_memory_rationale_8" + }, + { + "label": "Store a memory about the user's preferences, analysis results, or feedback.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L33", + "community": 149, + "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", + "id": "tools_memory_rationale_33" + }, + { + "label": "get_wallet_positions()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L27", + "community": 101, + "norm_label": "get_wallet_positions()", + "id": "tools_wallet_get_wallet_positions" + }, + { + "label": "get_wallet_summary()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L52", + "community": 101, + "norm_label": "get_wallet_summary()", + "id": "tools_wallet_get_wallet_summary" + }, + { + "label": "get_wallet_allocation()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L77", + "community": 101, + "norm_label": "get_wallet_allocation()", + "id": "tools_wallet_get_wallet_allocation" + }, + { + "label": "get_wallet_performance()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L148", + "community": 101, + "norm_label": "get_wallet_performance()", + "id": "tools_wallet_get_wallet_performance" + }, + { + "label": "get_wallet_rebalance()", + "file_type": "code", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L187", + "community": 101, + "norm_label": "get_wallet_rebalance()", + "id": "tools_wallet_get_wallet_rebalance" + }, { "label": "tools.py", "file_type": "code", @@ -13736,7 +13799,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L58", - "community": 137, + "community": 149, "norm_label": "save_memory()", "id": "orunmila_tools_save_memory" }, @@ -13754,7 +13817,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L121", - "community": 67, + "community": 628, "norm_label": "read_file()", "id": "orunmila_tools_read_file" }, @@ -13790,7 +13853,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L189", - "community": 67, + "community": 482, "norm_label": "get_wallet_positions()", "id": "orunmila_tools_get_wallet_positions" }, @@ -13808,7 +13871,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L261", - "community": 152, + "community": 67, "norm_label": "get_wallet_allocation()", "id": "orunmila_tools_get_wallet_allocation" }, @@ -13826,7 +13889,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L354", - "community": 152, + "community": 67, "norm_label": "get_wallet_performance()", "id": "orunmila_tools_get_wallet_performance" }, @@ -13835,7 +13898,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L404", - "community": 67, + "community": 631, "norm_label": "get_wallet_rebalance()", "id": "orunmila_tools_get_wallet_rebalance" }, @@ -13844,7 +13907,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L457", - "community": 137, + "community": 165, "norm_label": "dispatchtoolcall()", "id": "orunmila_tools_dispatchtoolcall" }, @@ -13862,7 +13925,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L59", - "community": 137, + "community": 149, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "orunmila_tools_rationale_59" }, @@ -13880,7 +13943,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L122", - "community": 67, + "community": 628, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "orunmila_tools_rationale_122" }, @@ -13916,7 +13979,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L190", - "community": 67, + "community": 482, "norm_label": "list wallet holdings with live prices, equity, allocation, and buy signals.", "id": "orunmila_tools_rationale_190" }, @@ -13934,7 +13997,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L262", - "community": 152, + "community": 67, "norm_label": "break wallet equity down by ticker or asset type. read-only: never mutate", "id": "orunmila_tools_rationale_262" }, @@ -13952,7 +14015,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L357", - "community": 152, + "community": 67, "norm_label": "compute time-weighted return, volatility, and dividends for a wallet or ticker.", "id": "orunmila_tools_rationale_357" }, @@ -13961,7 +14024,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L405", - "community": 67, + "community": 631, "norm_label": "show weight-share rebalance deltas per ticker (buy/sell/hold). read-only:", "id": "orunmila_tools_rationale_405" }, @@ -13997,7 +14060,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L54", - "community": 137, + "community": 149, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "orunmila_tools_rationale_54" }, @@ -14015,7 +14078,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L117", - "community": 67, + "community": 628, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "orunmila_tools_rationale_117" }, @@ -14051,7 +14114,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L185", - "community": 67, + "community": 482, "norm_label": "list wallet holdings with live prices, equity, allocation, and buy signals.", "id": "orunmila_tools_rationale_185" }, @@ -14069,7 +14132,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L263", - "community": 152, + "community": 67, "norm_label": "break wallet equity down by ticker or asset type. read-only: never mutate", "id": "orunmila_tools_rationale_263" }, @@ -14087,7 +14150,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L364", - "community": 152, + "community": 67, "norm_label": "compute time-weighted return, volatility, and dividends for a wallet or ticker.", "id": "orunmila_tools_rationale_364" }, @@ -14096,7 +14159,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L415", - "community": 67, + "community": 631, "norm_label": "show weight-share rebalance deltas per ticker (buy/sell/hold). read-only:", "id": "orunmila_tools_rationale_415" }, @@ -14105,7 +14168,7 @@ "file_type": "code", "source_file": "main/app/wallet/market_data.py", "source_location": "L42", - "community": 482, + "community": 518, "norm_label": "fetchcachedclose()", "id": "wallet_market_data_fetchcachedclose" }, @@ -14168,7 +14231,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L183", - "community": 68, + "community": 152, "norm_label": "narrate_positions()", "id": "orunmila_tools_narrate_positions" }, @@ -14186,7 +14249,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L53", - "community": 137, + "community": 149, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "orunmila_tools_rationale_53" }, @@ -14204,7 +14267,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L116", - "community": 67, + "community": 628, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "orunmila_tools_rationale_116" }, @@ -14240,7 +14303,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L184", - "community": 68, + "community": 152, "norm_label": "narrate the user's wallet positions in plain language. read-only summary", "id": "orunmila_tools_rationale_184" }, @@ -14357,7 +14420,7 @@ "file_type": "code", "source_file": "main/app/wallet/market_data.py", "source_location": "L16", - "community": 482, + "community": 518, "norm_label": "stocksapibase()", "id": "wallet_market_data_stocksapibase" }, @@ -14366,7 +14429,7 @@ "file_type": "code", "source_file": "main/app/wallet/market_data.py", "source_location": "L20", - "community": 482, + "community": 518, "norm_label": "stocksapiheaders()", "id": "wallet_market_data_stocksapiheaders" }, @@ -14690,7 +14753,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L52", - "community": 137, + "community": 149, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "orunmila_tools_rationale_52" }, @@ -14708,7 +14771,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L115", - "community": 67, + "community": 628, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "orunmila_tools_rationale_115" }, @@ -16571,7 +16634,7 @@ "file_type": "code", "source_file": "main/app/prometheus/agent.py", "source_location": "L45", - "community": 93, + "community": 116, "norm_label": "getclient()", "id": "prometheus_agent_getclient" }, @@ -16580,7 +16643,7 @@ "file_type": "code", "source_file": "main/app/prometheus/agent.py", "source_location": "L208", - "community": 93, + "community": 140, "norm_label": "prometheus", "id": "prometheus_agent_prometheus" }, @@ -16589,7 +16652,7 @@ "file_type": "code", "source_file": "main/app/prometheus/agent.py", "source_location": "L209", - "community": 93, + "community": 116, "norm_label": ".__init__()", "id": "prometheus_agent_prometheus_init" }, @@ -16634,7 +16697,7 @@ "file_type": "code", "source_file": "main/app/prometheus/chat.py", "source_location": "L13", - "community": 172, + "community": 29, "norm_label": "prometheuschatmanager", "id": "prometheus_chat_prometheuschatmanager" }, @@ -16652,7 +16715,7 @@ "file_type": "code", "source_file": "main/app/prometheus/chat.py", "source_location": "L33", - "community": 566, + "community": 125, "norm_label": "createsession()", "id": "prometheus_chat_createsession" }, @@ -17822,7 +17885,7 @@ "file_type": "code", "source_file": "main/models/prometheus.py", "source_location": "L1", - "community": 566, + "community": 61, "norm_label": "prometheus.py", "id": "main_models_prometheus_py" }, @@ -17831,7 +17894,7 @@ "file_type": "code", "source_file": "main/models/prometheus.py", "source_location": "L7", - "community": 566, + "community": 61, "norm_label": "prometheussession", "id": "models_prometheus_prometheussession" }, @@ -18425,7 +18488,7 @@ "file_type": "code", "source_file": "main/app/authentication/session.py", "source_location": "L14", - "community": 149, + "community": 44, "norm_label": "getdevicename()", "id": "authentication_session_getdevicename" }, @@ -18848,7 +18911,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L23", - "community": 186, + "community": 157, "norm_label": "jsonbytesresponse", "id": "controller_stocksapi_controller_jsonbytesresponse" }, @@ -18857,7 +18920,7 @@ "file_type": "code", "source_file": "", "source_location": "", - "community": 186, + "community": 157, "norm_label": "fastapiresponse", "id": "fastapiresponse" }, @@ -18866,7 +18929,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L26", - "community": 186, + "community": 157, "norm_label": ".render()", "id": "controller_stocksapi_controller_jsonbytesresponse_render" }, @@ -19667,7 +19730,7 @@ "file_type": "code", "source_file": "main/service/user_service.py", "source_location": "L46", - "community": 628, + "community": 222, "norm_label": "registersessioncleanupjobs()", "id": "service_user_service_registersessioncleanupjobs" }, @@ -19676,7 +19739,7 @@ "file_type": "rationale", "source_file": "main/service/user_service.py", "source_location": "L47", - "community": 628, + "community": 222, "norm_label": "p5: register the session-cleanup job on the shared scheduler. kept in thi", "id": "service_user_service_rationale_47" }, @@ -21179,7 +21242,7 @@ "file_type": "code", "source_file": "main/utils/service_manager.py", "source_location": "L15", - "community": 536, + "community": 564, "norm_label": "servicemanager", "id": "utils_service_manager_servicemanager" }, @@ -21341,7 +21404,7 @@ "file_type": "code", "source_file": "main/app/prometheus/agent.py", "source_location": "L58", - "community": 93, + "community": 116, "norm_label": "_get_client()", "id": "prometheus_agent_get_client" }, @@ -21350,7 +21413,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/agent.py", "source_location": "L59", - "community": 93, + "community": 116, "norm_label": "lazy module-level singleton so the genai client is created once, not per request", "id": "prometheus_agent_rationale_59" }, @@ -21530,7 +21593,7 @@ "file_type": "code", "source_file": "main/app/authentication/session.py", "source_location": "L124", - "community": 149, + "community": 44, "norm_label": "cleanupexpiredsessions()", "id": "authentication_session_cleanupexpiredsessions" }, @@ -21611,7 +21674,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/key.py", "source_location": "L61", - "community": 26, + "community": 500, "norm_label": "createkey()", "id": "stocks_api_key_createkey" }, @@ -21629,7 +21692,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L24", - "community": 186, + "community": 157, "norm_label": "sends pre-serialized json bytes without re-encoding (cache-friendly).", "id": "controller_stocksapi_controller_rationale_24" }, @@ -21728,7 +21791,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L51", - "community": 523, + "community": 517, "norm_label": ".set()", "id": "stocks_api_response_cache_responsecache_set" }, @@ -21773,7 +21836,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L323", - "community": 186, + "community": 500, "norm_label": "generatekey()", "id": "controller_stocksapi_controller_generatekey" }, @@ -22574,7 +22637,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L1", - "community": 523, + "community": 186, "norm_label": "compressor.py", "id": "main_app_stocks_api_compressor_py" }, @@ -22583,7 +22646,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L25", - "community": 523, + "community": 186, "norm_label": "getabbr()", "id": "stocks_api_compressor_getabbr" }, @@ -22592,7 +22655,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L36", - "community": 523, + "community": 186, "norm_label": "getnest()", "id": "stocks_api_compressor_getnest" }, @@ -22610,7 +22673,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L51", - "community": 523, + "community": 186, "norm_label": "walk()", "id": "stocks_api_compressor_walk" }, @@ -22619,7 +22682,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L59", - "community": 523, + "community": 186, "norm_label": "compactvalue()", "id": "stocks_api_compressor_compactvalue" }, @@ -22628,7 +22691,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L80", - "community": 523, + "community": 186, "norm_label": "tocolumnar()", "id": "stocks_api_compressor_tocolumnar" }, @@ -22637,7 +22700,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L89", - "community": 523, + "community": 186, "norm_label": "fixheaders()", "id": "stocks_api_compressor_fixheaders" }, @@ -22646,7 +22709,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L98", - "community": 523, + "community": 186, "norm_label": "compactrow()", "id": "stocks_api_compressor_compactrow" }, @@ -22655,7 +22718,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L126", - "community": 523, + "community": 186, "norm_label": "compactcotations()", "id": "stocks_api_compressor_compactcotations" }, @@ -22664,7 +22727,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/compressor.py", "source_location": "L160", - "community": 523, + "community": 186, "norm_label": "compressresponse()", "id": "stocks_api_compressor_compressresponse" }, @@ -23546,7 +23609,7 @@ "file_type": "code", "source_file": "main/app/prometheus/state.py", "source_location": "L14", - "community": 523, + "community": 568, "norm_label": ".set()", "id": "prometheus_state_harnessstate_set" }, @@ -24194,7 +24257,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tokenizer.py", "source_location": "L1", - "community": 87, + "community": 630, "norm_label": "tokenizer.py", "id": "main_app_prometheus_tokenizer_py" }, @@ -24203,7 +24266,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tokenizer.py", "source_location": "L10", - "community": 87, + "community": 630, "norm_label": "_get_tokenizer()", "id": "prometheus_tokenizer_get_tokenizer" }, @@ -24212,7 +24275,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tokenizer.py", "source_location": "L17", - "community": 87, + "community": 630, "norm_label": "counttokens()", "id": "prometheus_tokenizer_counttokens" }, @@ -24221,7 +24284,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tokenizer.py", "source_location": "L18", - "community": 87, + "community": 630, "norm_label": "count tokens using gemini's local tokenizer. accurate for portuguese.", "id": "prometheus_tokenizer_rationale_18" }, @@ -31565,7 +31628,7 @@ "file_type": "code", "source_file": "tests/test_agent_state_integration.py", "source_location": "L195", - "community": 617, + "community": 93, "norm_label": ".test_system_prompt_has_memory_sync_section()", "id": "tests_test_agent_state_integration_testsystempromptstateinstructions_test_system_prompt_has_memory_sync_section" }, @@ -31655,7 +31718,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L196", - "community": 617, + "community": 93, "norm_label": "system prompt should instruct llm about memory vs state.", "id": "tests_test_agent_state_integration_rationale_196" }, @@ -31664,7 +31727,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L1", - "community": 602, + "community": 26, "norm_label": "test_api_key_quota_atomic.py", "id": "tests_test_api_key_quota_atomic_py" }, @@ -31673,7 +31736,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L18", - "community": 602, + "community": 26, "norm_label": "samplekeydata()", "id": "tests_test_api_key_quota_atomic_samplekeydata" }, @@ -31727,7 +31790,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L150", - "community": 589, + "community": 26, "norm_label": ".test_invalid_api_key_returns_zero_rows()", "id": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_invalid_api_key_returns_zero_rows" }, @@ -31736,7 +31799,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L164", - "community": 589, + "community": 26, "norm_label": ".test_multiple_keys_independent_quotas()", "id": "tests_test_api_key_quota_atomic_testatomicquotaincrement_test_multiple_keys_independent_quotas" }, @@ -31808,7 +31871,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L1", - "community": 602, + "community": 26, "norm_label": "tests for atomic api key quota enforcement (race condition fix). verifies tha", "id": "tests_test_api_key_quota_atomic_rationale_1" }, @@ -31817,7 +31880,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L19", - "community": 602, + "community": 26, "norm_label": "sample api key data for tests.", "id": "tests_test_api_key_quota_atomic_rationale_19" }, @@ -31871,7 +31934,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L151", - "community": 589, + "community": 26, "norm_label": "test that invalid api key returns zero rows affected.", "id": "tests_test_api_key_quota_atomic_rationale_151" }, @@ -31880,7 +31943,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L165", - "community": 589, + "community": 26, "norm_label": "test that multiple api keys have independent quotas.", "id": "tests_test_api_key_quota_atomic_rationale_165" }, @@ -32501,7 +32564,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L146", - "community": 120, + "community": 45, "norm_label": "testregisterendpoint", "id": "tests_test_controllers_coverage_testregisterendpoint" }, @@ -32573,7 +32636,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L257", - "community": 120, + "community": 45, "norm_label": "testlogoutendpoint", "id": "tests_test_controllers_coverage_testlogoutendpoint" }, @@ -32663,7 +32726,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L390", - "community": 120, + "community": 45, "norm_label": "testgooglecallback", "id": "tests_test_controllers_coverage_testgooglecallback" }, @@ -32735,7 +32798,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L541", - "community": 47, + "community": 45, "norm_label": "testgetme", "id": "tests_test_controllers_coverage_testgetme" }, @@ -32744,7 +32807,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L544", - "community": 47, + "community": 45, "norm_label": ".test_get_me()", "id": "tests_test_controllers_coverage_testgetme_test_get_me" }, @@ -32825,7 +32888,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L614", - "community": 541, + "community": 45, "norm_label": "testgetsessions", "id": "tests_test_controllers_coverage_testgetsessions" }, @@ -32834,7 +32897,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L617", - "community": 541, + "community": 63, "norm_label": ".test_get_sessions()", "id": "tests_test_controllers_coverage_testgetsessions_test_get_sessions" }, @@ -32843,7 +32906,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L668", - "community": 63, + "community": 45, "norm_label": "testgetcurrentsession", "id": "tests_test_controllers_coverage_testgetcurrentsession" }, @@ -32906,7 +32969,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L805", - "community": 616, + "community": 45, "norm_label": "testrevokeallsessions", "id": "tests_test_controllers_coverage_testrevokeallsessions" }, @@ -32915,7 +32978,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L808", - "community": 616, + "community": 63, "norm_label": ".test_revoke_all_sessions()", "id": "tests_test_controllers_coverage_testrevokeallsessions_test_revoke_all_sessions" }, @@ -32942,7 +33005,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L849", - "community": 99, + "community": 45, "norm_label": "testprometheusgetsessions", "id": "tests_test_controllers_coverage_testprometheusgetsessions" }, @@ -32960,7 +33023,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L867", - "community": 99, + "community": 45, "norm_label": "testprometheuscreatesession", "id": "tests_test_controllers_coverage_testprometheuscreatesession" }, @@ -32969,7 +33032,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L870", - "community": 99, + "community": 45, "norm_label": ".test_create_session()", "id": "tests_test_controllers_coverage_testprometheuscreatesession_test_create_session" }, @@ -33104,7 +33167,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1121", - "community": 99, + "community": 148, "norm_label": ".test_chat_generic_exception()", "id": "tests_test_controllers_coverage_testprometheuschat_test_chat_generic_exception" }, @@ -33113,7 +33176,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1144", - "community": 45, + "community": 566, "norm_label": "teststocksapihealth", "id": "tests_test_controllers_coverage_teststocksapihealth" }, @@ -33122,7 +33185,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1147", - "community": 45, + "community": 566, "norm_label": ".test_health()", "id": "tests_test_controllers_coverage_teststocksapihealth_test_health" }, @@ -33131,7 +33194,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1158", - "community": 14, + "community": 577, "norm_label": "teststocksapihistorical", "id": "tests_test_controllers_coverage_teststocksapihistorical" }, @@ -33140,7 +33203,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1161", - "community": 14, + "community": 577, "norm_label": ".test_get_historical()", "id": "tests_test_controllers_coverage_teststocksapihistorical_test_get_historical" }, @@ -33149,7 +33212,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1172", - "community": 14, + "community": 610, "norm_label": "teststocksapifundamental", "id": "tests_test_controllers_coverage_teststocksapifundamental" }, @@ -33203,7 +33266,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1229", - "community": 529, + "community": 616, "norm_label": "testaddroletouser", "id": "tests_test_controllers_coverage_testaddroletouser" }, @@ -33212,7 +33275,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1232", - "community": 529, + "community": 617, "norm_label": ".test_add_role_success()", "id": "tests_test_controllers_coverage_testaddroletouser_test_add_role_success" }, @@ -33230,7 +33293,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1263", - "community": 529, + "community": 587, "norm_label": ".test_add_role_user_not_found()", "id": "tests_test_controllers_coverage_testaddroletouser_test_add_role_user_not_found" }, @@ -33275,7 +33338,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1323", - "community": 563, + "community": 589, "norm_label": ".test_get_current_user_not_found()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_not_found" }, @@ -33284,7 +33347,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1340", - "community": 563, + "community": 592, "norm_label": ".test_get_current_user_generic_exception()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_generic_exception" }, @@ -33293,7 +33356,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1357", - "community": 563, + "community": 602, "norm_label": ".test_get_current_user_no_session_id()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_no_session_id" }, @@ -33302,7 +33365,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1381", - "community": 194, + "community": 45, "norm_label": "testhashpasswordempty", "id": "tests_test_controllers_coverage_testhashpasswordempty" }, @@ -33320,7 +33383,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1391", - "community": 194, + "community": 45, "norm_label": "testverifyaccesstoken", "id": "tests_test_controllers_coverage_testverifyaccesstoken" }, @@ -33329,7 +33392,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1394", - "community": 194, + "community": 620, "norm_label": ".test_expired_token()", "id": "tests_test_controllers_coverage_testverifyaccesstoken_test_expired_token" }, @@ -33446,7 +33509,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L147", - "community": 120, + "community": 45, "norm_label": "covers lines 44-54, 63, 66-71: register success, valueerror, generic exception.", "id": "tests_test_controllers_coverage_rationale_147" }, @@ -33518,7 +33581,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L258", - "community": 120, + "community": 45, "norm_label": "covers lines 107, 109-130, 133: logout token extraction and revocation.", "id": "tests_test_controllers_coverage_rationale_258" }, @@ -33536,7 +33599,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L281", - "community": 120, + "community": 45, "norm_label": "covers lines 111-113: token extracted from authorization bearer header.", "id": "tests_test_controllers_coverage_rationale_281" }, @@ -33608,7 +33671,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L391", - "community": 120, + "community": 45, "norm_label": "covers lines 155-156, 158, 160-168, 170-177, 179-184, 186, 190-204: googlecallba", "id": "tests_test_controllers_coverage_rationale_391" }, @@ -33671,7 +33734,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L542", - "community": 47, + "community": 45, "norm_label": "covers line 24: get /user/me returns currentuser.", "id": "tests_test_controllers_coverage_rationale_542" }, @@ -33698,7 +33761,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L615", - "community": 541, + "community": 45, "norm_label": "covers lines 66, 68-72, 74: get /user/sessions.", "id": "tests_test_controllers_coverage_rationale_615" }, @@ -33707,7 +33770,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L618", - "community": 541, + "community": 63, "norm_label": "covers lines 66, 68-72, 74: full sessions listing.", "id": "tests_test_controllers_coverage_rationale_618" }, @@ -33716,7 +33779,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L669", - "community": 63, + "community": 45, "norm_label": "covers lines 100-104, 106: get /user/sessions/current.", "id": "tests_test_controllers_coverage_rationale_669" }, @@ -33779,7 +33842,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L806", - "community": 616, + "community": 45, "norm_label": "covers lines 143, 145, 147-148: post /user/sessions/revoke-all.", "id": "tests_test_controllers_coverage_rationale_806" }, @@ -33788,7 +33851,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L809", - "community": 616, + "community": 63, "norm_label": "covers lines 143, 145, 147-148.", "id": "tests_test_controllers_coverage_rationale_809" }, @@ -33806,7 +33869,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L850", - "community": 99, + "community": 45, "norm_label": "covers lines 33-36: get /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_850" }, @@ -33815,7 +33878,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L868", - "community": 99, + "community": 45, "norm_label": "covers line 52: post /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_868" }, @@ -33950,7 +34013,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1122", - "community": 99, + "community": 148, "norm_label": "generic exception in chat propagates via sse error event.", "id": "tests_test_controllers_coverage_rationale_1122" }, @@ -33959,7 +34022,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1145", - "community": 45, + "community": 566, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1145" }, @@ -33968,7 +34031,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1159", - "community": 14, + "community": 577, "norm_label": "covers line 35: get /stocks/historical.", "id": "tests_test_controllers_coverage_rationale_1159" }, @@ -33977,7 +34040,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1173", - "community": 14, + "community": 610, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1173" }, @@ -34022,7 +34085,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1230", - "community": 529, + "community": 616, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1230" }, @@ -34031,7 +34094,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1233", - "community": 529, + "community": 617, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1233" }, @@ -34040,7 +34103,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1250", - "community": 529, + "community": 14, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1250" }, @@ -34049,7 +34112,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1264", - "community": 529, + "community": 587, "norm_label": "covers lines 19-20: user not found raises 404.", "id": "tests_test_controllers_coverage_rationale_1264" }, @@ -34085,7 +34148,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1324", - "community": 563, + "community": 589, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1324" }, @@ -34094,7 +34157,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1341", - "community": 563, + "community": 592, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1341" }, @@ -34103,7 +34166,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1358", - "community": 563, + "community": 602, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1358" }, @@ -34112,7 +34175,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1382", - "community": 194, + "community": 45, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1382" }, @@ -34121,7 +34184,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1392", - "community": 194, + "community": 45, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1392" }, @@ -34130,7 +34193,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1395", - "community": 194, + "community": 620, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1395" }, @@ -35030,7 +35093,7 @@ "file_type": "code", "source_file": "tests/test_harness_state.py", "source_location": "L1", - "community": 577, + "community": 49, "norm_label": "test_harness_state.py", "id": "tests_test_harness_state_py" }, @@ -35192,7 +35255,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L14", - "community": 587, + "community": 25, "norm_label": "testregistervalidation", "id": "tests_test_input_validation_testregistervalidation" }, @@ -35201,7 +35264,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L17", - "community": 587, + "community": 25, "norm_label": ".test_valid_registration()", "id": "tests_test_input_validation_testregistervalidation_test_valid_registration" }, @@ -35210,7 +35273,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L25", - "community": 587, + "community": 25, "norm_label": ".test_username_too_short()", "id": "tests_test_input_validation_testregistervalidation_test_username_too_short" }, @@ -35219,7 +35282,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L32", - "community": 587, + "community": 25, "norm_label": ".test_username_too_long()", "id": "tests_test_input_validation_testregistervalidation_test_username_too_long" }, @@ -35228,7 +35291,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L39", - "community": 587, + "community": 25, "norm_label": ".test_email_too_short()", "id": "tests_test_input_validation_testregistervalidation_test_email_too_short" }, @@ -35237,7 +35300,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L46", - "community": 587, + "community": 25, "norm_label": ".test_password_too_short()", "id": "tests_test_input_validation_testregistervalidation_test_password_too_short" }, @@ -35246,7 +35309,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L54", - "community": 620, + "community": 25, "norm_label": "testloginvalidation", "id": "tests_test_input_validation_testloginvalidation" }, @@ -35255,7 +35318,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L57", - "community": 620, + "community": 25, "norm_label": ".test_valid_login_payload()", "id": "tests_test_input_validation_testloginvalidation_test_valid_login_payload" }, @@ -35264,7 +35327,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L65", - "community": 620, + "community": 25, "norm_label": ".test_username_too_short()", "id": "tests_test_input_validation_testloginvalidation_test_username_too_short" }, @@ -35273,7 +35336,7 @@ "file_type": "code", "source_file": "tests/test_input_validation.py", "source_location": "L72", - "community": 620, + "community": 25, "norm_label": ".test_password_too_short()", "id": "tests_test_input_validation_testloginvalidation_test_password_too_short" }, @@ -35426,7 +35489,7 @@ "file_type": "rationale", "source_file": "tests/test_input_validation.py", "source_location": "L15", - "community": 587, + "community": 25, "norm_label": "post /auth/register \u2014 validates username, email, password via body(...)", "id": "tests_test_input_validation_rationale_15" }, @@ -35435,7 +35498,7 @@ "file_type": "rationale", "source_file": "tests/test_input_validation.py", "source_location": "L55", - "community": 620, + "community": 25, "norm_label": "post /auth/login \u2014 validates username, password via body(...)", "id": "tests_test_input_validation_rationale_55" }, @@ -35624,7 +35687,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L8", - "community": 521, + "community": 140, "norm_label": "_create_memory()", "id": "tests_test_memory_dedup_create_memory" }, @@ -35633,7 +35696,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L12", - "community": 521, + "community": 140, "norm_label": "_count_memories()", "id": "tests_test_memory_dedup_count_memories" }, @@ -35642,7 +35705,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L20", - "community": 521, + "community": 140, "norm_label": "_get_memory()", "id": "tests_test_memory_dedup_get_memory" }, @@ -35660,7 +35723,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L29", - "community": 521, + "community": 140, "norm_label": ".test_exact_same_key_updates()", "id": "tests_test_memory_dedup_testexactsamekeyupdates_test_exact_same_key_updates" }, @@ -35678,7 +35741,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L37", - "community": 521, + "community": 140, "norm_label": ".test_similar_key_merges()", "id": "tests_test_memory_dedup_testsimilarkeymerges_test_similar_key_merges" }, @@ -35696,7 +35759,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L47", - "community": 521, + "community": 140, "norm_label": ".test_different_keys_no_merge()", "id": "tests_test_memory_dedup_testdifferentkeysnomerge_test_different_keys_no_merge" }, @@ -35714,7 +35777,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L56", - "community": 521, + "community": 140, "norm_label": ".test_merge_boosts_score()", "id": "tests_test_memory_dedup_testmergeboostsscore_test_merge_boosts_score" }, @@ -35732,7 +35795,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L65", - "community": 521, + "community": 140, "norm_label": ".test_merge_increments_access()", "id": "tests_test_memory_dedup_testmergeincrementsaccess_test_merge_increments_access" }, @@ -35750,7 +35813,7 @@ "file_type": "code", "source_file": "tests/test_memory_dedup.py", "source_location": "L74", - "community": 521, + "community": 140, "norm_label": ".test_threshold_boundary()", "id": "tests_test_memory_dedup_testthresholdboundary_test_threshold_boundary" }, @@ -35759,7 +35822,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L38", - "community": 521, + "community": 140, "norm_label": "keys with jaccard > 0.8 should merge.", "id": "tests_test_memory_dedup_rationale_38" }, @@ -35768,7 +35831,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L48", - "community": 521, + "community": 140, "norm_label": "keys with low similarity should not merge.", "id": "tests_test_memory_dedup_rationale_48" }, @@ -35777,7 +35840,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L75", - "community": 521, + "community": 140, "norm_label": "keys with jaccard <= 0.8 should not merge.", "id": "tests_test_memory_dedup_rationale_75" }, @@ -35786,7 +35849,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L1", - "community": 518, + "community": 574, "norm_label": "test_memory_maintenance.py", "id": "tests_test_memory_maintenance_py" }, @@ -35795,7 +35858,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L18", - "community": 518, + "community": 574, "norm_label": "brt()", "id": "tests_test_memory_maintenance_brt" }, @@ -35804,7 +35867,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L23", - "community": 518, + "community": 574, "norm_label": "create_memories()", "id": "tests_test_memory_maintenance_create_memories" }, @@ -35813,7 +35876,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L46", - "community": 518, + "community": 574, "norm_label": "testdecay", "id": "tests_test_memory_maintenance_testdecay" }, @@ -35822,7 +35885,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L47", - "community": 518, + "community": 574, "norm_label": ".test_active_memory_decays()", "id": "tests_test_memory_maintenance_testdecay_test_active_memory_decays" }, @@ -35831,7 +35894,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L54", - "community": 518, + "community": 574, "norm_label": ".test_zero_access_count_still_decays()", "id": "tests_test_memory_maintenance_testdecay_test_zero_access_count_still_decays" }, @@ -35840,7 +35903,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L61", - "community": 518, + "community": 574, "norm_label": ".test_high_score_decays_proportionally()", "id": "tests_test_memory_maintenance_testdecay_test_high_score_decays_proportionally" }, @@ -35849,7 +35912,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L67", - "community": 518, + "community": 574, "norm_label": ".test_very_low_score_stays_above_zero()", "id": "tests_test_memory_maintenance_testdecay_test_very_low_score_stays_above_zero" }, @@ -35858,7 +35921,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L74", - "community": 518, + "community": 574, "norm_label": ".test_multiple_users_all_decayed()", "id": "tests_test_memory_maintenance_testdecay_test_multiple_users_all_decayed" }, @@ -35930,7 +35993,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L133", - "community": 518, + "community": 574, "norm_label": "testdecayandarchivetogether", "id": "tests_test_memory_maintenance_testdecayandarchivetogether" }, @@ -35939,7 +36002,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L134", - "community": 518, + "community": 574, "norm_label": ".test_decay_then_archive_check()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_decay_then_archive_check" }, @@ -35948,7 +36011,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L143", - "community": 518, + "community": 574, "norm_label": ".test_score_above_threshold_after_decay_not_archived()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_score_above_threshold_after_decay_not_archived" }, @@ -35957,7 +36020,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L150", - "community": 518, + "community": 574, "norm_label": ".test_score_just_below_threshold_archived()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_score_just_below_threshold_archived" }, @@ -35966,7 +36029,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L156", - "community": 518, + "community": 574, "norm_label": ".test_days_just_below_threshold_not_archived()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_days_just_below_threshold_not_archived" }, @@ -35975,7 +36038,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L163", - "community": 518, + "community": 574, "norm_label": ".test_days_just_above_threshold_archived()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_days_just_above_threshold_archived" }, @@ -36002,7 +36065,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L24", - "community": 518, + "community": 574, "norm_label": "helper to create memories with controlled basescore, lastaccessedat, accesscount", "id": "tests_test_memory_maintenance_rationale_24" }, @@ -36011,7 +36074,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L55", - "community": 518, + "community": 574, "norm_label": "decay applies to all active memories, not just accessed ones.", "id": "tests_test_memory_maintenance_rationale_55" }, @@ -36020,7 +36083,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L68", - "community": 518, + "community": 574, "norm_label": "basescore should never reach exactly 0 from decay alone.", "id": "tests_test_memory_maintenance_rationale_68" }, @@ -36074,7 +36137,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L135", - "community": 518, + "community": 574, "norm_label": "decay happens first, then archive check with new scores.", "id": "tests_test_memory_maintenance_rationale_135" }, @@ -36083,7 +36146,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L144", - "community": 518, + "community": 574, "norm_label": "score that decays to >= threshold stays alive. 0.12 * 0.90 = 0.108 >= 0.1.", "id": "tests_test_memory_maintenance_rationale_144" }, @@ -36092,7 +36155,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L157", - "community": 518, + "community": 574, "norm_label": "89 days with low score \u2192 not archived (need > 90).", "id": "tests_test_memory_maintenance_rationale_157" }, @@ -36137,7 +36200,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L15", - "community": 627, + "community": 140, "norm_label": ".test_admin_user()", "id": "tests_test_memory_manager_testgetmemorylimit_test_admin_user" }, @@ -36155,7 +36218,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L20", - "community": 632, + "community": 140, "norm_label": ".test_create()", "id": "tests_test_memory_manager_testupsertmemory_test_create" }, @@ -36173,7 +36236,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L40", - "community": 633, + "community": 140, "norm_label": ".test_unchanged()", "id": "tests_test_memory_manager_testupsertmemory_test_unchanged" }, @@ -36191,7 +36254,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L59", - "community": 635, + "community": 140, "norm_label": ".test_limit_not_enforced_without_roles()", "id": "tests_test_memory_manager_testupsertmemory_test_limit_not_enforced_without_roles" }, @@ -36218,7 +36281,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L81", - "community": 636, + "community": 140, "norm_label": ".test_counts_active()", "id": "tests_test_memory_manager_testcountmemories_test_counts_active" }, @@ -36290,7 +36353,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L126", - "community": 630, + "community": 140, "norm_label": ".test_soft_delete()", "id": "tests_test_memory_manager_testdeletememory_test_soft_delete" }, @@ -36299,7 +36362,7 @@ "file_type": "code", "source_file": "tests/test_memory_manager.py", "source_location": "L132", - "community": 631, + "community": 140, "norm_label": ".test_delete_nonexistent()", "id": "tests_test_memory_manager_testdeletememory_test_delete_nonexistent" }, @@ -36416,7 +36479,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L60", - "community": 523, + "community": 568, "norm_label": ".test_memory_tool_names_unchanged()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_memory_tool_names_unchanged" }, @@ -36425,7 +36488,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L64", - "community": 609, + "community": 568, "norm_label": "testtoolregistry", "id": "tests_test_memory_tools_wiring_testtoolregistry" }, @@ -36434,7 +36497,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L67", - "community": 609, + "community": 568, "norm_label": ".test_registry_contains_memory_tools()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_contains_memory_tools" }, @@ -36443,7 +36506,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L71", - "community": 609, + "community": 568, "norm_label": ".test_registry_values_are_callable()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_values_are_callable" }, @@ -36452,7 +36515,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L75", - "community": 609, + "community": 568, "norm_label": ".test_registry_matches_tool_names()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_matches_tool_names" }, @@ -36461,7 +36524,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L79", - "community": 49, + "community": 627, "norm_label": "testmakechatincludesmemorytools", "id": "tests_test_memory_tools_wiring_testmakechatincludesmemorytools" }, @@ -36479,7 +36542,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L112", - "community": 49, + "community": 621, "norm_label": "testdispatchroutesmemorytools", "id": "tests_test_memory_tools_wiring_testdispatchroutesmemorytools" }, @@ -36533,7 +36596,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L65", - "community": 609, + "community": 568, "norm_label": "tool_registry pattern must work correctly.", "id": "tests_test_memory_tools_wiring_rationale_65" }, @@ -36542,7 +36605,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L80", - "community": 49, + "community": 627, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_80" }, @@ -36551,7 +36614,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L113", - "community": 49, + "community": 621, "norm_label": "dispatchtoolcall must route memory tool names via tool_registry.", "id": "tests_test_memory_tools_wiring_rationale_113" }, @@ -36668,7 +36731,7 @@ "file_type": "code", "source_file": "tests/test_models.py", "source_location": "L1", - "community": 566, + "community": 61, "norm_label": "test_models.py", "id": "tests_test_models_py" }, @@ -36884,7 +36947,7 @@ "file_type": "code", "source_file": "tests/test_models.py", "source_location": "L162", - "community": 566, + "community": 61, "norm_label": "testprometheussessionmodel", "id": "tests_test_models_testprometheussessionmodel" }, @@ -36893,7 +36956,7 @@ "file_type": "code", "source_file": "tests/test_models.py", "source_location": "L163", - "community": 566, + "community": 61, "norm_label": ".test_create_session()", "id": "tests_test_models_testprometheussessionmodel_test_create_session" }, @@ -36902,7 +36965,7 @@ "file_type": "code", "source_file": "tests/test_models.py", "source_location": "L172", - "community": 566, + "community": 61, "norm_label": ".test_default_history()", "id": "tests_test_models_testprometheussessionmodel_test_default_history" }, @@ -37109,7 +37172,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L1", - "community": 502, + "community": 576, "norm_label": "test_pagination.py", "id": "tests_test_pagination_py" }, @@ -37118,7 +37181,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L14", - "community": 502, + "community": 576, "norm_label": "app()", "id": "tests_test_pagination_app" }, @@ -37127,7 +37190,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L35", - "community": 502, + "community": 576, "norm_label": "client()", "id": "tests_test_pagination_client" }, @@ -37226,7 +37289,7 @@ "file_type": "rationale", "source_file": "tests/test_pagination.py", "source_location": "L1", - "community": 502, + "community": 576, "norm_label": "tests for inline pagination params (used in user + prometheus controllers).", "id": "tests_test_pagination_rationale_1" }, @@ -37244,7 +37307,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L26", - "community": 172, + "community": 29, "norm_label": "testprometheusinit", "id": "tests_test_prometheus_auth_coverage_testprometheusinit" }, @@ -37262,7 +37325,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L41", - "community": 172, + "community": 29, "norm_label": "testprometheussendmessage", "id": "tests_test_prometheus_auth_coverage_testprometheussendmessage" }, @@ -37325,7 +37388,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L248", - "community": 172, + "community": 29, "norm_label": ".test_init()", "id": "tests_test_prometheus_auth_coverage_testprometheuschatmanager_test_init" }, @@ -37487,7 +37550,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L469", - "community": 88, + "community": 29, "norm_label": "testauthenticationmanager", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager" }, @@ -37505,7 +37568,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L485", - "community": 88, + "community": 29, "norm_label": ".test_create_user_account_no_password_no_google()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_create_user_account_no_password_no_google" }, @@ -37514,7 +37577,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L496", - "community": 88, + "community": 29, "norm_label": ".test_create_user_account_username_taken()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_create_user_account_username_taken" }, @@ -37523,7 +37586,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L510", - "community": 88, + "community": 29, "norm_label": ".test_create_user_account_email_taken()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_create_user_account_email_taken" }, @@ -37541,7 +37604,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L539", - "community": 88, + "community": 29, "norm_label": ".test_create_user_account_with_google_id()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_create_user_account_with_google_id" }, @@ -37550,7 +37613,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L548", - "community": 88, + "community": 29, "norm_label": ".test_authenticate_google_user_found()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_authenticate_google_user_found" }, @@ -37559,7 +37622,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L563", - "community": 88, + "community": 29, "norm_label": ".test_authenticate_google_user_not_found()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_authenticate_google_user_not_found" }, @@ -37568,7 +37631,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L572", - "community": 88, + "community": 29, "norm_label": ".test_authenticate_google_user_exception()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_authenticate_google_user_exception" }, @@ -37595,7 +37658,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L611", - "community": 88, + "community": 29, "norm_label": ".test_authenticate_user_not_found()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_authenticate_user_not_found" }, @@ -37604,7 +37667,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L620", - "community": 88, + "community": 29, "norm_label": ".test_authenticate_user_no_password_hash()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_authenticate_user_no_password_hash" }, @@ -37613,7 +37676,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L631", - "community": 88, + "community": 29, "norm_label": ".test_authenticate_user_exception()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_authenticate_user_exception" }, @@ -37802,7 +37865,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L881", - "community": 190, + "community": 60, "norm_label": ".test_validate_session_expired_naive_tz()", "id": "tests_test_prometheus_auth_coverage_testsessionmanager_test_validate_session_expired_naive_tz" }, @@ -37811,7 +37874,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L895", - "community": 165, + "community": 60, "norm_label": ".test_validate_session_no_expiry()", "id": "tests_test_prometheus_auth_coverage_testsessionmanager_test_validate_session_no_expiry" }, @@ -37820,7 +37883,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L914", - "community": 172, + "community": 29, "norm_label": "testsso", "id": "tests_test_prometheus_auth_coverage_testsso" }, @@ -37829,7 +37892,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L919", - "community": 643, + "community": 58, "norm_label": "test_get_google_sso_with_redirect()", "id": "tests_test_prometheus_auth_coverage_test_get_google_sso_with_redirect" }, @@ -37838,7 +37901,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L938", - "community": 643, + "community": 58, "norm_label": "test_get_google_sso_default_redirect()", "id": "tests_test_prometheus_auth_coverage_test_get_google_sso_default_redirect" }, @@ -37856,7 +37919,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L42", - "community": 172, + "community": 29, "norm_label": "cover streammessage in agent.py.", "id": "tests_test_prometheus_auth_coverage_rationale_42" }, @@ -37892,7 +37955,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L470", - "community": 88, + "community": 29, "norm_label": "cover all methods in authentication.py (lines 13-75).", "id": "tests_test_prometheus_auth_coverage_rationale_470" }, @@ -37910,7 +37973,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L882", - "community": 190, + "community": 60, "norm_label": "exercises the tzinfo-is-none branch (line 144-148).", "id": "tests_test_prometheus_auth_coverage_rationale_882" }, @@ -37919,7 +37982,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L896", - "community": 165, + "community": 60, "norm_label": "exercises the expiresat-is-none branch (line 143).", "id": "tests_test_prometheus_auth_coverage_rationale_896" }, @@ -37928,7 +37991,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L915", - "community": 172, + "community": 29, "norm_label": "cover getgooglesso (lines 6-14).", "id": "tests_test_prometheus_auth_coverage_rationale_915" }, @@ -37955,7 +38018,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L44", - "community": 100, + "community": 568, "norm_label": "testmemorytoolfunctions", "id": "tests_test_prometheus_tools_testmemorytoolfunctions" }, @@ -37964,7 +38027,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L45", - "community": 100, + "community": 568, "norm_label": ".test_search_memory_has_docstring()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_search_memory_has_docstring" }, @@ -37973,7 +38036,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L49", - "community": 100, + "community": 568, "norm_label": ".test_save_memory_has_docstring()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_save_memory_has_docstring" }, @@ -37982,7 +38045,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L53", - "community": 100, + "community": 568, "norm_label": ".test_search_memory_signature()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_search_memory_signature" }, @@ -37991,7 +38054,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L59", - "community": 100, + "community": 568, "norm_label": ".test_save_memory_signature()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_save_memory_signature" }, @@ -38000,7 +38063,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L66", - "community": 100, + "community": 568, "norm_label": ".test_search_memory_has_type_hints()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_search_memory_has_type_hints" }, @@ -38009,7 +38072,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L71", - "community": 100, + "community": 568, "norm_label": ".test_save_memory_has_type_hints()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_save_memory_has_type_hints" }, @@ -38018,7 +38081,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L77", - "community": 100, + "community": 568, "norm_label": ".test_memory_tools_is_list_of_callables()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_memory_tools_is_list_of_callables" }, @@ -38027,7 +38090,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L83", - "community": 100, + "community": 568, "norm_label": ".test_memory_tool_names_unchanged()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_memory_tool_names_unchanged" }, @@ -38576,7 +38639,7 @@ "file_type": "code", "source_file": "tests/test_roles.py", "source_location": "L1", - "community": 577, + "community": 49, "norm_label": "test_roles.py", "id": "tests_test_roles_py" }, @@ -38585,7 +38648,7 @@ "file_type": "code", "source_file": "tests/test_roles.py", "source_location": "L4", - "community": 577, + "community": 45, "norm_label": "testpermission", "id": "tests_test_roles_testpermission" }, @@ -38594,7 +38657,7 @@ "file_type": "code", "source_file": "tests/test_roles.py", "source_location": "L5", - "community": 577, + "community": 45, "norm_label": ".test_permission_enum_values()", "id": "tests_test_roles_testpermission_test_permission_enum_values" }, @@ -38603,7 +38666,7 @@ "file_type": "code", "source_file": "tests/test_roles.py", "source_location": "L10", - "community": 577, + "community": 45, "norm_label": ".test_permission_all_includes_all()", "id": "tests_test_roles_testpermission_test_permission_all_includes_all" }, @@ -38900,7 +38963,7 @@ "file_type": "code", "source_file": "tests/test_roles_coverage.py", "source_location": "L83", - "community": 491, + "community": 45, "norm_label": "testpermissionall", "id": "tests_test_roles_coverage_testpermissionall" }, @@ -38909,7 +38972,7 @@ "file_type": "code", "source_file": "tests/test_roles_coverage.py", "source_location": "L84", - "community": 491, + "community": 45, "norm_label": ".test_all_includes_all_permissions()", "id": "tests_test_roles_coverage_testpermissionall_test_all_includes_all_permissions" }, @@ -39998,7 +40061,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L104", - "community": 503, + "community": 49, "norm_label": "test_dispatch_get_state()", "id": "tests_test_state_tools_test_dispatch_get_state" }, @@ -40394,7 +40457,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L291", - "community": 26, + "community": 500, "norm_label": "test_create_key_new_user()", "id": "tests_test_stocks_api_coverage_test_create_key_new_user" }, @@ -40412,7 +40475,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L323", - "community": 26, + "community": 500, "norm_label": "test_create_key_exception_rollback()", "id": "tests_test_stocks_api_coverage_test_create_key_exception_rollback" }, @@ -40565,7 +40628,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L473", - "community": 520, + "community": 3, "norm_label": ".test_deserialize_multiple_special_cols_with_none()", "id": "tests_test_stocks_api_coverage_testdeserializejsoncolumns_test_deserialize_multiple_special_cols_with_none" }, @@ -40790,7 +40853,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L686", - "community": 28, + "community": 541, "norm_label": ".test_historical_with_date_range()", "id": "tests_test_stocks_api_coverage_testqueryhistorical_test_historical_with_date_range" }, @@ -40889,7 +40952,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L766", - "community": 39, + "community": 190, "norm_label": ".test_fundamental_with_invalid_date()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_with_invalid_date" }, @@ -40943,7 +41006,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L819", - "community": 39, + "community": 17, "norm_label": ".test_fundamental_empty_search_string_no_dedup()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_empty_search_string_no_dedup" }, @@ -40952,7 +41015,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L828", - "community": 39, + "community": 17, "norm_label": ".test_fundamental_no_time_column()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_no_time_column" }, @@ -40997,7 +41060,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L890", - "community": 17, + "community": 39, "norm_label": ".test_fundamental_search_fallback_string_match()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_search_fallback_string_match" }, @@ -41033,7 +41096,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L963", - "community": 3, + "community": 112, "norm_label": ".test_fundamental_requires_search_fields_or_dates()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_requires_search_fields_or_dates" }, @@ -41195,7 +41258,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1139", - "community": 10, + "community": 521, "norm_label": ".test_cotations_http_route()", "id": "tests_test_stocks_api_coverage_testquerycotations_test_cotations_http_route" }, @@ -41321,7 +41384,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1315", - "community": 22, + "community": 493, "norm_label": ".test_cotations_search_required()", "id": "tests_test_stocks_api_coverage_testquerylivecotation_test_cotations_search_required" }, @@ -41519,7 +41582,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L474", - "community": 520, + "community": 3, "norm_label": "all four special_cols should parse correctly when mixed with none.", "id": "tests_test_stocks_api_coverage_rationale_474" }, @@ -41591,7 +41654,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L687", - "community": 28, + "community": 541, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_687" }, @@ -41627,7 +41690,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L767", - "community": 39, + "community": 190, "norm_label": "invalid date -> inner 400 passes through (not wrapped as 500).", "id": "tests_test_stocks_api_coverage_rationale_767" }, @@ -41636,7 +41699,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L820", - "community": 39, + "community": 17, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_820" }, @@ -41645,7 +41708,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L829", - "community": 39, + "community": 17, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_829" }, @@ -41654,7 +41717,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L842", - "community": 39, + "community": 190, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_842" }, @@ -41690,7 +41753,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L891", - "community": 17, + "community": 39, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_891" }, @@ -41762,7 +41825,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1140", - "community": 10, + "community": 521, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1140" }, @@ -41789,7 +41852,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1316", - "community": 22, + "community": 493, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1316" }, @@ -44669,7 +44732,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L190", - "community": 617, + "community": 93, "norm_label": "system prompt should instruct llm about memory vs state.", "id": "tests_test_agent_state_integration_rationale_190" }, @@ -44696,7 +44759,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1120", - "community": 99, + "community": 148, "norm_label": "generic exception in chat propagates to fastapi's default 500 handler.", "id": "tests_test_controllers_coverage_rationale_1120" }, @@ -44705,7 +44768,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1138", - "community": 45, + "community": 566, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1138" }, @@ -44714,7 +44777,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1152", - "community": 14, + "community": 577, "norm_label": "covers line 35: get /stocks/historical.", "id": "tests_test_controllers_coverage_rationale_1152" }, @@ -44723,7 +44786,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1166", - "community": 14, + "community": 610, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1166" }, @@ -44768,7 +44831,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1223", - "community": 529, + "community": 616, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1223" }, @@ -44777,7 +44840,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1226", - "community": 529, + "community": 617, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1226" }, @@ -44795,7 +44858,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1257", - "community": 529, + "community": 587, "norm_label": "covers lines 19-20: user not found raises 404.", "id": "tests_test_controllers_coverage_rationale_1257" }, @@ -44822,7 +44885,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1317", - "community": 563, + "community": 589, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1317" }, @@ -44831,7 +44894,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1334", - "community": 563, + "community": 592, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1334" }, @@ -44840,7 +44903,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1351", - "community": 563, + "community": 602, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1351" }, @@ -44849,7 +44912,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1375", - "community": 194, + "community": 45, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1375" }, @@ -44858,7 +44921,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1385", - "community": 194, + "community": 620, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1385" }, @@ -44867,7 +44930,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1388", - "community": 194, + "community": 620, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1388" }, @@ -44939,7 +45002,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L502", - "community": 88, + "community": 29, "norm_label": "cover all methods in authentication.py (lines 13-75).", "id": "tests_test_prometheus_auth_coverage_rationale_502" }, @@ -44957,7 +45020,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L914", - "community": 190, + "community": 60, "norm_label": "exercises the tzinfo-is-none branch (line 144-148).", "id": "tests_test_prometheus_auth_coverage_rationale_914" }, @@ -44966,7 +45029,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L928", - "community": 165, + "community": 60, "norm_label": "exercises the expiresat-is-none branch (line 143).", "id": "tests_test_prometheus_auth_coverage_rationale_928" }, @@ -44975,7 +45038,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L947", - "community": 172, + "community": 29, "norm_label": "cover getgooglesso (lines 6-14).", "id": "tests_test_prometheus_auth_coverage_rationale_947" }, @@ -45047,7 +45110,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L30", - "community": 521, + "community": 140, "norm_label": "keys with jaccard > 0.8 should merge.", "id": "tests_test_memory_dedup_rationale_30" }, @@ -45056,7 +45119,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L40", - "community": 521, + "community": 140, "norm_label": "keys with low similarity should not merge.", "id": "tests_test_memory_dedup_rationale_40" }, @@ -45065,7 +45128,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L67", - "community": 521, + "community": 140, "norm_label": "keys with jaccard <= 0.8 should not merge.", "id": "tests_test_memory_dedup_rationale_67" }, @@ -45542,7 +45605,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L7", - "community": 24, + "community": 8, "norm_label": "testagentsandboxintegration", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration" }, @@ -45551,7 +45614,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L8", - "community": 24, + "community": 8, "norm_label": ".test_build_system_prompt_includes_sandbox_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_includes_sandbox_instructions" }, @@ -45560,7 +45623,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L14", - "community": 24, + "community": 8, "norm_label": ".test_build_system_prompt_includes_state_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_includes_state_instructions" }, @@ -45569,7 +45632,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L19", - "community": 24, + "community": 8, "norm_label": ".test_build_system_prompt_with_state()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_with_state" }, @@ -48098,7 +48161,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L9", - "community": 24, + "community": 8, "norm_label": ".test_build_system_prompt_no_state()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_no_state" }, @@ -48107,7 +48170,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L20", - "community": 24, + "community": 8, "norm_label": ".test_build_system_prompt_empty_state()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_empty_state" }, @@ -48116,7 +48179,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L25", - "community": 24, + "community": 8, "norm_label": ".test_system_prompt_includes_state_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_system_prompt_includes_state_instructions" }, @@ -48125,7 +48188,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L30", - "community": 24, + "community": 8, "norm_label": ".test_system_prompt_includes_sandbox_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_system_prompt_includes_sandbox_instructions" }, @@ -48134,7 +48197,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L34", - "community": 24, + "community": 8, "norm_label": ".test_system_prompt_includes_cache_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_system_prompt_includes_cache_instructions" }, @@ -48143,7 +48206,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L38", - "community": 24, + "community": 8, "norm_label": ".test_makechat_uses_tool_registry()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_makechat_uses_tool_registry" }, @@ -48314,7 +48377,7 @@ "file_type": "code", "source_file": "tests/test_config_sandbox.py", "source_location": "L1", - "community": 577, + "community": 102, "norm_label": "test_config_sandbox.py", "id": "tests_test_config_sandbox_py" }, @@ -48737,7 +48800,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L194", - "community": 617, + "community": 93, "norm_label": "system prompt should instruct llm about memory vs state.", "id": "tests_test_agent_state_integration_rationale_194" }, @@ -49421,7 +49484,7 @@ "file_type": "rationale", "source_file": "tests/test_agent_state_integration.py", "source_location": "L191", - "community": 617, + "community": 93, "norm_label": "system prompt should instruct llm about memory vs state.", "id": "tests_test_agent_state_integration_rationale_191" }, @@ -49511,7 +49574,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/state.py", "source_location": "L22", - "community": 523, + "community": 568, "norm_label": "store a value in state. marks state as changed for context injection.", "id": "prometheus_state_rationale_22" }, @@ -49646,7 +49709,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L52", - "community": 521, + "community": 140, "norm_label": "keys with low similarity should not merge.", "id": "tests_test_memory_dedup_rationale_52" }, @@ -49655,7 +49718,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_dedup.py", "source_location": "L85", - "community": 521, + "community": 140, "norm_label": "keys with jaccard <= 0.8 should not merge.", "id": "tests_test_memory_dedup_rationale_85" }, @@ -49772,7 +49835,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L52", - "community": 49, + "community": 627, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_52" }, @@ -49781,7 +49844,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L89", - "community": 49, + "community": 621, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_89" }, @@ -49808,7 +49871,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L57", - "community": 49, + "community": 627, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_57" }, @@ -49817,7 +49880,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L92", - "community": 49, + "community": 621, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_92" }, @@ -49835,7 +49898,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L23", - "community": 518, + "community": 574, "norm_label": "helper to create memories with controlled basescore, lastaccessedat, accesscount", "id": "tests_test_memory_maintenance_rationale_23" }, @@ -49844,7 +49907,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L54", - "community": 518, + "community": 574, "norm_label": "decay applies to all active memories, not just accessed ones.", "id": "tests_test_memory_maintenance_rationale_54" }, @@ -49853,7 +49916,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L67", - "community": 518, + "community": 574, "norm_label": "basescore should never reach exactly 0 from decay alone.", "id": "tests_test_memory_maintenance_rationale_67" }, @@ -49907,7 +49970,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L134", - "community": 518, + "community": 574, "norm_label": "decay happens first, then archive check with new scores.", "id": "tests_test_memory_maintenance_rationale_134" }, @@ -49916,7 +49979,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L143", - "community": 518, + "community": 574, "norm_label": "score that decays to >= threshold stays alive. 0.11 * 0.95 = 0.1045 >= 0.1.", "id": "tests_test_memory_maintenance_rationale_143" }, @@ -49925,7 +49988,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L156", - "community": 518, + "community": 574, "norm_label": "89 days with low score \u2192 not archived (need > 90).", "id": "tests_test_memory_maintenance_rationale_156" }, @@ -50231,7 +50294,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1258", - "community": 529, + "community": 587, "norm_label": "covers lines 19-20: user not found raises 404.", "id": "tests_test_controllers_coverage_rationale_1258" }, @@ -50249,7 +50312,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1277", - "community": 563, + "community": 616, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1277" }, @@ -50267,7 +50330,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1318", - "community": 563, + "community": 589, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1318" }, @@ -50276,7 +50339,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1335", - "community": 563, + "community": 592, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1335" }, @@ -50285,7 +50348,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1352", - "community": 563, + "community": 602, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1352" }, @@ -50294,7 +50357,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1376", - "community": 194, + "community": 45, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1376" }, @@ -50303,7 +50366,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1386", - "community": 194, + "community": 45, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1386" }, @@ -50312,7 +50375,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1389", - "community": 194, + "community": 592, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1389" }, @@ -50573,7 +50636,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L56", - "community": 49, + "community": 627, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_56" }, @@ -50582,7 +50645,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L91", - "community": 49, + "community": 621, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_91" }, @@ -50906,7 +50969,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L48", - "community": 49, + "community": 627, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_48" }, @@ -50915,7 +50978,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L76", - "community": 49, + "community": 621, "norm_label": "dispatchtoolcall must route memory tool names to executememorytool.", "id": "tests_test_memory_tools_wiring_rationale_76" }, @@ -51032,7 +51095,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L10", - "community": 498, + "community": 72, "norm_label": "testmemorycontrollerroutes", "id": "tests_test_memory_controller_testmemorycontrollerroutes" }, @@ -51041,7 +51104,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L11", - "community": 498, + "community": 72, "norm_label": ".test_get_memories_endpoint_exists()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_get_memories_endpoint_exists" }, @@ -51050,7 +51113,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L15", - "community": 498, + "community": 72, "norm_label": ".test_post_memories_endpoint_exists()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_post_memories_endpoint_exists" }, @@ -51059,7 +51122,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L19", - "community": 498, + "community": 72, "norm_label": ".test_delete_memories_endpoint_exists()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_delete_memories_endpoint_exists" }, @@ -51068,7 +51131,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L23", - "community": 498, + "community": 72, "norm_label": ".test_get_memories_rejects_unauthenticated()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_get_memories_rejects_unauthenticated" }, @@ -51077,7 +51140,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L38", - "community": 498, + "community": 493, "norm_label": ".test_get_memories_rejects_basic_user()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_get_memories_rejects_basic_user" }, @@ -51914,7 +51977,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L11", - "community": 498, + "community": 72, "norm_label": "verify memory endpoints exist and are wired correctly.", "id": "tests_test_memory_controller_rationale_11" }, @@ -51923,7 +51986,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L14", - "community": 498, + "community": 72, "norm_label": "get /prometheus/memories exists.", "id": "tests_test_memory_controller_rationale_14" }, @@ -51932,7 +51995,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L20", - "community": 498, + "community": 72, "norm_label": "post /prometheus/memories exists.", "id": "tests_test_memory_controller_rationale_20" }, @@ -51941,7 +52004,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L25", - "community": 498, + "community": 72, "norm_label": "delete /prometheus/memories/{id} exists.", "id": "tests_test_memory_controller_rationale_25" }, @@ -51950,7 +52013,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L30", - "community": 498, + "community": 72, "norm_label": "get /memories requires authentication.", "id": "tests_test_memory_controller_rationale_30" }, @@ -51959,7 +52022,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L47", - "community": 498, + "community": 493, "norm_label": "get /memories requires use_prometheus (basic user role denied).", "id": "tests_test_memory_controller_rationale_47" }, @@ -52058,7 +52121,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L19", - "community": 627, + "community": 140, "norm_label": "admin gets extended limit (has all permissions).", "id": "tests_test_memory_manager_rationale_19" }, @@ -52067,7 +52130,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L25", - "community": 632, + "community": 140, "norm_label": "creates a new memory.", "id": "tests_test_memory_manager_rationale_25" }, @@ -52085,7 +52148,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L43", - "community": 633, + "community": 140, "norm_label": "returns unchanged when value is identical.", "id": "tests_test_memory_manager_rationale_43" }, @@ -52103,7 +52166,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L61", - "community": 635, + "community": 140, "norm_label": "no role check when user_roles not provided.", "id": "tests_test_memory_manager_rationale_61" }, @@ -52121,7 +52184,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L82", - "community": 636, + "community": 140, "norm_label": "counts only non-archived memories.", "id": "tests_test_memory_manager_rationale_82" }, @@ -52166,7 +52229,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L135", - "community": 630, + "community": 140, "norm_label": "soft-deletes a memory.", "id": "tests_test_memory_manager_rationale_135" }, @@ -52175,7 +52238,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_manager.py", "source_location": "L142", - "community": 631, + "community": 140, "norm_label": "returns false for non-existent memory.", "id": "tests_test_memory_manager_rationale_142" }, @@ -52697,7 +52760,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L492", - "community": 88, + "community": 29, "norm_label": "cover all methods in authentication.py (lines 13-75).", "id": "tests_test_prometheus_auth_coverage_rationale_492" }, @@ -52715,7 +52778,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L904", - "community": 190, + "community": 60, "norm_label": "exercises the tzinfo-is-none branch (line 144-148).", "id": "tests_test_prometheus_auth_coverage_rationale_904" }, @@ -52724,7 +52787,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L918", - "community": 165, + "community": 60, "norm_label": "exercises the expiresat-is-none branch (line 143).", "id": "tests_test_prometheus_auth_coverage_rationale_918" }, @@ -52733,7 +52796,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L937", - "community": 172, + "community": 29, "norm_label": "cover getgooglesso (lines 6-14).", "id": "tests_test_prometheus_auth_coverage_rationale_937" }, @@ -52940,7 +53003,7 @@ "file_type": "code", "source_file": "main/app/prometheus/agent.py", "source_location": "L33", - "community": 93, + "community": 116, "norm_label": ".updatedates()", "id": "prometheus_agent_prometheus_updatedates" }, @@ -52976,7 +53039,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L27", - "community": 172, + "community": 29, "norm_label": "cover __init__ and updatedates.", "id": "tests_test_prometheus_auth_coverage_rationale_27" }, @@ -52985,7 +53048,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L58", - "community": 172, + "community": 29, "norm_label": "cover sendmessage and streammessage in agent.py.", "id": "tests_test_prometheus_auth_coverage_rationale_58" }, @@ -53003,7 +53066,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L398", - "community": 88, + "community": 29, "norm_label": "cover all methods in authentication.py (lines 13-75).", "id": "tests_test_prometheus_auth_coverage_rationale_398" }, @@ -53021,7 +53084,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L810", - "community": 190, + "community": 60, "norm_label": "exercises the tzinfo-is-none branch (line 144-148).", "id": "tests_test_prometheus_auth_coverage_rationale_810" }, @@ -53030,7 +53093,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L824", - "community": 165, + "community": 60, "norm_label": "exercises the expiresat-is-none branch (line 143).", "id": "tests_test_prometheus_auth_coverage_rationale_824" }, @@ -53039,7 +53102,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L843", - "community": 172, + "community": 29, "norm_label": "cover getgooglesso (lines 6-14).", "id": "tests_test_prometheus_auth_coverage_rationale_843" }, @@ -53048,7 +53111,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L26", - "community": 172, + "community": 29, "norm_label": "testprometheusgeneratorinit", "id": "tests_test_prometheus_auth_coverage_testprometheusgeneratorinit" }, @@ -53057,7 +53120,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L57", - "community": 172, + "community": 29, "norm_label": "testprometheusgeneratorexecuteworkflow", "id": "tests_test_prometheus_auth_coverage_testprometheusgeneratorexecuteworkflow" }, @@ -53246,7 +53309,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L664", - "community": 88, + "community": 29, "norm_label": "cover all methods in authentication.py (lines 13-75).", "id": "tests_test_prometheus_auth_coverage_rationale_664" }, @@ -53264,7 +53327,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L1076", - "community": 190, + "community": 60, "norm_label": "exercises the tzinfo-is-none branch (line 144-148).", "id": "tests_test_prometheus_auth_coverage_rationale_1076" }, @@ -53273,7 +53336,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L1090", - "community": 165, + "community": 60, "norm_label": "exercises the expiresat-is-none branch (line 143).", "id": "tests_test_prometheus_auth_coverage_rationale_1090" }, @@ -53282,7 +53345,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L1109", - "community": 172, + "community": 29, "norm_label": "cover getgooglesso (lines 6-14).", "id": "tests_test_prometheus_auth_coverage_rationale_1109" }, @@ -53291,7 +53354,7 @@ "file_type": "code", "source_file": "main/app/prometheus/generation.py", "source_location": "L1", - "community": 566, + "community": 29, "norm_label": "generation.py", "id": "main_app_prometheus_generation_py" }, @@ -53444,7 +53507,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L538", - "community": 47, + "community": 45, "norm_label": "covers line 24: get /user/me returns currentuser.", "id": "tests_test_controllers_coverage_rationale_538" }, @@ -53471,7 +53534,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L611", - "community": 541, + "community": 45, "norm_label": "covers lines 66, 68-72, 74: get /user/sessions.", "id": "tests_test_controllers_coverage_rationale_611" }, @@ -53480,7 +53543,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L614", - "community": 541, + "community": 63, "norm_label": "covers lines 66, 68-72, 74: full sessions listing.", "id": "tests_test_controllers_coverage_rationale_614" }, @@ -53489,7 +53552,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L665", - "community": 63, + "community": 45, "norm_label": "covers lines 100-104, 106: get /user/sessions/current.", "id": "tests_test_controllers_coverage_rationale_665" }, @@ -53552,7 +53615,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L802", - "community": 616, + "community": 45, "norm_label": "covers lines 143, 145, 147-148: post /user/sessions/revoke-all.", "id": "tests_test_controllers_coverage_rationale_802" }, @@ -53561,7 +53624,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L805", - "community": 616, + "community": 63, "norm_label": "covers lines 143, 145, 147-148.", "id": "tests_test_controllers_coverage_rationale_805" }, @@ -53579,7 +53642,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L846", - "community": 99, + "community": 45, "norm_label": "covers lines 33-36: get /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_846" }, @@ -53588,7 +53651,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L864", - "community": 99, + "community": 45, "norm_label": "covers line 52: post /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_864" }, @@ -53723,7 +53786,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1116", - "community": 99, + "community": 148, "norm_label": "generic exception in chat propagates to fastapi's default 500 handler.", "id": "tests_test_controllers_coverage_rationale_1116" }, @@ -53732,7 +53795,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1134", - "community": 45, + "community": 566, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1134" }, @@ -53741,7 +53804,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1148", - "community": 14, + "community": 577, "norm_label": "covers line 35: get /stocks/historical.", "id": "tests_test_controllers_coverage_rationale_1148" }, @@ -53750,7 +53813,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1162", - "community": 14, + "community": 610, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1162" }, @@ -53795,7 +53858,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1219", - "community": 529, + "community": 616, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1219" }, @@ -53804,7 +53867,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1222", - "community": 529, + "community": 617, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1222" }, @@ -53822,7 +53885,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1254", - "community": 529, + "community": 587, "norm_label": "covers lines 19-20: user not found raises 404.", "id": "tests_test_controllers_coverage_rationale_1254" }, @@ -53858,7 +53921,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1314", - "community": 563, + "community": 589, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1314" }, @@ -53867,7 +53930,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1331", - "community": 563, + "community": 592, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1331" }, @@ -53876,7 +53939,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1348", - "community": 563, + "community": 602, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1348" }, @@ -53885,7 +53948,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1372", - "community": 563, + "community": 589, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1372" }, @@ -54056,7 +54119,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L536", - "community": 47, + "community": 45, "norm_label": "covers line 24: get /user/me returns currentuser.", "id": "tests_test_controllers_coverage_rationale_536" }, @@ -54083,7 +54146,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L609", - "community": 541, + "community": 45, "norm_label": "covers lines 66, 68-72, 74: get /user/sessions.", "id": "tests_test_controllers_coverage_rationale_609" }, @@ -54092,7 +54155,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L612", - "community": 541, + "community": 63, "norm_label": "covers lines 66, 68-72, 74: full sessions listing.", "id": "tests_test_controllers_coverage_rationale_612" }, @@ -54101,7 +54164,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L663", - "community": 63, + "community": 45, "norm_label": "covers lines 100-104, 106: get /user/sessions/current.", "id": "tests_test_controllers_coverage_rationale_663" }, @@ -54164,7 +54227,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L800", - "community": 616, + "community": 45, "norm_label": "covers lines 143, 145, 147-148: post /user/sessions/revoke-all.", "id": "tests_test_controllers_coverage_rationale_800" }, @@ -54173,7 +54236,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L803", - "community": 616, + "community": 63, "norm_label": "covers lines 143, 145, 147-148.", "id": "tests_test_controllers_coverage_rationale_803" }, @@ -54191,7 +54254,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L844", - "community": 99, + "community": 45, "norm_label": "covers lines 33-36: get /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_844" }, @@ -54200,7 +54263,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L862", - "community": 99, + "community": 45, "norm_label": "covers line 52: post /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_862" }, @@ -54335,7 +54398,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1115", - "community": 99, + "community": 148, "norm_label": "generic exception in chat propagates to fastapi's default 500 handler.", "id": "tests_test_controllers_coverage_rationale_1115" }, @@ -54344,7 +54407,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1133", - "community": 45, + "community": 566, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1133" }, @@ -54353,7 +54416,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1147", - "community": 14, + "community": 577, "norm_label": "covers line 35: get /stocks/historical.", "id": "tests_test_controllers_coverage_rationale_1147" }, @@ -54362,7 +54425,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1161", - "community": 14, + "community": 610, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1161" }, @@ -54398,7 +54461,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1218", - "community": 529, + "community": 616, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1218" }, @@ -54407,7 +54470,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1221", - "community": 529, + "community": 617, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1221" }, @@ -54425,7 +54488,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1253", - "community": 529, + "community": 587, "norm_label": "covers lines 19-20: user not found raises 404.", "id": "tests_test_controllers_coverage_rationale_1253" }, @@ -54461,7 +54524,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1313", - "community": 563, + "community": 589, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1313" }, @@ -54470,7 +54533,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1330", - "community": 563, + "community": 592, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1330" }, @@ -54479,7 +54542,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1347", - "community": 563, + "community": 602, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1347" }, @@ -54488,7 +54551,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1371", - "community": 194, + "community": 45, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1371" }, @@ -54497,7 +54560,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1381", - "community": 194, + "community": 45, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1381" }, @@ -54506,7 +54569,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1384", - "community": 194, + "community": 620, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1384" }, @@ -55019,7 +55082,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L550", - "community": 520, + "community": 3, "norm_label": "all four special_cols should parse correctly when mixed with none.", "id": "tests_test_stocks_api_coverage_rationale_550" }, @@ -55118,7 +55181,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L843", - "community": 39, + "community": 190, "norm_label": "invalid date -> inner 400 passes through (not wrapped as 500).", "id": "tests_test_stocks_api_coverage_rationale_843" }, @@ -55181,7 +55244,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L967", - "community": 17, + "community": 39, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_967" }, @@ -55253,7 +55316,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1216", - "community": 10, + "community": 521, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1216" }, @@ -55280,7 +55343,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1392", - "community": 22, + "community": 493, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1392" }, @@ -55415,7 +55478,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1394", - "community": 22, + "community": 493, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1394" }, @@ -55604,7 +55667,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1468", - "community": 22, + "community": 493, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1468" }, @@ -55784,7 +55847,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L549", - "community": 520, + "community": 3, "norm_label": "all four special_cols should parse correctly when mixed with none.", "id": "tests_test_stocks_api_coverage_rationale_549" }, @@ -55856,7 +55919,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L762", - "community": 28, + "community": 541, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_762" }, @@ -55892,7 +55955,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L895", - "community": 39, + "community": 17, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_895" }, @@ -55901,7 +55964,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L904", - "community": 39, + "community": 17, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_904" }, @@ -55937,7 +56000,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L964", - "community": 17, + "community": 39, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_964" }, @@ -56009,7 +56072,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1212", - "community": 10, + "community": 521, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1212" }, @@ -56036,7 +56099,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1464", - "community": 22, + "community": 493, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1464" }, @@ -56072,7 +56135,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1456", - "community": 22, + "community": 493, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1456" }, @@ -56108,7 +56171,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1297", - "community": 498, + "community": 493, "norm_label": ".test_cotations_search_required()", "id": "tests_test_stocks_api_coverage_testquerycotations_test_cotations_search_required" }, @@ -56117,7 +56180,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1298", - "community": 498, + "community": 493, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1298" }, @@ -56153,7 +56216,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1210", - "community": 10, + "community": 521, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1210" }, @@ -56162,7 +56225,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1288", - "community": 498, + "community": 493, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1288" }, @@ -56171,7 +56234,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L832", - "community": 39, + "community": 17, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_832" }, @@ -56180,7 +56243,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L885", - "community": 39, + "community": 17, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_885" }, @@ -56189,7 +56252,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L894", - "community": 39, + "community": 17, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_894" }, @@ -56225,7 +56288,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L954", - "community": 17, + "community": 39, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_954" }, @@ -56297,7 +56360,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1191", - "community": 10, + "community": 521, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1191" }, @@ -56828,7 +56891,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1170", - "community": 10, + "community": 521, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1170" }, @@ -56873,7 +56936,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1141", - "community": 10, + "community": 521, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1141" }, @@ -56936,7 +56999,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L63", - "community": 186, + "community": 157, "norm_label": "getrealtimecotation()", "id": "controller_stocksapi_controller_getrealtimecotation" }, @@ -56954,7 +57017,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1148", - "community": 10, + "community": 521, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1148" }, @@ -56981,7 +57044,7 @@ "file_type": "code", "source_file": "main/app/prometheus/chat.py", "source_location": "L14", - "community": 172, + "community": 29, "norm_label": ".__init__()", "id": "prometheus_chat_prometheuschatmanager_init" }, @@ -56990,7 +57053,7 @@ "file_type": "code", "source_file": "main/app/prometheus/generation.py", "source_location": "L19", - "community": 566, + "community": 29, "norm_label": "sessionproxy", "id": "prometheus_generation_sessionproxy" }, @@ -57008,7 +57071,7 @@ "file_type": "code", "source_file": "main/app/prometheus/generation.py", "source_location": "L23", - "community": 566, + "community": 29, "norm_label": ".post()", "id": "prometheus_generation_sessionproxy_post" }, @@ -57044,7 +57107,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L23", - "community": 186, + "community": 157, "norm_label": "apikeytest()", "id": "controller_stocksapi_controller_apikeytest" }, @@ -57107,7 +57170,7 @@ "file_type": "code", "source_file": "main/utils/pagination.py", "source_location": "L1", - "community": 528, + "community": 502, "norm_label": "pagination.py", "id": "main_utils_pagination_py" }, @@ -57116,7 +57179,7 @@ "file_type": "code", "source_file": "main/utils/pagination.py", "source_location": "L4", - "community": 528, + "community": 502, "norm_label": "paginationparams", "id": "utils_pagination_paginationparams" }, @@ -57125,7 +57188,7 @@ "file_type": "code", "source_file": "main/utils/pagination.py", "source_location": "L5", - "community": 528, + "community": 502, "norm_label": ".__init__()", "id": "utils_pagination_paginationparams_init" }, @@ -57152,7 +57215,7 @@ "file_type": "code", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L20", - "community": 602, + "community": 26, "norm_label": "dbsession()", "id": "tests_test_api_key_quota_atomic_dbsession" }, @@ -57161,7 +57224,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L21", - "community": 602, + "community": 26, "norm_label": "create an in-memory sqlite database for testing.", "id": "tests_test_api_key_quota_atomic_rationale_21" }, @@ -57170,7 +57233,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L34", - "community": 602, + "community": 26, "norm_label": "sample api key data for tests.", "id": "tests_test_api_key_quota_atomic_rationale_34" }, @@ -57224,7 +57287,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L166", - "community": 589, + "community": 26, "norm_label": "test that invalid api key returns zero rows affected.", "id": "tests_test_api_key_quota_atomic_rationale_166" }, @@ -57233,7 +57296,7 @@ "file_type": "rationale", "source_file": "tests/test_api_key_quota_atomic.py", "source_location": "L180", - "community": 589, + "community": 26, "norm_label": "test that multiple api keys have independent quotas.", "id": "tests_test_api_key_quota_atomic_rationale_180" }, @@ -57323,7 +57386,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1194", - "community": 14, + "community": 45, "norm_label": "teststocksapikeytest", "id": "tests_test_controllers_coverage_teststocksapikeytest" }, @@ -57368,7 +57431,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L148", - "community": 120, + "community": 45, "norm_label": "covers lines 44-54, 63, 66-71: register success, valueerror, generic exception.", "id": "tests_test_controllers_coverage_rationale_148" }, @@ -57503,7 +57566,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L425", - "community": 120, + "community": 45, "norm_label": "covers lines 155-156, 158, 160-168, 170-177, 179-184, 186, 190-204: googlecallba", "id": "tests_test_controllers_coverage_rationale_425" }, @@ -57548,7 +57611,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L581", - "community": 47, + "community": 45, "norm_label": "covers line 24: get /user/me returns currentuser.", "id": "tests_test_controllers_coverage_rationale_581" }, @@ -57575,7 +57638,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L654", - "community": 541, + "community": 45, "norm_label": "covers lines 66, 68-72, 74: get /user/sessions.", "id": "tests_test_controllers_coverage_rationale_654" }, @@ -57584,7 +57647,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L657", - "community": 541, + "community": 63, "norm_label": "covers lines 66, 68-72, 74: full sessions listing.", "id": "tests_test_controllers_coverage_rationale_657" }, @@ -57593,7 +57656,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L708", - "community": 63, + "community": 45, "norm_label": "covers lines 100-104, 106: get /user/sessions/current.", "id": "tests_test_controllers_coverage_rationale_708" }, @@ -57656,7 +57719,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L845", - "community": 616, + "community": 45, "norm_label": "covers lines 143, 145, 147-148: post /user/sessions/revoke-all.", "id": "tests_test_controllers_coverage_rationale_845" }, @@ -57665,7 +57728,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L848", - "community": 616, + "community": 63, "norm_label": "covers lines 143, 145, 147-148.", "id": "tests_test_controllers_coverage_rationale_848" }, @@ -57683,7 +57746,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L889", - "community": 99, + "community": 45, "norm_label": "covers lines 33-36: get /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_889" }, @@ -57692,7 +57755,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L907", - "community": 99, + "community": 45, "norm_label": "covers line 52: post /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_907" }, @@ -57827,7 +57890,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1160", - "community": 99, + "community": 148, "norm_label": "covers line 125, 126-128: generic exception in chat.", "id": "tests_test_controllers_coverage_rationale_1160" }, @@ -57836,7 +57899,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1181", - "community": 45, + "community": 566, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1181" }, @@ -57854,7 +57917,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1206", - "community": 14, + "community": 577, "norm_label": "covers line 35: get /stocks/historical.", "id": "tests_test_controllers_coverage_rationale_1206" }, @@ -57863,7 +57926,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1220", - "community": 14, + "community": 610, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1220" }, @@ -57899,7 +57962,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1280", - "community": 529, + "community": 617, "norm_label": "covers lines 17, 22-27: user found, role not present, role added.", "id": "tests_test_controllers_coverage_rationale_1280" }, @@ -57908,7 +57971,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1312", - "community": 529, + "community": 587, "norm_label": "covers lines 19-20: user not found raises 404.", "id": "tests_test_controllers_coverage_rationale_1312" }, @@ -57926,7 +57989,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1406", - "community": 563, + "community": 602, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1406" }, @@ -57935,7 +57998,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1430", - "community": 194, + "community": 45, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1430" }, @@ -57944,7 +58007,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1440", - "community": 194, + "community": 45, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1440" }, @@ -57953,7 +58016,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1443", - "community": 194, + "community": 620, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1443" }, @@ -58151,7 +58214,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L28", - "community": 172, + "community": 29, "norm_label": "cover __init__ and updatedates (lines 22-37).", "id": "tests_test_prometheus_auth_coverage_rationale_28" }, @@ -58160,7 +58223,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L59", - "community": 172, + "community": 29, "norm_label": "cover executeworkflow (lines 39-363).", "id": "tests_test_prometheus_auth_coverage_rationale_59" }, @@ -58259,7 +58322,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L665", - "community": 88, + "community": 29, "norm_label": "cover all methods in authentication.py (lines 13-75).", "id": "tests_test_prometheus_auth_coverage_rationale_665" }, @@ -58277,7 +58340,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L1077", - "community": 190, + "community": 60, "norm_label": "exercises the tzinfo-is-none branch (line 144-148).", "id": "tests_test_prometheus_auth_coverage_rationale_1077" }, @@ -58286,7 +58349,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L1091", - "community": 165, + "community": 60, "norm_label": "exercises the expiresat-is-none branch (line 143).", "id": "tests_test_prometheus_auth_coverage_rationale_1091" }, @@ -58295,7 +58358,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L1110", - "community": 172, + "community": 29, "norm_label": "cover getgooglesso (lines 6-14).", "id": "tests_test_prometheus_auth_coverage_rationale_1110" }, @@ -58601,7 +58664,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L548", - "community": 520, + "community": 3, "norm_label": "all four special_cols should parse correctly when mixed with none.", "id": "tests_test_stocks_api_coverage_rationale_548" }, @@ -58673,7 +58736,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L761", - "community": 28, + "community": 541, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_761" }, @@ -58691,7 +58754,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L831", - "community": 39, + "community": 190, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_831" }, @@ -58700,7 +58763,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L884", - "community": 39, + "community": 17, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_884" }, @@ -58709,7 +58772,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L893", - "community": 39, + "community": 17, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_893" }, @@ -58754,7 +58817,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L953", - "community": 17, + "community": 39, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_953" }, @@ -58934,7 +58997,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L757", - "community": 28, + "community": 541, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_757" }, @@ -58961,7 +59024,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L827", - "community": 39, + "community": 190, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_827" }, @@ -58970,7 +59033,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L876", - "community": 39, + "community": 17, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_876" }, @@ -59033,7 +59096,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L756", - "community": 28, + "community": 541, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_756" }, @@ -59051,7 +59114,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L826", - "community": 39, + "community": 190, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_826" }, @@ -59087,7 +59150,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L943", - "community": 17, + "community": 39, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_943" }, @@ -59105,7 +59168,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/generation.py", "source_location": "L20", - "community": 566, + "community": 29, "norm_label": "thread-safe proxy that delegates to per-thread sessions.", "id": "prometheus_generation_rationale_20" }, @@ -59168,7 +59231,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L710", - "community": 28, + "community": 541, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_710" }, @@ -59186,7 +59249,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L780", - "community": 39, + "community": 190, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_780" }, @@ -59195,7 +59258,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L828", - "community": 39, + "community": 17, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_828" }, @@ -59204,7 +59267,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L837", - "community": 39, + "community": 17, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_837" }, @@ -59240,7 +59303,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L897", - "community": 17, + "community": 39, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_897" }, @@ -59339,7 +59402,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L711", - "community": 28, + "community": 541, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_711" }, @@ -59357,7 +59420,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L781", - "community": 39, + "community": 190, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_781" }, @@ -59366,7 +59429,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L838", - "community": 39, + "community": 17, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_838" }, @@ -59465,7 +59528,7 @@ "file_type": "code", "source_file": "main/utils/errors.py", "source_location": "L65", - "community": 120, + "community": 63, "norm_label": "register_error_handlers()", "id": "utils_errors_register_error_handlers" }, @@ -59924,7 +59987,7 @@ "file_type": "code", "source_file": "main/service/user_service.py", "source_location": "L35", - "community": 628, + "community": 222, "norm_label": "inactivesessionsscheduler()", "id": "service_user_service_inactivesessionsscheduler" }, @@ -60275,7 +60338,7 @@ "file_type": "rationale", "source_file": "main/utils/errors.py", "source_location": "L68", - "community": 120, + "community": 63, "norm_label": "register exception handlers on the fastapi app. note: httpexception and r", "id": "utils_errors_rationale_68" }, @@ -60446,7 +60509,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L705", - "community": 28, + "community": 541, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_705" }, @@ -60473,7 +60536,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L775", - "community": 39, + "community": 190, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_775" }, @@ -60482,7 +60545,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L823", - "community": 39, + "community": 17, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_823" }, @@ -60518,7 +60581,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L892", - "community": 17, + "community": 39, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_892" }, @@ -60932,7 +60995,7 @@ "file_type": "rationale", "source_file": "main/utils/errors.py", "source_location": "L67", - "community": 120, + "community": 63, "norm_label": "register exception handlers on the fastapi app. note: httpexception and r", "id": "utils_errors_rationale_67" }, @@ -60941,7 +61004,7 @@ "file_type": "code", "source_file": "main/app/authentication/session.py", "source_location": "L67", - "community": 149, + "community": 44, "norm_label": "getsessionbyidsafe()", "id": "authentication_session_getsessionbyidsafe" }, @@ -61922,7 +61985,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L72", - "community": 586, + "community": 172, "norm_label": "testquerycaching", "id": "tests_test_stocks_optimization_testquerycaching" }, @@ -61931,7 +61994,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L75", - "community": 586, + "community": 172, "norm_label": ".test_cache_manager_has_caches_method()", "id": "tests_test_stocks_optimization_testquerycaching_test_cache_manager_has_caches_method" }, @@ -61940,7 +62003,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L83", - "community": 586, + "community": 172, "norm_label": ".test_querycache_ttl_configuration()", "id": "tests_test_stocks_optimization_testquerycaching_test_queryCache_ttl_configuration" }, @@ -61949,7 +62012,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L91", - "community": 586, + "community": 172, "norm_label": ".test_get_cached_stocks_respects_columns_parameter()", "id": "tests_test_stocks_optimization_testquerycaching_test_get_cached_stocks_respects_columns_parameter" }, @@ -61958,7 +62021,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L101", - "community": 586, + "community": 172, "norm_label": ".test_different_queries_not_cached()", "id": "tests_test_stocks_optimization_testquerycaching_test_different_queries_not_cached" }, @@ -61967,7 +62030,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L105", - "community": 586, + "community": 172, "norm_label": ".test_cache_expiry_after_ttl()", "id": "tests_test_stocks_optimization_testquerycaching_test_cache_expiry_after_ttl" }, @@ -62012,7 +62075,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L137", - "community": 592, + "community": 586, "norm_label": "testqueryoptimization", "id": "tests_test_stocks_optimization_testqueryoptimization" }, @@ -62021,7 +62084,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L140", - "community": 592, + "community": 586, "norm_label": ".test_all_optimizations_present()", "id": "tests_test_stocks_optimization_testqueryoptimization_test_all_optimizations_present" }, @@ -62030,7 +62093,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L155", - "community": 592, + "community": 586, "norm_label": ".test_query_filter_uses_optimization()", "id": "tests_test_stocks_optimization_testqueryoptimization_test_query_filter_uses_optimization" }, @@ -62120,7 +62183,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L310", - "community": 610, + "community": 586, "norm_label": "testqueryperformance", "id": "tests_test_stocks_optimization_testqueryperformance" }, @@ -62129,7 +62192,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L313", - "community": 610, + "community": 586, "norm_label": ".test_query_response_time_under_1_second()", "id": "tests_test_stocks_optimization_testqueryperformance_test_query_response_time_under_1_second" }, @@ -62192,7 +62255,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L73", - "community": 586, + "community": 172, "norm_label": "tests for query result caching", "id": "tests_test_stocks_optimization_rationale_73" }, @@ -62201,7 +62264,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L76", - "community": 586, + "community": 172, "norm_label": "cachemanager should track cached queries", "id": "tests_test_stocks_optimization_rationale_76" }, @@ -62210,7 +62273,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L84", - "community": 586, + "community": 172, "norm_label": "query cache should have configurable ttl", "id": "tests_test_stocks_optimization_rationale_84" }, @@ -62219,7 +62282,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L92", - "community": 586, + "community": 172, "norm_label": "getcachedstocks should support column filtering", "id": "tests_test_stocks_optimization_rationale_92" }, @@ -62228,7 +62291,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L102", - "community": 586, + "community": 172, "norm_label": "different query parameters should not share cache", "id": "tests_test_stocks_optimization_rationale_102" }, @@ -62237,7 +62300,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L106", - "community": 586, + "community": 172, "norm_label": "cache should expire after ttl", "id": "tests_test_stocks_optimization_rationale_106" }, @@ -62282,7 +62345,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L138", - "community": 592, + "community": 586, "norm_label": "integration tests for all query optimizations", "id": "tests_test_stocks_optimization_rationale_138" }, @@ -62291,7 +62354,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L141", - "community": 592, + "community": 586, "norm_label": "all optimizations should be implemented", "id": "tests_test_stocks_optimization_rationale_141" }, @@ -62300,7 +62363,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L156", - "community": 592, + "community": 586, "norm_label": "query filter should use ticker index", "id": "tests_test_stocks_optimization_rationale_156" }, @@ -62390,7 +62453,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L311", - "community": 610, + "community": 586, "norm_label": "performance tests for query operations", "id": "tests_test_stocks_optimization_rationale_311" }, @@ -62399,7 +62462,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L314", - "community": 610, + "community": 586, "norm_label": "query should respond within 1 second", "id": "tests_test_stocks_optimization_rationale_314" }, @@ -62435,7 +62498,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L182", - "community": 610, + "community": 586, "norm_label": "performance tests for query operations", "id": "tests_test_stocks_optimization_rationale_182" }, @@ -62444,7 +62507,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L185", - "community": 610, + "community": 586, "norm_label": "query should respond within 1 second", "id": "tests_test_stocks_optimization_rationale_185" }, @@ -62767,7 +62830,7 @@ "label": "Authentication System", "file_type": "document", "source_file": "docs/authentication.md", - "community": 107, + "community": 528, "norm_label": "authentication system", "id": "authentication" }, @@ -62775,7 +62838,7 @@ "label": "JWT Authentication", "file_type": "rationale", "source_file": "docs/authentication.md", - "community": 107, + "community": 528, "norm_label": "jwt authentication", "id": "jwt" }, @@ -62783,7 +62846,7 @@ "label": "Google OAuth", "file_type": "rationale", "source_file": "docs/authentication.md", - "community": 107, + "community": 528, "norm_label": "google oauth", "id": "google_oauth" }, @@ -62871,7 +62934,7 @@ "label": "Pytest Testing", "file_type": "rationale", "source_file": "pyproject.toml", - "community": 577, + "community": 49, "norm_label": "pytest testing", "id": "pytest" }, @@ -71546,6 +71609,17 @@ "source": "orunmila_vector_embed", "target": "models_loader_getembeddingmodel" }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L47", + "weight": 1.0, + "source": "tools_memory_save_memory", + "target": "orunmila_vector_embed" + }, { "relation": "calls", "context": "call", @@ -71563,9 +71637,9 @@ "source_file": "main/app/orunmila/tools/context.py", "source_location": "L7", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_context_py", - "target": "tools_context_popauthsession", - "confidence_score": 1.0 + "target": "tools_context_popauthsession" }, { "relation": "contains", @@ -71573,9 +71647,9 @@ "source_file": "main/app/orunmila/tools/context.py", "source_location": "L24", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_context_py", - "target": "tools_context_closeownsession", - "confidence_score": 1.0 + "target": "tools_context_closeownsession" }, { "relation": "rationale_for", @@ -71583,9 +71657,9 @@ "source_file": "main/app/orunmila/tools/context.py", "source_location": "L8", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_context_rationale_8", - "target": "tools_context_popauthsession", - "confidence_score": 1.0 + "target": "tools_context_popauthsession" }, { "relation": "calls", @@ -71617,7 +71691,7 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L35", "weight": 1.0, - "source": "tools_wallet_get_wallet_positions", + "source": "tools_wallet_wallet_positions", "target": "tools_context_popauthsession" }, { @@ -71628,7 +71702,7 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L60", "weight": 1.0, - "source": "tools_wallet_get_wallet_summary", + "source": "tools_wallet_wallet_summary", "target": "tools_context_popauthsession" }, { @@ -71639,7 +71713,7 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L86", "weight": 1.0, - "source": "tools_wallet_get_wallet_allocation", + "source": "tools_wallet_wallet_allocation", "target": "tools_context_popauthsession" }, { @@ -71653,6 +71727,61 @@ "source": "tools_wallet_list_wallet_earnings", "target": "tools_context_popauthsession" }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L161", + "weight": 1.0, + "source": "tools_wallet_wallet_performance", + "target": "tools_context_popauthsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L195", + "weight": 1.0, + "source": "tools_wallet_wallet_rebalance", + "target": "tools_context_popauthsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L35", + "weight": 1.0, + "source": "tools_wallet_get_wallet_positions", + "target": "tools_context_popauthsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L60", + "weight": 1.0, + "source": "tools_wallet_get_wallet_summary", + "target": "tools_context_popauthsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L86", + "weight": 1.0, + "source": "tools_wallet_get_wallet_allocation", + "target": "tools_context_popauthsession" + }, { "relation": "calls", "context": "call", @@ -71705,7 +71834,7 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L49", "weight": 1.0, - "source": "tools_wallet_get_wallet_positions", + "source": "tools_wallet_wallet_positions", "target": "tools_context_closeownsession" }, { @@ -71716,7 +71845,7 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L74", "weight": 1.0, - "source": "tools_wallet_get_wallet_summary", + "source": "tools_wallet_wallet_summary", "target": "tools_context_closeownsession" }, { @@ -71727,7 +71856,7 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L101", "weight": 1.0, - "source": "tools_wallet_get_wallet_allocation", + "source": "tools_wallet_wallet_allocation", "target": "tools_context_closeownsession" }, { @@ -71741,6 +71870,61 @@ "source": "tools_wallet_list_wallet_earnings", "target": "tools_context_closeownsession" }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L184", + "weight": 1.0, + "source": "tools_wallet_wallet_performance", + "target": "tools_context_closeownsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L209", + "weight": 1.0, + "source": "tools_wallet_wallet_rebalance", + "target": "tools_context_closeownsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L49", + "weight": 1.0, + "source": "tools_wallet_get_wallet_positions", + "target": "tools_context_closeownsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L74", + "weight": 1.0, + "source": "tools_wallet_get_wallet_summary", + "target": "tools_context_closeownsession" + }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L101", + "weight": 1.0, + "source": "tools_wallet_get_wallet_allocation", + "target": "tools_context_closeownsession" + }, { "relation": "calls", "context": "call", @@ -71769,9 +71953,9 @@ "source_file": "main/app/orunmila/tools/memory.py", "source_location": "L7", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_memory_py", - "target": "tools_memory_search_memory", - "confidence_score": 1.0 + "target": "tools_memory_search_memory" }, { "relation": "contains", @@ -71779,8 +71963,18 @@ "source_file": "main/app/orunmila/tools/memory.py", "source_location": "L32", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_memory_py", - "target": "tools_memory_save_memory", + "target": "tools_memory_save_memory" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L9", + "weight": 1.0, + "source": "tools_memory_rationale_9", + "target": "tools_memory_search_memory", "confidence_score": 1.0 }, { @@ -71789,8 +71983,18 @@ "source_file": "main/app/orunmila/tools/memory.py", "source_location": "L8", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_memory_rationale_8", - "target": "tools_memory_search_memory", + "target": "tools_memory_search_memory" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/memory.py", + "source_location": "L34", + "weight": 1.0, + "source": "tools_memory_rationale_34", + "target": "tools_memory_save_memory", "confidence_score": 1.0 }, { @@ -71799,9 +72003,9 @@ "source_file": "main/app/orunmila/tools/memory.py", "source_location": "L33", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_memory_rationale_33", - "target": "tools_memory_save_memory", - "confidence_score": 1.0 + "target": "tools_memory_save_memory" }, { "relation": "contains", @@ -71809,9 +72013,9 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L11", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_sandbox_py", - "target": "tools_sandbox_execute_code", - "confidence_score": 1.0 + "target": "tools_sandbox_execute_code" }, { "relation": "contains", @@ -71819,9 +72023,9 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L32", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_sandbox_py", - "target": "tools_sandbox_read_file", - "confidence_score": 1.0 + "target": "tools_sandbox_read_file" }, { "relation": "contains", @@ -71829,9 +72033,9 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L46", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_sandbox_py", - "target": "tools_sandbox_write_file", - "confidence_score": 1.0 + "target": "tools_sandbox_write_file" }, { "relation": "contains", @@ -71839,9 +72043,9 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L62", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_sandbox_py", - "target": "tools_sandbox_list_files", - "confidence_score": 1.0 + "target": "tools_sandbox_list_files" }, { "relation": "contains", @@ -71849,9 +72053,9 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L75", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_sandbox_py", - "target": "tools_sandbox_serve_file", - "confidence_score": 1.0 + "target": "tools_sandbox_serve_file" }, { "relation": "rationale_for", @@ -71859,9 +72063,9 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L12", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_sandbox_rationale_12", - "target": "tools_sandbox_execute_code", - "confidence_score": 1.0 + "target": "tools_sandbox_execute_code" }, { "relation": "rationale_for", @@ -71869,9 +72073,9 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L33", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_sandbox_rationale_33", - "target": "tools_sandbox_read_file", - "confidence_score": 1.0 + "target": "tools_sandbox_read_file" }, { "relation": "rationale_for", @@ -71879,9 +72083,9 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L47", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_sandbox_rationale_47", - "target": "tools_sandbox_write_file", - "confidence_score": 1.0 + "target": "tools_sandbox_write_file" }, { "relation": "rationale_for", @@ -71889,9 +72093,9 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L63", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_sandbox_rationale_63", - "target": "tools_sandbox_list_files", - "confidence_score": 1.0 + "target": "tools_sandbox_list_files" }, { "relation": "rationale_for", @@ -71899,9 +72103,9 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L76", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_sandbox_rationale_76", - "target": "tools_sandbox_serve_file", - "confidence_score": 1.0 + "target": "tools_sandbox_serve_file" }, { "relation": "imports_from", @@ -71910,9 +72114,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L4", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_wallet_py", - "target": "fastapi", - "confidence_score": 1.0 + "target": "fastapi" }, { "relation": "contains", @@ -71920,9 +72124,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L15", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_wallet_py", - "target": "tools_wallet_ensureownership", - "confidence_score": 1.0 + "target": "tools_wallet_ensureownership" }, { "relation": "contains", @@ -71931,7 +72135,7 @@ "source_location": "L27", "weight": 1.0, "source": "main_app_orunmila_tools_wallet_py", - "target": "tools_wallet_get_wallet_positions", + "target": "tools_wallet_wallet_positions", "confidence_score": 1.0 }, { @@ -71941,7 +72145,7 @@ "source_location": "L52", "weight": 1.0, "source": "main_app_orunmila_tools_wallet_py", - "target": "tools_wallet_get_wallet_summary", + "target": "tools_wallet_wallet_summary", "confidence_score": 1.0 }, { @@ -71951,7 +72155,7 @@ "source_location": "L77", "weight": 1.0, "source": "main_app_orunmila_tools_wallet_py", - "target": "tools_wallet_get_wallet_allocation", + "target": "tools_wallet_wallet_allocation", "confidence_score": 1.0 }, { @@ -71960,9 +72164,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L104", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_wallet_py", - "target": "tools_wallet_list_wallet_earnings", - "confidence_score": 1.0 + "target": "tools_wallet_list_wallet_earnings" }, { "relation": "contains", @@ -71971,7 +72175,7 @@ "source_location": "L148", "weight": 1.0, "source": "main_app_orunmila_tools_wallet_py", - "target": "tools_wallet_get_wallet_performance", + "target": "tools_wallet_wallet_performance", "confidence_score": 1.0 }, { @@ -71981,9 +72185,59 @@ "source_location": "L187", "weight": 1.0, "source": "main_app_orunmila_tools_wallet_py", - "target": "tools_wallet_get_wallet_rebalance", + "target": "tools_wallet_wallet_rebalance", "confidence_score": 1.0 }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L27", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_orunmila_tools_wallet_py", + "target": "tools_wallet_get_wallet_positions" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L52", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_orunmila_tools_wallet_py", + "target": "tools_wallet_get_wallet_summary" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L77", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_orunmila_tools_wallet_py", + "target": "tools_wallet_get_wallet_allocation" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L148", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_orunmila_tools_wallet_py", + "target": "tools_wallet_get_wallet_performance" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L187", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_orunmila_tools_wallet_py", + "target": "tools_wallet_get_wallet_rebalance" + }, { "relation": "calls", "context": "call", @@ -71991,7 +72245,7 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L40", "weight": 1.0, - "source": "tools_wallet_get_wallet_positions", + "source": "tools_wallet_wallet_positions", "target": "tools_wallet_ensureownership", "confidence_score": 1.0 }, @@ -72002,7 +72256,7 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L65", "weight": 1.0, - "source": "tools_wallet_get_wallet_summary", + "source": "tools_wallet_wallet_summary", "target": "tools_wallet_ensureownership", "confidence_score": 1.0 }, @@ -72013,7 +72267,7 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L91", "weight": 1.0, - "source": "tools_wallet_get_wallet_allocation", + "source": "tools_wallet_wallet_allocation", "target": "tools_wallet_ensureownership", "confidence_score": 1.0 }, @@ -72024,9 +72278,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L118", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_wallet_list_wallet_earnings", - "target": "tools_wallet_ensureownership", - "confidence_score": 1.0 + "target": "tools_wallet_ensureownership" }, { "relation": "calls", @@ -72035,7 +72289,7 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L172", "weight": 1.0, - "source": "tools_wallet_get_wallet_performance", + "source": "tools_wallet_wallet_performance", "target": "tools_wallet_ensureownership", "confidence_score": 1.0 }, @@ -72046,10 +72300,65 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L200", "weight": 1.0, - "source": "tools_wallet_get_wallet_rebalance", + "source": "tools_wallet_wallet_rebalance", "target": "tools_wallet_ensureownership", "confidence_score": 1.0 }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L40", + "weight": 1.0, + "confidence_score": 1.0, + "source": "tools_wallet_get_wallet_positions", + "target": "tools_wallet_ensureownership" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L65", + "weight": 1.0, + "confidence_score": 1.0, + "source": "tools_wallet_get_wallet_summary", + "target": "tools_wallet_ensureownership" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L91", + "weight": 1.0, + "confidence_score": 1.0, + "source": "tools_wallet_get_wallet_allocation", + "target": "tools_wallet_ensureownership" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L172", + "weight": 1.0, + "confidence_score": 1.0, + "source": "tools_wallet_get_wallet_performance", + "target": "tools_wallet_ensureownership" + }, + { + "relation": "calls", + "context": "call", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L200", + "weight": 1.0, + "confidence_score": 1.0, + "source": "tools_wallet_get_wallet_rebalance", + "target": "tools_wallet_ensureownership" + }, { "relation": "rationale_for", "confidence": "EXTRACTED", @@ -72057,7 +72366,7 @@ "source_location": "L28", "weight": 1.0, "source": "tools_wallet_rationale_28", - "target": "tools_wallet_get_wallet_positions", + "target": "tools_wallet_wallet_positions", "confidence_score": 1.0 }, { @@ -72067,7 +72376,7 @@ "source_location": "L53", "weight": 1.0, "source": "tools_wallet_rationale_53", - "target": "tools_wallet_get_wallet_summary", + "target": "tools_wallet_wallet_summary", "confidence_score": 1.0 }, { @@ -72077,7 +72386,7 @@ "source_location": "L78", "weight": 1.0, "source": "tools_wallet_rationale_78", - "target": "tools_wallet_get_wallet_allocation", + "target": "tools_wallet_wallet_allocation", "confidence_score": 1.0 }, { @@ -72086,9 +72395,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L105", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_wallet_rationale_105", - "target": "tools_wallet_list_wallet_earnings", - "confidence_score": 1.0 + "target": "tools_wallet_list_wallet_earnings" }, { "relation": "rationale_for", @@ -72097,7 +72406,7 @@ "source_location": "L151", "weight": 1.0, "source": "tools_wallet_rationale_151", - "target": "tools_wallet_get_wallet_performance", + "target": "tools_wallet_wallet_performance", "confidence_score": 1.0 }, { @@ -72107,18 +72416,68 @@ "source_location": "L188", "weight": 1.0, "source": "tools_wallet_rationale_188", - "target": "tools_wallet_get_wallet_rebalance", + "target": "tools_wallet_wallet_rebalance", "confidence_score": 1.0 }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L28", + "weight": 1.0, + "confidence_score": 1.0, + "source": "tools_wallet_rationale_28", + "target": "tools_wallet_get_wallet_positions" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L53", + "weight": 1.0, + "confidence_score": 1.0, + "source": "tools_wallet_rationale_53", + "target": "tools_wallet_get_wallet_summary" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L78", + "weight": 1.0, + "confidence_score": 1.0, + "source": "tools_wallet_rationale_78", + "target": "tools_wallet_get_wallet_allocation" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L151", + "weight": 1.0, + "confidence_score": 1.0, + "source": "tools_wallet_rationale_151", + "target": "tools_wallet_get_wallet_performance" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L188", + "weight": 1.0, + "confidence_score": 1.0, + "source": "tools_wallet_rationale_188", + "target": "tools_wallet_get_wallet_rebalance" + }, { "relation": "contains", "confidence": "EXTRACTED", "source_file": "main/app/orunmila/tools/__init__.py", "source_location": "L39", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_init_py", - "target": "tools_init_dispatchtoolcall", - "confidence_score": 1.0 + "target": "tools_init_dispatchtoolcall" }, { "relation": "contains", @@ -160785,5 +161144,5 @@ "label": "User Authentication & Authorization" } ], - "built_at_commit": "638e52b716b1186d9bce437f5bd20779731f6217" + "built_at_commit": "81d7224b5a4be29c33eb5eb30ce425374bf20643" } \ No newline at end of file diff --git a/graphify-out/manifest.json b/graphify-out/manifest.json index 0235c3ae..e3822785 100644 --- a/graphify-out/manifest.json +++ b/graphify-out/manifest.json @@ -280,23 +280,23 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\memory.py": { - "mtime": 1790832553.07237, - "ast_hash": "0a02b1d417ed1b9929dcbbd471d32461", + "mtime": 1790834474.292885, + "ast_hash": "afb11fc5b48e60e65e640d1b51d1065a", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\sandbox.py": { - "mtime": 1790832926.2121358, - "ast_hash": "669b63ebbe26e8c507d8f539a758ff33", + "mtime": 1790834443.8187387, + "ast_hash": "6616c6fb85723bc43371ba27538d27da", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\wallet.py": { - "mtime": 1790832579.4839613, - "ast_hash": "07262619e8d45c8971a5479e9c86af76", + "mtime": 1790834325.0523524, + "ast_hash": "d7169d2c574c7e44aab4511692dacf9e", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\__init__.py": { - "mtime": 1790832588.690746, - "ast_hash": "6240a2e38d2557732056f384f7601566", + "mtime": 1790834498.726344, + "ast_hash": "01702bd99310f3a0f6c8e240d91a0022", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\scraper_b3\\scraper.py": { diff --git a/main/app/wallet/positions.py b/main/app/wallet/positions.py index 78b1f635..ffa8469a 100644 --- a/main/app/wallet/positions.py +++ b/main/app/wallet/positions.py @@ -20,13 +20,6 @@ class PositionsManager: @classmethod @walletCache(ttl="6h", key="wallet:xango:{tickers}") def fetchXangoScores(cls, tickers: tuple[str, ...]) -> dict[str, float | None]: - """XANGO quality score per ticker (0-100 scale). - - One fundamental read per ticker; any per-ticker failure degrades to - None and scoreBuyFlag redistributes the xango weight over the other - inputs (flag degrades, never fails). Shared cashews entry is the - freshness story; no staleness gate beyond it, YAGNI. - """ scores: dict[str, float | None] = {} for ticker in tickers: try: @@ -80,7 +73,6 @@ def pricePass( def rebalanceDeltas( cls, holdings: list[Holding], equities: dict[str, float | None], equityTotal: float ) -> dict[str, float | None]: - """Weight-share deltas on backend floats: target_i = w_i/Σw, targetEquity = target_i × equityTotal, delta = targetEquity − equity. Σw=0 → all deltas null.""" weightTotal = sum(cls.weightOf(holding) for holding in holdings) deltas: dict[str, float | None] = {} for holding in holdings: @@ -146,10 +138,8 @@ def getRebalance(cls, db: Session, walletId: int, userId: int) -> dict: items = [] for holding in holdings: ticker = str(holding.ticker) - weightFloat = cls.weightOf(holding) - # Display rounds to int; all math above stays on backend floats. - weight = int(round(weightFloat)) - targetPct = (weightFloat / weightTotal) if weightTotal else 0.0 + weight = cls.weightOf(holding) + targetPct = (weight / weightTotal) if weightTotal else 0.0 equity = equities[ticker] currentPct = (equity / equityTotal) if equity is not None and equityTotal else 0.0 delta = deltas[ticker] diff --git a/main/app/wallet/summary.py b/main/app/wallet/summary.py index e990ff9d..32f196e5 100644 --- a/main/app/wallet/summary.py +++ b/main/app/wallet/summary.py @@ -162,8 +162,4 @@ def set_rating(cls, db: Session, userId: int, data: RatingUpsert) -> Holding: return holding - -# Digest-pinned alias: wallet_controller.py set_rating_route handler bytes are -# hashed by test_ratings_route_untouched, so the controller keeps calling -# summary.set_rating — this alias keeps that path resolving to the class. set_rating = SummaryManager.set_rating From a9afeec3d8913477f8aa579b8e6a792243ccf92e Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 03:13:16 -0300 Subject: [PATCH 30/34] remove wallet service shim --- main/app/wallet/wallet_service.py | 25 ------------------------- 1 file changed, 25 deletions(-) delete mode 100644 main/app/wallet/wallet_service.py diff --git a/main/app/wallet/wallet_service.py b/main/app/wallet/wallet_service.py deleted file mode 100644 index 399f30f2..00000000 --- a/main/app/wallet/wallet_service.py +++ /dev/null @@ -1,25 +0,0 @@ -import logging - -from main.app.wallet.earnings import EarningsManager -from main.app.wallet.entries import EntriesManager, EntryCreate, EntryUpdate -from main.app.wallet.market_data import MarketDataManager -from main.app.wallet.performance import PerformanceManager -from main.app.wallet.positions import PositionsManager -from main.app.wallet.summary import RatingUpsert, SummaryManager, TargetUpsert -from main.app.wallet.wallets import WalletsManager - -logger = logging.getLogger(__name__) - -__all__ = [ - "EarningsManager", - "EntriesManager", - "EntryCreate", - "EntryUpdate", - "MarketDataManager", - "PerformanceManager", - "PositionsManager", - "RatingUpsert", - "SummaryManager", - "TargetUpsert", - "WalletsManager", -] From 3959c3854c2d026e3d518875d48fed5a419fe53b Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 03:43:51 -0300 Subject: [PATCH 31/34] add wallet to status services list --- run.py | 1 + 1 file changed, 1 insertion(+) diff --git a/run.py b/run.py index 42a5eea0..7953c60d 100644 --- a/run.py +++ b/run.py @@ -95,6 +95,7 @@ async def status(): services = {} for name, config in [ ("user", Config.USER), + ("wallet", Config.USER), ("stocks_api", Config.STOCKS_API), ("orunmila", Config.ORUNMILA), ]: From 45768447bc5c0e3ab9d73f95ac48e070c1282704 Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 03:49:57 -0300 Subject: [PATCH 32/34] drop dead holding columns tickername and percentideal --- main/models/wallet.py | 2 - .../d4e5f6a7b8c9_drop_dead_holding_columns.py | 37 +++++++++++++++++++ 2 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 migrations/versions/d4e5f6a7b8c9_drop_dead_holding_columns.py diff --git a/main/models/wallet.py b/main/models/wallet.py index 2836f941..5b3fb57f 100644 --- a/main/models/wallet.py +++ b/main/models/wallet.py @@ -32,10 +32,8 @@ class Holding(Base): walletId = Column(Integer, ForeignKey("wallets.walletId", ondelete="RESTRICT"), nullable=False, index=True) assetType = Column(String(20), nullable=False) ticker = Column(String(20), nullable=False, index=True) - tickerName = Column(String(120), nullable=True) quantity = Column(Numeric(18, 8), nullable=False) avgPrice = Column(Numeric(18, 6), nullable=False) - percentIdeal = Column(Numeric(5, 2), nullable=True) rating = Column(SmallInteger, nullable=True) updatedAt = Column(TIMESTAMP, server_default=func.current_timestamp(), nullable=False) diff --git a/migrations/versions/d4e5f6a7b8c9_drop_dead_holding_columns.py b/migrations/versions/d4e5f6a7b8c9_drop_dead_holding_columns.py new file mode 100644 index 00000000..396289ce --- /dev/null +++ b/migrations/versions/d4e5f6a7b8c9_drop_dead_holding_columns.py @@ -0,0 +1,37 @@ +"""drop dead holding columns + +Revision ID: d4e5f6a7b8c9 +Revises: c4d1e8f2a917 +Create Date: 2026-10-01 00:00:00.000000 + +Holding.percentIdeal (targets live in Target) + Holding.tickerName +(never populated) removed from main/models/wallet.py. +""" + +from typing import Sequence, Union + +from alembic import op +import sqlalchemy as sa + + +# revision identifiers, used by Alembic. +revision: str = "d4e5f6a7b8c9" +down_revision: Union[str, Sequence[str], None] = "c4d1e8f2a917" +branch_labels: Union[str, Sequence[str], None] = None +depends_on: Union[str, Sequence[str], None] = None + + +def upgrade() -> None: + """Upgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.drop_column("holdings", "percentIdeal") + op.drop_column("holdings", "tickerName") + # ### end Alembic commands ### + + +def downgrade() -> None: + """Downgrade schema.""" + # ### commands auto generated by Alembic - please adjust! ### + op.add_column("holdings", sa.Column("tickerName", sa.String(length=120), nullable=True)) + op.add_column("holdings", sa.Column("percentIdeal", sa.Numeric(precision=5, scale=2), nullable=True)) + # ### end Alembic commands ### From a6d02b91e62e24ade81b26cd240a582894125e9b Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 03:53:44 -0300 Subject: [PATCH 33/34] align orunmila tool tests with renamed wallet keys and direct imports --- main/app/orunmila/tools/__init__.py | 13 ++++++--- main/app/orunmila/tools/context.py | 8 +++--- main/app/orunmila/tools/sandbox.py | 4 +-- tests/test_memory_async_loop.py | 4 +-- tests/test_orunmila_tools.py | 14 +++++----- tests/test_orunmila_wallet_tools.py | 42 ++++++++++++++--------------- tests/test_sandbox_tools.py | 8 +++--- 7 files changed, 49 insertions(+), 44 deletions(-) diff --git a/main/app/orunmila/tools/__init__.py b/main/app/orunmila/tools/__init__.py index 6738e09d..cdc44c1c 100644 --- a/main/app/orunmila/tools/__init__.py +++ b/main/app/orunmila/tools/__init__.py @@ -1,9 +1,16 @@ import logging -from typing import Any +from typing import Any, Optional from main.app.orunmila.tools.memory import save_memory, search_memory from main.app.orunmila.tools.sandbox import execute_code, list_files, read_file, serve_file, write_file -from main.app.orunmila.tools.wallet import wallet_allocation, wallet_performance, wallet_positions, wallet_rebalance, wallet_summary, list_wallet_earnings +from main.app.orunmila.tools.wallet import ( + wallet_allocation, + wallet_performance, + wallet_positions, + wallet_rebalance, + wallet_summary, + list_wallet_earnings, +) logger = logging.getLogger(__name__) @@ -30,7 +37,7 @@ async def dispatchToolCall( mcpClients, user=None, db=None, - sandbox_id: str | None = None, + sandbox_id: Optional[str] = None, ) -> dict: name = functionCall.name args = dict(functionCall.args or {}) diff --git a/main/app/orunmila/tools/context.py b/main/app/orunmila/tools/context.py index 420169f3..f6588855 100644 --- a/main/app/orunmila/tools/context.py +++ b/main/app/orunmila/tools/context.py @@ -1,10 +1,10 @@ -from typing import Any +from typing import Any, Optional from config import SessionLocal from sqlalchemy.orm import Session -def popAuthSession(args: dict) -> tuple[Any, Session | None, bool, dict | None]: +def popAuthSession(args: dict) -> tuple[Any, Optional[Session], bool, Optional[dict]]: """Shared auth-guard + own-SessionLocal convention every tool repeats. Returns (user, db, ownSession, error). When error is not None the caller @@ -14,13 +14,13 @@ def popAuthSession(args: dict) -> tuple[Any, Session | None, bool, dict | None]: user = args.get("user") if not user: return None, None, False, {"error": "Authentication required"} - db: Session | None = args.get("db") + db: Optional[Session] = args.get("db") ownSession = not db if ownSession: db = SessionLocal() return user, db, ownSession, None -def closeOwnSession(db: Session | None, ownSession: bool) -> None: +def closeOwnSession(db: Optional[Session], ownSession: bool) -> None: if ownSession: db.close() # type: ignore[union-attr] diff --git a/main/app/orunmila/tools/sandbox.py b/main/app/orunmila/tools/sandbox.py index 22ba231e..55712af0 100644 --- a/main/app/orunmila/tools/sandbox.py +++ b/main/app/orunmila/tools/sandbox.py @@ -3,7 +3,7 @@ from forgevm.exceptions import SandboxNotFound -from main.app.orunmila.sandbox import SandboxManager +from main.app.orunmila.sandbox import SandboxManager, hostPath logger = logging.getLogger(__name__) @@ -84,7 +84,7 @@ async def serve_file(path: str, **_) -> dict: """ userId = _.get("userId", 0) try: - host = SandboxManager.hostPath(userId, path) + host = hostPath(userId, path) except ValueError: return {"error": "Invalid workspace path"} if not host.exists() or not host.is_file(): diff --git a/tests/test_memory_async_loop.py b/tests/test_memory_async_loop.py index 4311d970..08d47a3d 100644 --- a/tests/test_memory_async_loop.py +++ b/tests/test_memory_async_loop.py @@ -4,7 +4,7 @@ import pytest import main.app.orunmila.memory as memoryMod -import main.app.orunmila.tools as toolsMod +import main.app.orunmila.tools.memory as toolsMemoryMod from main.app.orunmila.memory import OrunmilaMemory, clearAll, getMatrix from main.app.orunmila.tools import save_memory, search_memory @@ -71,7 +71,7 @@ async def test_saveMemoryToolInsideLoop(self, dbSession, monkeypatch): # clearAll() is sync and drives the cache via asyncio.run — run it in a # worker thread since this test itself runs inside an event loop. await asyncio.to_thread(clearAll) - monkeypatch.setattr(toolsMod, "embed", lambda texts: [makeQueryVector() for _ in texts]) + monkeypatch.setattr(toolsMemoryMod, "embed", lambda texts: [makeQueryVector() for _ in texts]) monkeypatch.setattr(memoryMod, "embed", lambda texts: [makeQueryVector() for _ in texts]) saved = await save_memory( "ticker favorito", diff --git a/tests/test_orunmila_tools.py b/tests/test_orunmila_tools.py index 53751ffa..5df7e518 100644 --- a/tests/test_orunmila_tools.py +++ b/tests/test_orunmila_tools.py @@ -115,7 +115,7 @@ class TestServeFile: async def test_serve_file_returns_markdown_link(self): from main.app.orunmila.tools import serve_file - with patch("main.app.orunmila.tools.hostPath") as m_host: + with patch("main.app.orunmila.tools.sandbox.hostPath") as m_host: fake_path = MagicMock() fake_path.exists.return_value = True fake_path.is_file.return_value = True @@ -130,7 +130,7 @@ async def test_serve_file_returns_markdown_link(self): async def test_serve_file_missing_file_returns_error(self): from main.app.orunmila.tools import serve_file - with patch("main.app.orunmila.tools.hostPath") as m_host: + with patch("main.app.orunmila.tools.sandbox.hostPath") as m_host: fake_path = MagicMock() fake_path.exists.return_value = False m_host.return_value = fake_path @@ -142,7 +142,7 @@ async def test_serve_file_missing_file_returns_error(self): async def test_serve_file_rejects_traversal(self): from main.app.orunmila.tools import serve_file - with patch("main.app.orunmila.tools.hostPath", side_effect=ValueError("Invalid workspace path")): + with patch("main.app.orunmila.tools.sandbox.hostPath", side_effect=ValueError("Invalid workspace path")): result = await serve_file("/workspace/../../etc/passwd", userId=1) assert "error" in result @@ -150,7 +150,7 @@ async def test_serve_file_rejects_traversal(self): async def test_serve_file_quotes_special_chars(self): from main.app.orunmila.tools import serve_file - with patch("main.app.orunmila.tools.hostPath") as m_host: + with patch("main.app.orunmila.tools.sandbox.hostPath") as m_host: fake_path = MagicMock() fake_path.exists.return_value = True fake_path.is_file.return_value = True @@ -179,7 +179,7 @@ async def test_read_file_rejects_traversal(self): from main.app.orunmila.tools import read_file with patch( - "main.app.orunmila.tools.SandboxManager.read_file", + "main.app.orunmila.tools.sandbox.SandboxManager.read_file", side_effect=ValueError("bad path"), ): result = await read_file("/workspace/../../etc/passwd", userId=1) @@ -190,7 +190,7 @@ async def test_write_file_rejects_traversal(self): from main.app.orunmila.tools import write_file with patch( - "main.app.orunmila.tools.SandboxManager.write_file", + "main.app.orunmila.tools.sandbox.SandboxManager.write_file", side_effect=ValueError("bad path"), ): result = await write_file("/workspace/../../etc/evil", "x", userId=1) @@ -201,7 +201,7 @@ async def test_list_files_rejects_traversal(self): from main.app.orunmila.tools import list_files with patch( - "main.app.orunmila.tools.SandboxManager.list_files", + "main.app.orunmila.tools.sandbox.SandboxManager.list_files", side_effect=ValueError("bad path"), ): result = await list_files("/workspace/../../etc", userId=1) diff --git a/tests/test_orunmila_wallet_tools.py b/tests/test_orunmila_wallet_tools.py index c1cc66b6..f23e3877 100644 --- a/tests/test_orunmila_wallet_tools.py +++ b/tests/test_orunmila_wallet_tools.py @@ -12,12 +12,12 @@ from tests.conftest import make_wallet_client WALLET_TOOLS = [ - "get_wallet_positions", - "get_wallet_summary", - "get_wallet_allocation", + "wallet_positions", + "wallet_summary", + "wallet_allocation", "list_wallet_earnings", - "get_wallet_performance", - "get_wallet_rebalance", + "wallet_performance", + "wallet_rebalance", ] @@ -112,35 +112,33 @@ def _seed_earnings(dbSession, walletId): dbSession.commit() -def test_get_wallet_positions_returns_read_view(dbSession, monkeypatch): +def test_wallet_positions_returns_read_view(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _live_ok) walletId = _seed_wallet(dbSession) result = asyncio.run( - TOOL_REGISTRY["get_wallet_positions"](wallet_id=walletId, user={"userId": 1, "language": "pt-BR"}, db=dbSession) + TOOL_REGISTRY["wallet_positions"](wallet_id=walletId, user={"userId": 1, "language": "pt-BR"}, db=dbSession) ) assert result["items"][0]["ticker"] == "PETR4" assert result["equity_total"] == 300.0 -def test_get_wallet_summary_returns_totals(dbSession, monkeypatch): +def test_wallet_summary_returns_totals(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _live_ok) walletId = _seed_wallet(dbSession) - result = asyncio.run(TOOL_REGISTRY["get_wallet_summary"](wallet_id=walletId, user={"userId": 1}, db=dbSession)) + result = asyncio.run(TOOL_REGISTRY["wallet_summary"](wallet_id=walletId, user={"userId": 1}, db=dbSession)) assert result["applied"] == 100.0 assert result["equity"] == 300.0 assert result["variation"] == 200.0 -def test_get_wallet_allocation_groups_by_ticker_and_asset(dbSession, monkeypatch): +def test_wallet_allocation_groups_by_ticker_and_asset(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _live_ok) walletId = _seed_wallet(dbSession) - byTicker = asyncio.run(TOOL_REGISTRY["get_wallet_allocation"](wallet_id=walletId, user={"userId": 1}, db=dbSession)) + byTicker = asyncio.run(TOOL_REGISTRY["wallet_allocation"](wallet_id=walletId, user={"userId": 1}, db=dbSession)) assert byTicker["items"][0]["key"] == "PETR4" assert byTicker["equity_total"] == 300.0 byAsset = asyncio.run( - TOOL_REGISTRY["get_wallet_allocation"]( - wallet_id=walletId, group_by="assetType", user={"userId": 1}, db=dbSession - ) + TOOL_REGISTRY["wallet_allocation"](wallet_id=walletId, group_by="assetType", user={"userId": 1}, db=dbSession) ) assert byAsset["items"][0]["key"] == "Stock" @@ -161,7 +159,7 @@ def test_list_wallet_earnings_filters_by_status(dbSession): assert len(allRows["earnings"]) == 2 -def test_get_wallet_performance_returns_metrics(dbSession, monkeypatch): +def test_wallet_performance_returns_metrics(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _flat_series) walletId = _seed_wallet(dbSession) dbSession.add( @@ -178,7 +176,7 @@ def test_get_wallet_performance_returns_metrics(dbSession, monkeypatch): ) dbSession.commit() result = asyncio.run( - TOOL_REGISTRY["get_wallet_performance"]( + TOOL_REGISTRY["wallet_performance"]( wallet_id=walletId, from_date="2026-01-01", to_date="2026-01-11", @@ -191,20 +189,20 @@ def test_get_wallet_performance_returns_metrics(dbSession, monkeypatch): assert result["dividends_received"] == 10.0 -def test_get_wallet_performance_rejects_bad_date(dbSession): +def test_wallet_performance_rejects_bad_date(dbSession): walletId = _seed_wallet(dbSession) result = asyncio.run( - TOOL_REGISTRY["get_wallet_performance"]( + TOOL_REGISTRY["wallet_performance"]( wallet_id=walletId, from_date="01/01/2026", to_date="2026-01-11", user={"userId": 1}, db=dbSession ) ) assert result == {"error": "invalid date, use YYYY-MM-DD"} -def test_get_wallet_rebalance_single_holding_holds(dbSession, monkeypatch): +def test_wallet_rebalance_single_holding_holds(dbSession, monkeypatch): monkeypatch.setattr(requests, "get", _live_ok) walletId = _seed_wallet(dbSession) - result = asyncio.run(TOOL_REGISTRY["get_wallet_rebalance"](wallet_id=walletId, user={"userId": 1}, db=dbSession)) + result = asyncio.run(TOOL_REGISTRY["wallet_rebalance"](wallet_id=walletId, user={"userId": 1}, db=dbSession)) assert result["items"][0]["side"] == "hold" assert result["items"][0]["target_pct"] == 1.0 @@ -214,7 +212,7 @@ def test_wallet_tools_cross_user_denied(dbSession): baseArgs = {"wallet_id": walletId, "user": {"userId": 2, "language": "pt-BR"}, "db": dbSession} for name in WALLET_TOOLS: args = dict(baseArgs) - if name == "get_wallet_performance": + if name == "wallet_performance": args.update({"from_date": "2026-01-01", "to_date": "2026-01-11"}) result = asyncio.run(TOOL_REGISTRY[name](**args)) assert result == {"error": "not-owner"} @@ -224,7 +222,7 @@ def test_wallet_tools_no_auth_no_data(): baseArgs = {"wallet_id": 1} for name in WALLET_TOOLS: args = dict(baseArgs) - if name == "get_wallet_performance": + if name == "wallet_performance": args.update({"from_date": "2026-01-01", "to_date": "2026-01-11"}) result = asyncio.run(TOOL_REGISTRY[name](**args)) assert result == {"error": "Authentication required"} diff --git a/tests/test_sandbox_tools.py b/tests/test_sandbox_tools.py index 5451f904..14fe3882 100644 --- a/tests/test_sandbox_tools.py +++ b/tests/test_sandbox_tools.py @@ -23,7 +23,7 @@ def test_execute_code_has_docstring(self): class TestDispatchToolCallSandbox: - @patch("main.app.orunmila.tools.SandboxManager") + @patch("main.app.orunmila.tools.sandbox.SandboxManager") async def test_dispatch_execute_code(self, mock_sandbox): mock_fc = MagicMock() mock_fc.name = "execute_code" @@ -40,7 +40,7 @@ async def test_dispatch_execute_code_no_sandbox(self): result = await dispatchToolCall(mock_fc, {}, user={"userId": 1}, sandbox_id=None) assert "error" in result - @patch("main.app.orunmila.tools.SandboxManager") + @patch("main.app.orunmila.tools.sandbox.SandboxManager") async def test_dispatch_read_file(self, mock_sandbox): mock_fc = MagicMock() mock_fc.name = "read_file" @@ -49,7 +49,7 @@ async def test_dispatch_read_file(self, mock_sandbox): result = await dispatchToolCall(mock_fc, {}, user={"userId": 1}, sandbox_id="sb-123") assert result["content"] == '{"key": "value"}' - @patch("main.app.orunmila.tools.SandboxManager") + @patch("main.app.orunmila.tools.sandbox.SandboxManager") async def test_dispatch_write_file(self, mock_sandbox): mock_fc = MagicMock() mock_fc.name = "write_file" @@ -58,7 +58,7 @@ async def test_dispatch_write_file(self, mock_sandbox): result = await dispatchToolCall(mock_fc, {}, user={"userId": 1}, sandbox_id="sb-123") assert result["success"] is True - @patch("main.app.orunmila.tools.SandboxManager") + @patch("main.app.orunmila.tools.sandbox.SandboxManager") async def test_dispatch_list_files(self, mock_sandbox): mock_fc = MagicMock() mock_fc.name = "list_files" From 6e30802e9014aba931cb82771884321bc262ec2d Mon Sep 17 00:00:00 2001 From: heitorrosa <76885858+heitorrosa@users.noreply.github.com> Date: Thu, 1 Oct 2026 13:06:36 -0300 Subject: [PATCH 34/34] ruff --- graphify-out/.graphify_labels.json | 3 + graphify-out/GRAPH_REPORT.md | 441 ++--- graphify-out/graph.json | 2563 +++++++++++++++------------- graphify-out/manifest.json | 48 +- main/app/orunmila/tools/wallet.py | 4 +- main/app/wallet/summary.py | 1 + 6 files changed, 1594 insertions(+), 1466 deletions(-) diff --git a/graphify-out/.graphify_labels.json b/graphify-out/.graphify_labels.json index 038ac20f..6b7947ae 100644 --- a/graphify-out/.graphify_labels.json +++ b/graphify-out/.graphify_labels.json @@ -631,7 +631,10 @@ "629": "Community 629", "630": "Community 630", "631": "Community 631", + "632": "Community 632", + "633": "Community 633", "634": "Community 634", + "635": "Community 635", "637": "Community 637", "638": "Community 638", "639": "Community 639", diff --git a/graphify-out/GRAPH_REPORT.md b/graphify-out/GRAPH_REPORT.md index 6eaa8f10..41f2e68f 100644 --- a/graphify-out/GRAPH_REPORT.md +++ b/graphify-out/GRAPH_REPORT.md @@ -1,16 +1,16 @@ # Graph Report - server (2026-10-01) ## Corpus Check -- 158 files · ~123,258 words +- 158 files · ~123,714 words - Verdict: corpus is large enough that graph structure adds value. ## Summary -- 6998 nodes · 9590 edges · 639 communities (397 shown, 242 thin omitted) -- Extraction: 84% EXTRACTED · 16% INFERRED · 0% AMBIGUOUS · INFERRED: 1562 edges (avg confidence: 0.68) +- 7004 nodes · 9596 edges · 642 communities (399 shown, 243 thin omitted) +- Extraction: 84% EXTRACTED · 16% INFERRED · 0% AMBIGUOUS · INFERRED: 1563 edges (avg confidence: 0.68) - Token cost: 0 input · 0 output ## Graph Freshness -- Built from commit: `81d7224b` +- Built from commit: `45768447` - Run `git rev-parse HEAD` and compare to check if the graph is stale. - Run `graphify update .` after code changes (no API cost). @@ -633,7 +633,10 @@ - [[_COMMUNITY_Community 629|Community 629]] - [[_COMMUNITY_Community 630|Community 630]] - [[_COMMUNITY_Community 631|Community 631]] +- [[_COMMUNITY_Community 632|Community 632]] +- [[_COMMUNITY_Community 633|Community 633]] - [[_COMMUNITY_Community 634|Community 634]] +- [[_COMMUNITY_Community 635|Community 635]] - [[_COMMUNITY_Community 637|Community 637]] - [[_COMMUNITY_Community 638|Community 638]] - [[_COMMUNITY_Community 639|Community 639]] @@ -654,8 +657,6 @@ 10. `Prometheus` - 41 edges ## Surprising Connections (you probably didn't know these) -- `lifespan()` --calls--> `runAll()` [INFERRED] - run.py → main/utils/service_manager.py - `StocksCacheManager` --calls--> `test_cache_scheduler_starts_apscheduler()` [INFERRED] main/app/stocks_api/cache.py → tests/test_stocks_api_coverage.py - `StocksCacheManager` --calls--> `test_cache_scheduler_starts_daemon_thread()` [INFERRED] @@ -664,6 +665,8 @@ main/app/prometheus/state.py → tests/test_state_tools.py - `HarnessState` --uses--> `TestSetState` [INFERRED] main/app/prometheus/state.py → tests/test_state_tools.py +- `HarnessState` --uses--> `TestStateDispatch` [INFERRED] + main/app/prometheus/state.py → tests/test_state_tools.py ## Hyperedges (group relationships) - **Authentication Module** — AuthenticationManager, SessionManager, auth_util, auth_constants, getGoogleSSO [INFERRED] @@ -673,7 +676,7 @@ - **Configuration & Database Infrastructure** — config_Config, config_engine, config_stocksEngine [INFERRED] - **User Authentication & Authorization** — user_service, authentication, user_roles, permission_system [INFERRED] -## Communities (639 total, 242 thin omitted) +## Communities (642 total, 243 thin omitted) ### Community 0 - "Stocks API Endpoints" Cohesion: 0.0 @@ -688,8 +691,8 @@ Cohesion: 0.13 Nodes (21): Thin async wrapper around the CubeSandbox/E2B HTTP API. All methods are sta, SandboxManager, _mock_forgevm(), Unit tests for SandboxManager — HTTP calls mocked via a fake client class., Wire up mock forgevm AsyncClient that returns sandbox with all methods., Wire up mock forgevm AsyncClient that returns sandbox with all methods., test_create_sandbox(), test_destroy_sandbox() (+13 more) ### Community 3 - "Prometheus Agent" -Cohesion: 0.1 -Nodes (16): _make_stocks_df(), Return a small DataFrame with the columns the query module expects., Return a small DataFrame with the columns the query module expects., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48. (+8 more) +Cohesion: 0.11 +Nodes (12): _make_stocks_df(), Return a small DataFrame with the columns the query module expects., Return a small DataFrame with the columns the query module expects., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48., Tests covering query.py lines 22-48. (+4 more) ### Community 4 - "Data Models & Types" Cohesion: 0.11 @@ -708,16 +711,16 @@ Cohesion: 0.07 Nodes (29): Algorithmic Compression (`compact.py`) Implementation Plan, code:python (# main/app/prometheus/compact.py), code:python (# Before:), code:python (# Before:), code:python (# Before:), code:bash (pytest tests/ -k "prometheus" -v), code:bash (git add main/app/prometheus/agent.py), code:bash (git mv main/app/prometheus/summarizer.py main/app/prometheus) (+21 more) ### Community 8 - "Device Detection" -Cohesion: 0.05 -Nodes (16): HarnessState, Retrieve a value from state. Returns default if key not found., Return a copy of the current state., Format state as a string for injection into the LLM context., Check if state changed since last reset., Reset the changed flag. Returns the previous state., Clear all state data., In-memory state dict that persists across loop iterations within a single reques (+8 more) +Cohesion: 0.06 +Nodes (15): HarnessState, Retrieve a value from state. Returns default if key not found., Return a copy of the current state., Format state as a string for injection into the LLM context., Check if state changed since last reset., Reset the changed flag. Returns the previous state., Clear all state data., In-memory state dict that persists across loop iterations within a single reques (+7 more) ### Community 9 - "Server Configuration" Cohesion: 0.11 Nodes (17): code:python (def filterCotationColumn(series: pd.Series, startDate, endDa), code:bash (git add -A), code:bash (git add main/app/stocks_api/query.py), code:python (def buildCotationDateIndex(df: pd.DataFrame, col: str = "COT), code:python (def filterCotationColumn(series: pd.Series, startDate, endDa), code:bash (git add main/app/stocks_api/cache.py main/app/stocks_api/que), code:python (PARQUET_PATH = Path(__file__).parent / "stocks_cache.parquet), code:bash (git add main/app/stocks_api/cache.py) (+9 more) ### Community 10 - "Prometheus Memory" -Cohesion: 0.06 -Nodes (27): Tests for queryCotations and /stocks/cotations., 2 tickers x 2 rows. Rows 0,2 are 2024-01-15; rows 1,3 are 2024-06-15. M, Tests for queryCotations and /stocks/cotations., 4 rows for 2 tickers -> 2 results, one per ticker, both with latest TIME., 4 rows for 2 tickers -> 2 results, one per ticker, both with latest TIME., 2 tickers x 2 rows. Rows 0,2 are 2024-01-15; rows 1,3 are 2024-06-15. M, dates="2016-12-02" should keep only the 02-12-2016 entry in each JSON list., dates="2016-12-02" should keep only the 02-12-2016 entry in each JSON list. (+19 more) +Cohesion: 0.05 +Nodes (35): Tests for queryCotations and /stocks/cotations., 2 tickers x 2 rows. Rows 0,2 are 2024-01-15; rows 1,3 are 2024-06-15. M, Tests for queryCotations and /stocks/cotations., 4 rows for 2 tickers -> 2 results, one per ticker, both with latest TIME., 4 rows for 2 tickers -> 2 results, one per ticker, both with latest TIME., 2 tickers x 2 rows. Rows 0,2 are 2024-01-15; rows 1,3 are 2024-06-15. M, dates="2016-12-02" should keep only the 02-12-2016 entry in each JSON list., dates="2016-12-02" should keep only the 02-12-2016 entry in each JSON list. (+27 more) ### Community 11 - "Auth Utilities & SSO" Cohesion: 0.05 @@ -732,16 +735,16 @@ Cohesion: 0.06 Nodes (31): code:python ("""Measure whether the stocks query hot path is GIL-bound.), code:bash (git add main/utils/migrator.py tests/test_migrator_guard.py), code:python (import importlib), code:python (DB_POOL_SIZE = int(os.getenv("DB_POOL_SIZE", "20"))), code:bash (git add config.py tests/test_config_pools.py), code:python (import importlib), code:python (if __name__ == "__main__":), code:python (if len(instances) > 1 and fcntl is None: # pragma: no cover) (+23 more) ### Community 14 - "User Roles & Permissions" -Cohesion: 0.08 -Nodes (24): _make_stocksapi_client(), Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont, Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont, Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont, Covers lines 52-53: user without GENERATE_API_KEYS permission gets 403., Covers lines 52-53: user without GENERATE_API_KEYS permission gets 403., Covers lines 52-53, 57-63: GET /stocks/key/generate. NOTE: stocksapi_cont, Covers lines 52-53: user without GENERATE_API_KEYS permission gets 403. (+16 more) +Cohesion: 0.05 +Nodes (36): _make_stocksapi_client(), Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental. (+28 more) ### Community 15 - "Community 15" Cohesion: 0.05 Nodes (38): code:block1 (User 123: "Analyze PETR4 vs VALE3 correlation"), code:python (from main.app.prometheus.sandbox import SandboxManager), code:python (TOOL_REGISTRY: dict[str, Any] = {), code:bash (git add main/app/prometheus/tools.py tests/test_sandbox_tool), code:python (import pytest), code:python (from main.app.prometheus.sandbox import SandboxManager), code:python (async def streamMessage(self, query=None, sessionId=None, db), code:python (## Code Sandbox (On-Demand)) (+30 more) ### Community 17 - "Community 17" -Cohesion: 0.08 -Nodes (23): search.strip() == '' should still dedup (line 181)., search.strip() == '' should still dedup (line 181)., search.strip() == '' should still dedup (line 181)., DataFrame without TIME column., Invalid date -> inner 400 caught by outer except -> 500., DataFrame without TIME column., DataFrame without TIME column., search.strip() == '' should still dedup (line 181). (+15 more) +Cohesion: 0.07 +Nodes (26): Two dates in the range, both valid., Two dates in the range, both valid., Two dates in the range, both valid., Two dates in the range, both valid., Search with no index match falls back to string startswith., Search with no index match falls back to string startswith., search.strip() == '' should still dedup (line 181)., Search with no index match falls back to string startswith. (+18 more) ### Community 18 - "Community 18" Cohesion: 0.07 @@ -756,12 +759,12 @@ Cohesion: 0.06 Nodes (35): 1. Memory System (B+), 2. Summarizer/Episodes (B), 3. Loop Events (A-), 4. Core Architecture (B+), 5. Security (B+), 6. Performance (B), 7. Code Quality (B), After (B+) (+27 more) ### Community 21 - "Community 21" -Cohesion: 0.14 +Cohesion: 0.15 Nodes (13): benchOnce(), main(), batchCosineSimilarity(), decodeEmbeddings(), normalizeRows(), Empty matrix → empty array., Single row matches cosine_similarity., Multiple rows ranked correctly. (+5 more) ### Community 22 - "Community 22" -Cohesion: 0.14 -Nodes (7): filterCotationColumn(), Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., TestQueryLiveCotation +Cohesion: 0.1 +Nodes (13): filterCotationColumn(), Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., Tests for queryLiveCotation and /stocks/cotations/live., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422. (+5 more) ### Community 23 - "Community 23" Cohesion: 0.07 @@ -784,12 +787,12 @@ Cohesion: 0.15 Nodes (15): getUserMemories(), getRelevanceScore(), _FakeMemory, A memory with no lastAccessedAt should use baseScore as-is., Scores are deterministic — no cron mutation needed., Same memory at different points in time yields different scores., A memory accessed 10x (baseScore 1.0) should still outrank a memory acce, A rarely-used old memory should lose to a popular fresh one. (+7 more) ### Community 28 - "Community 28" -Cohesion: 0.06 -Nodes (34): Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Pass field name WITHOUT year (how categorizeColumns returns them)., Pass field name WITHOUT year (how categorizeColumns returns them)., No historical data columns -> inner 400 caught by outer except -> 500., Pass field name WITHOUT year (how categorizeColumns returns them). (+26 more) +Cohesion: 0.05 +Nodes (42): Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Tests covering query.py lines 77-132., Pass field name WITHOUT year (how categorizeColumns returns them)., Pass field name WITHOUT year (how categorizeColumns returns them)., No historical data columns -> inner 400 caught by outer except -> 500., Pass field name WITHOUT year (how categorizeColumns returns them). (+34 more) ### Community 29 - "Community 29" -Cohesion: 0.04 -Nodes (42): SessionManager, PrometheusChatManager, PrometheusGenerator, Thread-safe proxy that delegates to per-thread sessions., SessionProxy, _make_generator(), Tests to increase coverage for: - main/app/prometheus/generation.py - main/a, Cover getGoogleSSO (lines 6-14). (+34 more) +Cohesion: 0.08 +Nodes (17): PrometheusGenerator, Thread-safe proxy that delegates to per-thread sessions., SessionProxy, _make_generator(), Tests to increase coverage for: - main/app/prometheus/generation.py - main/a, test_execute_workflow_basic_no_history(), test_execute_workflow_global_request_api_error(), test_execute_workflow_global_request_status_not_200() (+9 more) ### Community 30 - "Community 30" Cohesion: 0.07 @@ -828,8 +831,8 @@ Cohesion: 0.07 Nodes (27): code:json ([), code:javascript (const loadHistory = async (sid) => {), code:jsx (export default function MessageList({ messages, toolEvents, ), code:javascript (const loadHistory = async (sid) => {), code:jsx (export default function AgentLoop({ toolEvents, turnMetrics ), code:bash (git add frontend/src/App.jsx frontend/src/components/Message), code:bash (docker-compose up -d --build), code:sql (SELECT COUNT(*) FROM prometheus WHERE JSON_CONTAINS_PATH(his) (+19 more) ### Community 39 - "Community 39" -Cohesion: 0.07 -Nodes (25): Two dates in the range, both valid., Two dates in the range, both valid., Two dates in the range, both valid., Search with no index match falls back to string startswith., Search with no index match falls back to string startswith., search.strip() == '' should still dedup (line 181)., Search with no index match falls back to string startswith., Two dates in the range, both valid. (+17 more) +Cohesion: 0.06 +Nodes (31): Invalid date -> inner 400 passes through (not wrapped as 500)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., search.strip() == '' should still dedup (line 181)., search.strip() == '' should still dedup (line 181)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500. (+23 more) ### Community 40 - "Community 40" Cohesion: 0.12 @@ -844,32 +847,32 @@ Cohesion: 0.09 Nodes (16): StocksCacheManager, Tests for dynamic ticker index feature, Ticker index should be built when cache is loaded, Ticker index should contain all tickers from cache, Ticker index should be case-insensitive, Looking up ticker should return valid row index, Ticker index should be rebuilt when cache refreshes, TestTickerIndex (+8 more) ### Community 43 - "Community 43" -Cohesion: 0.12 +Cohesion: 0.15 Nodes (6): authenticateUser(), createUserAccount(), hashPassword(), verifyPassword(), TestAuthUtil, TestAuthUtilEdgeCases ### Community 44 - "Community 44" -Cohesion: 0.08 -Nodes (8): createSession(), getSessionById(), parseDeviceFields(), revokeSession(), validateSession(), UserSession, TestSessionExpiration, TestUserSessionModel +Cohesion: 0.14 +Nodes (3): UserSession, TestSessionExpiration, TestUserSessionModel ### Community 45 - "Community 45" -Cohesion: 0.03 -Nodes (89): AuthenticationManager, IntFlag, OrunmilaMemory, Orunmila, OrunmilaChatManager, MemoryCandidate, OrunmilaMemory, Covers line 28: GET /auth/health. (+81 more) +Cohesion: 0.05 +Nodes (38): IntFlag, Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 28: GET /auth/health., Covers line 28: GET /auth/health. (+30 more) ### Community 46 - "Community 46" Cohesion: 0.09 Nodes (21): Regression: queryFundamental must not mutate the shared cache TIME column., Regression: queryFundamental must not mutate the shared cache TIME column., Regression: queryFundamental must not mutate the shared cache TIME column., Single invalid date -> inner 400 passes through., Single invalid date -> inner 400 caught by outer except -> 500., Single invalid date -> inner 400 caught by outer except -> 500., Single invalid date -> inner 400 caught by outer except -> 500., Invalid fields now raise 400 with actionable error message. (+13 more) ### Community 47 - "Community 47" -Cohesion: 0.14 -Nodes (12): _make_user_client(), Return (client, app) with user router and mocked deps., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise., Covers lines 53-54, 56: admin access granted / denied., Covers lines 53-54, 56: admin access granted / denied., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise. (+4 more) +Cohesion: 0.1 +Nodes (17): _make_user_client(), Return (client, app) with user router and mocked deps., Covers line 24: GET /user/me returns currentUser., Covers line 24: GET /user/me returns currentUser., Covers line 24: GET /user/me returns currentUser., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise., Covers lines 31-32, 36, 43-44, 48: upgrade developer starter/enterprise. (+9 more) ### Community 48 - "Community 48" Cohesion: 0.06 Nodes (34): Backend (COMMIT), code:bash (cd frontend && pnpm add @openuidev/react-lang), code:bash (rm frontend/src/components/MdocMessage.jsx), code:python ("""OpenUI Lang system prompt section for Prometheus agent.), code:block12, code:block13, code:block14, code:block15 (+26 more) ### Community 49 - "Community 49" -Cohesion: 0.11 -Nodes (20): dispatchToolCall(), Pytest Testing, TDD tests: verify memory tools are wired into the Prometheus agent. RED: Thes, test_memory_tool_skipped_without_user(), test_non_memory_tool_not_routed_to_executeMemoryTool(), test_non_registry_tool_not_routed(), test_save_memory_routed_to_executeMemoryTool(), test_save_memory_routed_via_registry() (+12 more) +Cohesion: 0.1 +Nodes (20): dispatchToolCall(), TDD tests: verify memory tools are wired into the Prometheus agent. RED: Thes, TOOL_REGISTRY pattern must work correctly., test_memory_tool_skipped_without_user(), test_non_memory_tool_not_routed_to_executeMemoryTool(), test_non_registry_tool_not_routed(), test_save_memory_routed_to_executeMemoryTool(), test_save_memory_routed_via_registry() (+12 more) ### Community 50 - "Community 50" Cohesion: 0.07 @@ -884,8 +887,8 @@ Cohesion: 0.08 Nodes (7): Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., Cover all methods in chat.py (lines 11-120)., TestPrometheusChatManager ### Community 53 - "Community 53" -Cohesion: 0.1 -Nodes (39): applyUpdate(), archiveDead(), clearAll(), clearAllAsync(), count_memories(), countMemories(), countTokensCached(), decayScores() (+31 more) +Cohesion: 0.09 +Nodes (40): applyUpdate(), archiveDead(), clearAll(), clearAllAsync(), count_memories(), countMemories(), countTokensCached(), decayScores() (+32 more) ### Community 54 - "Community 54" Cohesion: 0.17 @@ -904,16 +907,16 @@ Cohesion: 0.09 Nodes (15): Performance benchmark tests for stocks API, Performance benchmark tests for stocks API, Ticker index lookup should be O(1) - very fast, Ticker index lookup should be O(1) - very fast, Prefix scan should be much slower than index lookup, Prefix scan should be much slower than index lookup, Index lookup should be significantly faster than scan, Index lookup should be significantly faster than scan (+7 more) ### Community 58 - "Community 58" -Cohesion: 0.15 -Nodes (17): getGoogleSSO(), createAccessToken(), googleCallback(), googleLogin(), isSecureScheme(), issueSessionCookie(), login(), logout() (+9 more) +Cohesion: 0.22 +Nodes (13): createAccessToken(), googleCallback(), isSecureScheme(), issueSessionCookie(), login(), logout(), register(), requireServiceToken() (+5 more) ### Community 59 - "Community 59" -Cohesion: 0.17 -Nodes (20): Tests for main/utils/connectivity.py — covers all branches., test_both_engines_ok(), test_connection_error(), test_generic_exception(), test_non_200_status(), test_non_stocks_prefix(), test_request_exception(), test_service_not_found() (+12 more) +Cohesion: 0.08 +Nodes (32): lifespan(), status(), Tests for main/utils/connectivity.py — covers all branches., checkServiceConnection — success, not found, errors., checkServiceConnection — success, not found, errors., checkMySqlConnection — success, errors, engine=None paths., checkMySqlConnection — success, errors, engine=None paths., test_both_engines_ok() (+24 more) ### Community 60 - "Community 60" -Cohesion: 0.06 -Nodes (19): Exercises the tzinfo-is-None branch (line 144-148)., Exercises the tzinfo-is-None branch (line 144-148)., Exercises the expiresAt-is-None branch (line 143)., Exercises the expiresAt-is-None branch (line 143)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154). (+11 more) +Cohesion: 0.09 +Nodes (7): Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., Cover all methods in session.py (lines 14-154)., TestSessionManager ### Community 61 - "Community 61" Cohesion: 0.13 @@ -924,8 +927,8 @@ Cohesion: 0.1 Nodes (20): architectures, attention_probs_dropout_prob, gradient_checkpointing, hidden_act, hidden_dropout_prob, hidden_size, initializer_range, intermediate_size (+12 more) ### Community 63 - "Community 63" -Cohesion: 0.09 -Nodes (19): Covers lines 66, 68-72, 74: full sessions listing., Covers lines 66, 68-72, 74: full sessions listing., Covers lines 66, 68-72, 74: full sessions listing., Covers lines 66, 68-72, 74: full sessions listing., Covers lines 100-104, 106: session found., Covers lines 100-104, 106: session found., Covers lines 100-104, 106: session found., Covers line 104: session not found. (+11 more) +Cohesion: 0.11 +Nodes (16): Calling with all None returns 400., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Calling with all None returns 400. (+8 more) ### Community 64 - "Community 64" Cohesion: 0.06 @@ -940,16 +943,16 @@ Cohesion: 0.1 Nodes (19): 1. Explore Agent — Prometheus Architecture, 2. MySQL Vector Storage (Researcher), 3. Memory Patterns (Researcher), A. Vector Embedding Integration, B. Pandas-First Vector Cache, C. Search Upgrade, code:python (class MemoryCache:), code:python (def searchMemories(cls, db, userId, query, embedding=None, l) (+11 more) ### Community 67 - "Community 67" -Cohesion: 0.07 -Nodes (29): execute_code(), get_wallet_allocation(), get_wallet_performance(), get_wallet_summary(), list_files(), Execute Python code in an isolated sandbox. Use for quantitative analysis,, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri (+21 more) +Cohesion: 0.08 +Nodes (24): get_wallet_positions(), get_wallet_rebalance(), get_wallet_summary(), Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Write a file to the workspace. Use this to save data files (CSV, JSON, scri (+16 more) ### Community 68 - "Community 68" Cohesion: 0.15 Nodes (28): addEntry(), applyEntries(), cachedPerformance(), createWallet(), deleteEntry(), fetchCachedClose(), fetchLivePrices(), fetchMarketDividends() (+20 more) ### Community 69 - "Community 69" -Cohesion: 0.2 -Nodes (26): downloadWorkspaceFile(), _base_url(), baseUrl(), checkpoint(), create(), delete_file(), destroy(), execute() (+18 more) +Cohesion: 0.22 +Nodes (25): _base_url(), baseUrl(), checkpoint(), create(), delete_file(), destroy(), execute(), executeWithWorkspace() (+17 more) ### Community 70 - "Community 70" Cohesion: 0.11 @@ -960,12 +963,12 @@ Cohesion: 0.11 Nodes (19): API Key System, B3 Scraper, Fundamental Data, Gemini Model, Historical Data, Ma'at Stock Algorithm, Mansa Server, MySQL Database (+11 more) ### Community 72 - "Community 72" -Cohesion: 0.09 -Nodes (10): Verify memory endpoints exist and are wired correctly., GET /prometheus/memories exists., POST /memories rejects missing key., POST /memories rejects missing value., POST /prometheus/memories exists., DELETE /prometheus/memories/{id} exists., GET /memories requires authentication., Full integration tests using mocked MemoryManager. (+2 more) +Cohesion: 0.08 +Nodes (11): Verify memory endpoints exist and are wired correctly., GET /prometheus/memories exists., POST /memories rejects missing key., POST /memories rejects missing value., POST /prometheus/memories exists., DELETE /prometheus/memories/{id} exists., GET /memories requires authentication., GET /memories requires USE_PROMETHEUS (basic USER role denied). (+3 more) ### Community 73 - "Community 73" -Cohesion: 0.13 -Nodes (11): autoAbbreviate(), dedupAbbrev(), detectNestedFields(), generateAbbreviations(), _parse_date(), parseDate(), parseDateEnd(), parseDateRange() (+3 more) +Cohesion: 0.16 +Nodes (7): _parse_date(), parseDate(), parseDateEnd(), parseDateRange(), parseDateStart(), TestParseDateRange, TestParseDateRange ### Community 74 - "Community 74" Cohesion: 0.11 @@ -992,7 +995,7 @@ Cohesion: 0.05 Nodes (44): cn(), AlertDialogAction(), AlertDialogCancel(), AlertDialogContent(), AlertDialogDescription(), AlertDialogFooter(), AlertDialogHeader(), AlertDialogMedia() (+36 more) ### Community 80 - "Community 80" -Cohesion: 0.15 +Cohesion: 0.14 Nodes (19): buildSummary(), charCount(), countTokens(), dedup(), extractDecisions(), extractMetrics(), extractSnapshots(), extractTickers() (+11 more) ### Community 81 - "Community 81" @@ -1000,7 +1003,7 @@ Cohesion: 0.14 Nodes (14): getLiveCotation(), Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th, Get real-time price quotation for a single Brazilian B3 stock. Returns th (+6 more) ### Community 82 - "Community 82" -Cohesion: 0.09 +Cohesion: 0.08 Nodes (27): buildFeatherCache(), Feather build / read helpers for the stocks cache. Owns the on-disk layout (CAC, Return (engine, featherPath, nestedPath), preferring live values on the cach, Return (engine, featherPath, nestedPath), preferring live values on the cach, readFeatherDataFrame(), _runtimeConf(), tryBuildLock(), arrowTypeFor() (+19 more) ### Community 83 - "Community 83" @@ -1008,8 +1011,8 @@ Cohesion: 0.1 Nodes (21): B3 Market Scraper, Brazilian Stocks Market Scraper, code:env (SCRAPER_ENABLED=FALSE # default False), code:json ({), Configuration Parameters, Constraint Engine ($\Lambda$), Engines, Fundamental Engine ($\Phi$) (+13 more) ### Community 84 - "Community 84" -Cohesion: 0.15 -Nodes (11): chat(), chat_stream(), createSession(), _forward(), getHistory(), Verify the user owns the session, raise 403 otherwise., Verify the user owns the session, raise 403 otherwise., resumeChatStream() (+3 more) +Cohesion: 0.14 +Nodes (12): chat(), chat_stream(), createSession(), downloadWorkspaceFile(), _forward(), getHistory(), Verify the user owns the session, raise 403 otherwise., Verify the user owns the session, raise 403 otherwise. (+4 more) ### Community 85 - "Community 85" Cohesion: 0.21 @@ -1020,8 +1023,8 @@ Cohesion: 0.08 Nodes (24): code:python (def test_build_requests_presorted_rows(monkeypatch, tmp_path), code:python (def test_read_feather_dataframe_uses_arrow_backed_columns(tm), code:python (from pyarrow import feather), code:python (def readFeatherDataFrame(path) -> tuple[pd.DataFrame, bool]:), code:python (df, presorted = readFeatherDataFrame(CACHE_FEATHER_PATH)), code:bash (git add main/app/stocks_api/cache.py tests/test_stocks_cache), code:python (def test_deserialize_jsoncolumns_handles_arrowdtype_binary()), code:python (if col in JSON_COLUMNS and (df[col].dtype == "object" or pd.) (+16 more) ### Community 87 - "Community 87" -Cohesion: 0.12 -Nodes (16): countTokens(), getTokenizer(), PrometheusSummarizer, Summarize conversation history into episode summaries., Check if accumulated tokens exceed episode threshold., Get messages since the last episode for summarization., Check if accumulated tokens exceed episode threshold., Check if accumulated tokens exceed episode threshold. (+8 more) +Cohesion: 0.1 +Nodes (19): countTokens(), getTokenizer(), PrometheusSummarizer, Summarize conversation history into episode summaries., Check if accumulated tokens exceed episode threshold., Get messages since the last episode for summarization., Check if accumulated tokens exceed episode threshold., Check if accumulated tokens exceed episode threshold. (+11 more) ### Community 88 - "Community 88" Cohesion: 0.18 @@ -1064,20 +1067,20 @@ Cohesion: 0.15 Nodes (16): AuthenticationManager, AuthenticationService, PrometheusChatManager, PrometheusGenerator, PrometheusService, SessionManager, UserManager, UserService (+8 more) ### Community 98 - "Community 98" -Cohesion: 0.28 +Cohesion: 0.25 Nodes (6): extractTokenPayload(), Tests for extractTokenPayload — the standalone token extraction dependency., Create a mock Starlette Request with given headers., Authorization: Bearer (empty) — no token after Bearer., Authorization: Basic xxx — not Bearer, so no token found., TestExtractTokenPayload ### Community 99 - "Community 99" -Cohesion: 0.09 -Nodes (19): _make_prometheus_client(), Return (client, app) with prometheus router and mocked deps., Covers lines 62-63, 65-68: PUT /prometheus/sessions/{sessionId}., Covers lines 62-63, 65-68: PUT /prometheus/sessions/{sessionId}., Covers lines 65-68: title updated successfully., Covers lines 65-68: title updated successfully., Covers lines 62-63, 65-68: PUT /prometheus/sessions/{sessionId}., Covers lines 65-68: title updated successfully. (+11 more) +Cohesion: 0.04 +Nodes (46): _make_prometheus_client(), Covers lines 95-98: session deleted., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 111-112: sessionId is None, new session created., Covers lines 111-112: sessionId is None, new session created., Covers lines 118-119: sessionId is None, new session created. (+38 more) ### Community 100 - "Community 100" -Cohesion: 0.09 -Nodes (13): _assert_gemini_safe(), Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Regression: HarnessState must never leak into tool signatures., Regression: HarnessState must never leak into tool signatures., Assert a tool function has only Gemini-compatible parameter types., Assert a tool function has only Gemini-compatible parameter types., test_get_state_no_state_returns_error() (+5 more) +Cohesion: 0.16 +Nodes (6): _assert_gemini_safe(), Assert a tool function has only Gemini-compatible parameter types., Assert a tool function has only Gemini-compatible parameter types., test_get_state_no_state_returns_error(), test_tool_has_gemini_safe_signature(), TestStateToolFunctions ### Community 101 - "Community 101" -Cohesion: 0.23 -Nodes (21): closeOwnSession(), popAuthSession(), Shared auth-guard + own-SessionLocal convention every tool repeats. Returns, ensureOwnership(), get_wallet_allocation(), get_wallet_performance(), get_wallet_positions(), get_wallet_rebalance() (+13 more) +Cohesion: 0.2 +Nodes (23): closeOwnSession(), popAuthSession(), Shared auth-guard + own-SessionLocal convention every tool repeats. Returns, ensureOwnership(), get_wallet_allocation(), get_wallet_performance(), get_wallet_positions(), get_wallet_rebalance() (+15 more) ### Community 102 - "Community 102" Cohesion: 0.11 @@ -1099,6 +1102,10 @@ Nodes (5): buildClient(), connect(), ensureFastmcp(), MCPClientPool, _parseServe Cohesion: 0.22 Nodes (3): parseYearInput(), TestParseYearInput, TestParseYearInput +### Community 107 - "Community 107" +Cohesion: 0.22 +Nodes (4): Authentication System, Google OAuth, JWT Authentication, TestSessionExpiryConfig + ### Community 108 - "Community 108" Cohesion: 0.14 Nodes (13): all-MiniLM-L6-v2, Background, code:block1 (pip install -U sentence-transformers), code:python (from sentence_transformers import SentenceTransformer), code:python (from transformers import AutoTokenizer, AutoModel), Fine-tuning, Hyper parameters, Intended uses (+5 more) @@ -1116,8 +1123,8 @@ Cohesion: 0.14 Nodes (13): code:python (import pytest), code:python (import logging), code:bash (git add main/app/prometheus/state.py tests/test_harness_stat), File Map, Global Constraints, Phase 1: HarnessState (In-Memory Agent Scratchpad), Prometheus Harness — Master Implementation Plan (v2: CubeSandbox + On-Demand), Relationship to Existing Systems (+5 more) ### Community 112 - "Community 112" -Cohesion: 0.1 -Nodes (16): Calling with all None returns 400., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Tests covering query.py lines 142-202., Calling with all None returns 400. (+8 more) +Cohesion: 0.12 +Nodes (19): AuthenticationManager, SessionManager, PrometheusChatManager, Cover getGoogleSSO (lines 6-14)., Cover getGoogleSSO (lines 6-14)., Cover __init__ and updateDates., Cover __init__ and updateDates (lines 22-37)., Cover streamMessage in agent.py. (+11 more) ### Community 113 - "Community 113" Cohesion: 0.15 @@ -1132,8 +1139,8 @@ Cohesion: 0.17 Nodes (11): dateOnly(), EditDividendDialog(), EditLotDialog(), fmtBRL(), fmtMoney(), KIND_STYLES, lotTitle(), deleteDividend() (+3 more) ### Community 116 - "Community 116" -Cohesion: 0.12 -Nodes (16): _build_system_prompt(), buildSystemPrompt(), chatSession(), _execute_memory_tool(), executeMemoryTool(), _get_client(), _get_memory_tools(), getClient() (+8 more) +Cohesion: 0.11 +Nodes (20): create_memory(), createMemory(), embed(), _build_system_prompt(), buildSystemPrompt(), chatSession(), _execute_memory_tool(), executeMemoryTool() (+12 more) ### Community 117 - "Community 117" Cohesion: 0.15 @@ -1148,8 +1155,8 @@ Cohesion: 0.07 Nodes (26): code:python ("""Tests for SandboxManager file mutation helpers (delete_fi), code:python (from main.app.prometheus.sandbox import SandboxManager, host), code:python (@router.post("/workspace/upload")), code:bash (git add main/controller/prometheus_controller.py tests/test_), code:python (from unittest.mock import patch, MagicMock), code:python (from main.app.prometheus.sandbox import SandboxManager, host), code:python (async def serve_file(path: str, **_) -> dict:), code:python ("serve_file": serve_file,) (+18 more) ### Community 120 - "Community 120" -Cohesion: 0.16 -Nodes (20): _make_auth_client(), Tests to cover uncovered lines across controllers, UserManager, and auth util., Return (client, app) with auth + user routers and mocked getSession., test_callback_existing_user(), test_callback_generic_exception(), test_callback_new_user(), test_callback_no_user_info(), test_callback_with_state_redirect() (+12 more) +Cohesion: 0.09 +Nodes (35): _make_auth_client(), Tests to cover uncovered lines across controllers, UserManager, and auth util., Covers lines 44-54, 63, 66-71: register success, ValueError, generic Exception., Covers lines 44-54, 63, 66-71: register success, ValueError, generic Exception., Covers lines 87-93, 102: login success and failure paths., Covers lines 87-93, 102: login success and failure paths., Return (client, app) with auth + user routers and mocked getSession., Covers lines 107, 109-130, 133: logout token extraction and revocation. (+27 more) ### Community 121 - "Community 121" Cohesion: 0.21 @@ -1188,8 +1195,8 @@ Cohesion: 0.07 Nodes (27): 1.1 Functional (per surface; tags: EXISTS = build on it, PARTIAL = half reusable, MISSING = greenfield), 1.2 Non-functional, 1. Requirements, 2. Domain model, 3. API contracts (all under `/api/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout), 3. API contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout), 3. API contracts (all under `/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth = wallet-local dependency on the **introspect contract** (user directive 2026-09-30): resolve the raw token (`X-Access-Token` → `Authorization: Bearer` → `mansa_token` cookie, order per `main/app/authentication/util.py:54-66`) → `introspectToken(db, raw)` (`main/app/authentication/introspect.py:14`) → `{userId, username, roles}` → `Roles.checkAccess(roles, Permission.WALLET)` (`main/utils/roles.py:29-39`) → `403` if absent; `Depends(getSession)` for the DB session), 4. Phased build plan (writing-plans: each phase independently reviewable; reviewer PASS per phase) (+19 more) ### Community 131 - "Community 131" -Cohesion: 0.23 -Nodes (8): pack → unpack preserves values., Empty list roundtrips., 384-dim vector packs to 1536 bytes., TestPackUnpack, pack_vector(), Unpack MySQL BLOB to float list., Vectorized cosine similarity: one query against N embeddings., unpack_vector() +Cohesion: 0.11 +Nodes (17): Same input → same hash., Different inputs → different hashes., Returns 32-char hex string., pack → unpack preserves values., Empty list roundtrips., 384-dim vector packs to 1536 bytes., TestContentHash, TestPackUnpack (+9 more) ### Community 132 - "Community 132" Cohesion: 0.25 @@ -1208,8 +1215,8 @@ Cohesion: 0.11 Nodes (4): cache(), Tests for ResultCache., TestColumnValidator, TestResultCache ### Community 136 - "Community 136" -Cohesion: 0.09 -Nodes (23): _getDb(), Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use (+15 more) +Cohesion: 0.18 +Nodes (12): _getDb(), Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use t, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use, Search user's saved memories, preferences, and past analysis context. Use (+4 more) ### Community 137 - "Community 137" Cohesion: 0.18 @@ -1225,7 +1232,7 @@ Nodes (6): Dataset, produce_data(), Train script for a single file Need to set ### Community 140 - "Community 140" Cohesion: 0.05 -Nodes (49): PrometheusMemory, PrometheusMemory, Prometheus, MemoryManager, PrometheusMemory, All memory operations. Stateless class methods., PrometheusService, _count_memories() (+41 more) +Nodes (49): PrometheusMemory, PrometheusMemory, MemoryManager, PrometheusMemory, All memory operations. Stateless class methods., PrometheusService, _count_memories(), _create_memory() (+41 more) ### Community 141 - "Community 141" Cohesion: 0.24 @@ -1256,8 +1263,8 @@ Cohesion: 0.23 Nodes (3): categorizeColumns(), TestCategorizeColumns, TestCategorizeColumns ### Community 148 - "Community 148" -Cohesion: 0.07 -Nodes (24): Covers lines 114-115, 117-120, 122, 125: POST /prometheus/chat., Covers lines 114-115, 117-120, 122, 125: POST /prometheus/chat., Covers lines 111-112: sessionId is None, new session created., Covers lines 111-112: sessionId is None, new session created., Covers lines 109-136: POST /prometheus/chat/stream (SSE)., Covers lines 118-119: sessionId is None, new session created., Covers lines 114-115, 117-120, 122: existing session with verified ownership., Covers lines 114-115, 117-120, 122: existing session with verified ownership. (+16 more) +Cohesion: 0.09 +Nodes (20): Covers lines 114-115, 117-120, 122, 125: POST /prometheus/chat., Covers lines 114-115, 117-120, 122, 125: POST /prometheus/chat., Covers lines 109-136: POST /prometheus/chat/stream (SSE)., Covers lines 114-115, 117-120, 122: existing session with verified ownership., Covers lines 114-115, 117-120, 122: existing session with verified ownership., Covers lines 114-115, 117-120, 122: existing session with verified ownership., Covers lines 120-121: existing session with verified ownership., Covers lines 114-115, 117-120, 122, 125: POST /prometheus/chat. (+12 more) ### Community 149 - "Community 149" Cohesion: 0.15 @@ -1269,7 +1276,7 @@ Nodes (3): MEMORY_TOOLS must be defined as a Tool wrapping FunctionDeclarations. ### Community 152 - "Community 152" Cohesion: 0.16 -Nodes (21): list_wallet_earnings(), narrate_positions(), Narrate the user's wallet positions in plain language. Read-only summary, List accrued earnings (dividends, JSCP) for a wallet. Read-only: never mu, List accrued earnings (dividends, JSCP) for a wallet. Read-only: never mu, listEarnings(), syncEarnings(), addEntry() (+13 more) +Nodes (23): get_wallet_allocation(), list_wallet_earnings(), narrate_positions(), Narrate the user's wallet positions in plain language. Read-only summary, Break wallet equity down by ticker or asset type. Read-only: never mutate, Break wallet equity down by ticker or asset type. Read-only: never mutate, List accrued earnings (dividends, JSCP) for a wallet. Read-only: never mu, List accrued earnings (dividends, JSCP) for a wallet. Read-only: never mu (+15 more) ### Community 153 - "Community 153" Cohesion: 0.11 @@ -1288,8 +1295,8 @@ Cohesion: 0.22 Nodes (8): API Endpoints, code:env (#), code:bash (python __init__.py), code:mermaid (graph TD), License, Prometheus, Usage, Workflow ### Community 157 - "Community 157" -Cohesion: 0.1 -Nodes (16): getFundamental(), JSONBytesResponse, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret (+8 more) +Cohesion: 0.15 +Nodes (13): getFundamental(), Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret, Get point-in-time fundamental/valuation data for Brazilian B3 stocks. Ret (+5 more) ### Community 158 - "Community 158" Cohesion: 0.22 @@ -1344,8 +1351,8 @@ Cohesion: 0.25 Nodes (8): padding, direction, pad_id, pad_to_multiple_of, pad_token, pad_type_id, strategy, Fixed ### Community 172 - "Community 172" -Cohesion: 0.17 -Nodes (7): Different query parameters should not share cache, Cache should expire after TTL, Tests for query result caching, CacheManager should track cached queries, Query cache should have configurable TTL, getCachedStocks should support column filtering, TestQueryCaching +Cohesion: 0.2 +Nodes (9): introspectToken(), verifyAccessToken(), introspect(), Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError. (+1 more) ### Community 173 - "Community 173" Cohesion: 0.25 @@ -1388,16 +1395,16 @@ Cohesion: 0.14 Nodes (14): 3.0 Verified ground truth, 3.10 Migration sequence + verification, 3.1 Target topology, 3.2 Worker-container extraction, 3.3 nginx upstream evolution — validated against the user's plan, 3.4 TODO 13 migration — drop `{service}_HOST`/`{service}_PORT`, 3.5 Redis — exactly two jobs, 3.6 Cache strategy across boxes (+6 more) ### Community 184 - "Community 184" -Cohesion: 0.14 -Nodes (9): Verify that getSession() returns per-thread Session instances., Calling getSession() twice in the same thread returns the same object., Two threads must NOT share a Session object., With 20 concurrent threads, every thread must get its own Session., The returned object must be a real requests.Session., TestGetSession, get_session(), Return a requests.Session for the current thread. Sessions are created la (+1 more) +Cohesion: 0.11 +Nodes (12): TestCleanup, Verify that getSession() returns per-thread Session instances., Calling getSession() twice in the same thread returns the same object., Two threads must NOT share a Session object., With 20 concurrent threads, every thread must get its own Session., The returned object must be a real requests.Session., TestGetSession, cleanup() (+4 more) ### Community 185 - "Community 185" Cohesion: 0.38 Nodes (7): code:python (import pytest), code:python (from __future__ import annotations), code:bash (git add main/app/prometheus/context.py tests/test_context.py), Phase 4: ToolContext (Bundled Dispatch Dependencies), Phase 4: ToolContext (Replace God Function), Task 5: ToolContext — Dataclass for Agent Use, Task 5: ToolContext — Single Dispatch Object ### Community 186 - "Community 186" -Cohesion: 0.13 -Nodes (20): listFields(), Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental. (+12 more) +Cohesion: 0.11 +Nodes (25): listFields(), Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental., Discover available field names before querying /historical or /fundamental. (+17 more) ### Community 187 - "Community 187" Cohesion: 0.25 @@ -1412,8 +1419,8 @@ Cohesion: 0.33 Nodes (3): buildClient(), connect(), MCPClientPool ### Community 190 - "Community 190" -Cohesion: 0.2 -Nodes (9): Invalid date -> inner 400 passes through (not wrapped as 500)., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Invalid date -> inner 400 caught by outer except -> 500., Two dates in the range, both valid. (+1 more) +Cohesion: 0.18 +Nodes (11): Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback., Store a memory about the user's preferences, analysis results, or feedback. (+3 more) ### Community 191 - "Community 191" Cohesion: 0.33 @@ -1428,8 +1435,8 @@ Cohesion: 0.33 Nodes (6): normalizer, clean_text, handle_chinese_chars, lowercase, strip_accents, type ### Community 194 - "Community 194" -Cohesion: 0.29 -Nodes (6): Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError., Covers lines 50-51: jwt.InvalidTokenError. +Cohesion: 0.18 +Nodes (11): Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers line 16: empty password raises ValueError., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 48-49: jwt.ExpiredSignatureError. (+3 more) ### Community 195 - "Community 195" Cohesion: 0.33 @@ -1440,8 +1447,8 @@ Cohesion: 0.33 Nodes (5): cls_token, mask_token, pad_token, sep_token, unk_token ### Community 197 - "Community 197" -Cohesion: 0.17 -Nodes (12): getHistorical(), Get year-based historical financial data for Brazilian B3 stocks. Returns, Get year-based historical financial data for Brazilian B3 stocks. Returns, Get year-based historical financial data for Brazilian B3 stocks. Returns, Get year-based historical financial data for Brazilian B3 stocks. Returns, Get year-based historical financial data for Brazilian B3 stocks. Returns, Get year-based historical financial data for Brazilian B3 stocks. Returns, Get year-based historical financial data for Brazilian B3 stocks. Returns (+4 more) +Cohesion: 0.1 +Nodes (15): getHistorical(), JSONBytesResponse, Get year-based historical financial data for Brazilian B3 stocks. Returns, Get year-based historical financial data for Brazilian B3 stocks. Returns, Get year-based historical financial data for Brazilian B3 stocks. Returns, Get year-based historical financial data for Brazilian B3 stocks. Returns, Sends pre-serialized JSON bytes without re-encoding (cache-friendly)., Get year-based historical financial data for Brazilian B3 stocks. Returns (+7 more) ### Community 198 - "Community 198" Cohesion: 0.33 @@ -1532,12 +1539,12 @@ Cohesion: 0.4 Nodes (5): model, continuing_subword_prefix, max_input_chars_per_word, type, unk_token ### Community 221 - "Community 221" -Cohesion: 0.11 -Nodes (21): execute_code(), Store a value in the harness state for this session. Use this to save inter, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Execute Python code in an isolated sandbox. Use for quantitative analysis,, Read a file from the workspace. Args: path: Path to the file (e. (+13 more) +Cohesion: 0.16 +Nodes (14): execute_code(), Store a value in the harness state for this session. Use this to save inter, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis, (+6 more) ### Community 222 - "Community 222" -Cohesion: 0.14 -Nodes (12): initialize(), P5: register memory maintenance on the shared scheduler. Kept in this ser, registerMemoryMaintenanceJob(), initialize(), P5: register the session-cleanup job on the shared scheduler. Kept in thi, registerSessionCleanupJobs(), UserService, getSharedScheduler() (+4 more) +Cohesion: 0.1 +Nodes (19): _downloadModel(), getEmbeddingModel(), initialize(), initialize(), OrunmilaService, initialize(), P5: register memory maintenance on the shared scheduler. Kept in this ser, registerMemoryMaintenanceJob() (+11 more) ### Community 223 - "Community 223" Cohesion: 0.4 @@ -1571,6 +1578,10 @@ Nodes (5): code:python (import pytest), code:python (import hashlib), code:bash Cohesion: 0.18 Nodes (11): 2.2.1 Complexity hotspots table (H1–H17 condensed to P0/P1/P2), 2.2.2 Blob inventory (LOC table + SRP evidence), 2.2.3 Mass data loads, 2.2.4 Phased fix roadmap (P0/P1/P2), §2.2 CODE EFFICIENCY — O(n²), Complexity & Blob Anti-Patterns, code:block4 (scraper.py:44 671 LOC — mass loads: SELECT * fetchma), code:powershell (ruff check . && ruff format --check .), code:powershell (pytest tests/test_stocks_cache_concurrency.py -v # ThreadPo) (+3 more) +### Community 231 - "Community 231" +Cohesion: 0.15 +Nodes (18): executeStateTool(), get_state(), Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, test_dispatch_get_state(), test_dispatch_set_state() (+10 more) + ### Community 232 - "Community 232" Cohesion: 0.4 Nodes (5): Bucket A: Security Fixes (quick wins, 30 min), Bucket B: DB Session Cleanup (medium, 1-2 hrs), Bucket C: Testing (medium, 2-3 hrs), Bucket D: Infrastructure (large, 4+ hrs), Recommended Delegation Buckets @@ -1580,8 +1591,8 @@ Cohesion: 0.4 Nodes (5): 8. Build Sequence (4 phases, each independently shippable), Phase 0 — Sandbox foundation (1-2 days, no user-facing change), Phase 1 — MCP exposure of STOCKS_API (1 day), Phase 2 — Refactor PROMETHEUS to agentic (3-5 days, the big one), Phase 3 — Hardening (1-2 days, can ship incrementally) ### Community 234 - "Community 234" -Cohesion: 0.11 -Nodes (25): chat_stream(), downloadWorkspaceFile(), getHistory(), resumeChatStream(), updateSessionTitle(), verifySessionOwnsership(), create(), delete_file() (+17 more) +Cohesion: 0.07 +Nodes (37): chat_stream(), downloadWorkspaceFile(), getHistory(), resumeChatStream(), updateSessionTitle(), verifySessionOwnsership(), OrunmilaSandbox, create() (+29 more) ### Community 236 - "Community 236" Cohesion: 0.5 @@ -1648,8 +1659,8 @@ Cohesion: 0.5 Nodes (3): Basic fields like ROE must still pass., Basic fields like ROE must still pass., Basic fields like ROE must still pass. ### Community 256 - "Community 256" -Cohesion: 0.13 -Nodes (13): Covers lines 83-84: session not found., Covers lines 77, 83-84, 86: GET /prometheus/history/{sessionId}., Covers lines 77, 83-84, 86: GET /prometheus/history/{sessionId}., Covers lines 77, 86: session found with history., Covers lines 77, 86: session found with history., Covers lines 77, 83-84, 86: GET /prometheus/history/{sessionId}., Covers lines 77, 86: session found with history., Covers lines 77, 83-84, 86: GET /prometheus/history/{sessionId}. (+5 more) +Cohesion: 0.12 +Nodes (11): Zero access but score still above threshold → not archived., Even with low score, if accessed → not archived., Even with low score, if accessed → not archived., Already archived memories are skipped., Already archived memories are skipped., Score below threshold + accessCount=0 + 90+ days → archived., Score below threshold + accessCount=0 + 90+ days → archived., Low score but accessed recently → not archived. (+3 more) ### Community 258 - "Community 258" Cohesion: 0.67 @@ -1672,8 +1683,8 @@ Cohesion: 0.22 Nodes (8): 1. Prime owns the goal, lanes own the work, 2. Dispatch: `delegate()`, one per lane, one turn, 3. Delegate toolsets vary — verify each lane, 4. Trust nothing — verify everything, 5. Windows PowerShell survival, 6. Finish per lane, not per swarm, 7. Standing bans (this repo), SWARMS.md — subagent swarm playbook (OpenCode / Hermes) ### Community 474 - "Community 474" -Cohesion: 0.12 -Nodes (4): B3Scraper, getCurrentSelic(), getInitialData(), calculateInvestingScore() +Cohesion: 0.1 +Nodes (9): B3Scraper, getCurrentSelic(), getInitialData(), calculateInvestingScore(), initialize(), P5: register the scraper cron jobs on the shared scheduler. Kept in this, registerScraperJobs(), runScraper() (+1 more) ### Community 475 - "Community 475" Cohesion: 0.15 @@ -1704,8 +1715,8 @@ Cohesion: 0.5 Nodes (4): code:python (def test_session_scoped_memory(db_session, sample_user):), code:python (# Add to main/models/memory.py), code:bash (git add main/models/memory.py main/app/prometheus/memory.py ), Task 8: Session Scoping ### Community 482 - "Community 482" -Cohesion: 0.14 -Nodes (20): get_wallet_positions(), List wallet holdings with live prices, equity, allocation, and buy signals., List wallet holdings with live prices, equity, allocation, and buy signals., fetchLivePrices(), fetchXangoScores(), getPositions(), getRebalance(), pricePass() (+12 more) +Cohesion: 0.17 +Nodes (17): fetchLivePrices(), fetchXangoScores(), getPositions(), getRebalance(), pricePass(), XANGO quality score per ticker (0-100 scale). One fundamental read per tick, XANGO quality score per ticker (0-100 scale). One fundamental read per ti, XANGO quality score per ticker (0-100 scale). One fundamental read per tick (+9 more) ### Community 483 - "Community 483" Cohesion: 0.5 @@ -1744,8 +1755,8 @@ Cohesion: 0.33 Nodes (5): Baseline (lane 4), Export recipe, Move triggers (any one fires the migration), Options, Vector Scale-Up Runbook ### Community 493 - "Community 493" -Cohesion: 0.1 -Nodes (16): GET /memories requires USE_PROMETHEUS (basic USER role denied)., GET /stocks/realtime-cotation without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422., GET /stocks/realtime-cotation without search returns 422. (+8 more) +Cohesion: 0.13 +Nodes (13): Covers lines 100-104, 106: GET /user/sessions/current., Covers lines 100-104, 106: GET /user/sessions/current., Covers lines 100-104, 106: session found., Covers lines 100-104, 106: session found., Covers lines 100-104, 106: GET /user/sessions/current., Covers lines 100-104, 106: session found., Covers line 104: session not found., Covers line 104: session not found. (+5 more) ### Community 495 - "Community 495" Cohesion: 0.05 @@ -1756,8 +1767,8 @@ Cohesion: 0.17 Nodes (7): Tests for dynamic ticker index feature, Ticker index should be built when cache is loaded, Ticker index should contain all tickers from cache, Ticker index should be case-insensitive, Looking up ticker should return valid row index, Ticker index should be rebuilt when cache refreshes, TestTickerIndex ### Community 498 - "Community 498" -Cohesion: 0.1 -Nodes (17): Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 126, 131, 135-136., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 127-129: session not found., Covers lines 127-129: session not found. (+9 more) +Cohesion: 0.04 +Nodes (42): Covers lines 83-84: session not found., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 126, 131, 135-136., Covers lines 126-136: DELETE /user/sessions/{sessionId}., Covers lines 126, 131, 135-136., Covers lines 127-129: session not found. (+34 more) ### Community 499 - "Community 499" Cohesion: 0.2 @@ -1771,9 +1782,13 @@ Nodes (21): generateKey(), createKey(), createStoredApiKey(), hashApiKey(), init Cohesion: 0.22 Nodes (3): getCurrentSession(), getSessions(), sessionToDict() +### Community 502 - "Community 502" +Cohesion: 0.17 +Nodes (7): OrunmilaMemory, OrunmilaSession, Orunmila, createSession(), OrunmilaChatManager, MemoryCandidate, OrunmilaMemory + ### Community 503 - "Community 503" -Cohesion: 0.16 -Nodes (17): executeStateTool(), get_state(), Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, Retrieve values from the harness state. Use this to recall intermediate results,, test_dispatch_set_state(), test_get_state_all() (+9 more) +Cohesion: 0.32 +Nodes (4): memoryMaintenance(), _create(), After 10 cycles, preference (0.99^10) > context (0.90^10)., TestTypeAwareDecay ### Community 505 - "Community 505" Cohesion: 0.33 @@ -1807,49 +1822,49 @@ Nodes (11): 2.0 Grounding: what the code actually does, 2.1 Hypotheses, 2.3 Scen Cohesion: 0.26 Nodes (4): Shared query pipeline for historical and fundamental endpoints., Fetch live prices for B3 tickers via yfinance. B3 tickers must match, sanitizeNanValues(), StocksQueryManager -### Community 518 - "Community 518" -Cohesion: 0.42 -Nodes (7): fetchCachedClose(), fetchMarketDividends(), fetchPadraoCloses(), stocksApiBase(), stocksApiHeaders(), cachedPerformance(), getPerformance() - ### Community 519 - "Community 519" -Cohesion: 0.57 -Nodes (6): addRole(), addRoleToUser(), getCurrentUser(), getRolesList(), hasRole(), toDict() +Cohesion: 0.12 +Nodes (7): Cover all methods in authentication.py (lines 13-75)., Cover all methods in authentication.py (lines 13-75)., Cover all methods in authentication.py (lines 13-75)., Cover all methods in authentication.py (lines 13-75)., Cover all methods in authentication.py (lines 13-75)., Cover all methods in authentication.py (lines 13-75)., TestAuthenticationManager ### Community 520 - "Community 520" -Cohesion: 0.33 -Nodes (5): pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged. +Cohesion: 0.16 +Nodes (9): pd.NA is not a string, so lambda returns it unchanged., All four SPECIAL_COLS should parse correctly when mixed with None., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., pd.NA is not a string, so lambda returns it unchanged., All four SPECIAL_COLS should parse correctly when mixed with None., All four SPECIAL_COLS should parse correctly when mixed with None. (+1 more) ### Community 521 - "Community 521" -Cohesion: 0.22 -Nodes (8): Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false., Hit the actual /stocks/cotations HTTP endpoint with adjusted=false. +Cohesion: 0.29 +Nodes (7): check_cache(), Read a file from the sandbox filesystem. Args: path: Absolute pa, List files in the workspace directory. Args: path: Directory pat, Upload a file to the sandbox filesystem. Use this to push data files (CSV,, Check if a computed result exists in the cache. Use before executing expens, read_sandbox_file(), upload_to_sandbox() ### Community 522 - "Community 522" Cohesion: 0.18 Nodes (11): 2.0 Grounding: what the code actually does, 2.1 Hypotheses, 2.3 Scenarios, 2.4 Protocol, 2.5 Metrics, 2.6 Acceptance thresholds — **ALL PROPOSED, freeze after first real run**, 2.7 Results doc layout, 2.8 Feeding `/status` (TODO 14) (+3 more) +### Community 523 - "Community 523" +Cohesion: 0.18 +Nodes (5): createSession(), getSessionById(), parseDeviceFields(), revokeSession(), validateSession() + ### Community 524 - "Community 524" Cohesion: 0.36 Nodes (4): countTokens(), getTokenizer(), PrometheusSummarizer, smartTruncate() ### Community 525 - "Community 525" -Cohesion: 0.09 -Nodes (29): check_cache(), executeMemoryTool(), list_files(), Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri (+21 more) +Cohesion: 0.11 +Nodes (21): list_files(), Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, Write a file to the workspace. Use this to save data files (CSV, JSON, scri, List files in the workspace directory. Args: path: Directory pat, List files in the workspace directory. Args: path: Directory pat (+13 more) ### Community 526 - "Community 526" Cohesion: 0.33 Nodes (7): buildKey(), clearAll(), getMatrix(), invalidateUser(), runAwait(), main(), One-shot: renormalize stored embeddings to unit norm. Usage: python scripts/back ### Community 528 - "Community 528" -Cohesion: 0.17 -Nodes (10): Authentication System, introspectToken(), verifyAccessToken(), introspect(), FastAPI, Google OAuth, JWT Authentication, getWalletIdentity() (+2 more) +Cohesion: 0.57 +Nodes (6): addRole(), addRoleToUser(), getCurrentUser(), getRolesList(), hasRole(), toDict() ### Community 529 - "Community 529" -Cohesion: 0.18 -Nodes (9): Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails. (+1 more) +Cohesion: 0.2 +Nodes (9): Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval. (+1 more) ### Community 530 - "Community 530" Cohesion: 0.2 -Nodes (10): code:python (def test_compra_average_includes_costs(dbSession):), code:python (from datetime import date), code:bash (git add main/service/wallet_service.py main/controller/walle), code:bash (git add ), code:python (import main.models.wallet # noqa: F401), code:bash (git add migrations/env.py migrations/versions/_wallet_t), Review Focus, Task 3: Alembic revision for the wallet tables (needs MySQL) (+2 more) +Nodes (10): code:bash (git add ), code:python (from main.models.base import Base), code:python (from sqlalchemy import Column, Date, Enum, ForeignKey, Integ), code:bash (git add main/models/wallet.py tests/test_wallet_models.py), code:python (import main.models.wallet # noqa: F401), code:bash (git add migrations/env.py migrations/versions/_wallet_t), Review Focus, Task 2: Wallet ORM models (5 tables, `user_db`) (+2 more) ### Community 532 - "Community 532" Cohesion: 0.5 @@ -1864,12 +1879,16 @@ Cohesion: 0.5 Nodes (4): LATER (P2 — when touching these files), NOW (P0 — fix before next release), Priority Matrix, SOON (P1 — fix within 2 weeks) ### Community 535 - "Community 535" -Cohesion: 0.13 -Nodes (13): Covers lines 95-98: session deleted., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 96-97: session not found., Covers lines 95-98: DELETE /prometheus/sessions/{sessionId}., Covers lines 95-98: session deleted., Covers lines 96-97: session not found., Covers lines 95-98: DELETE /prometheus/sessions/{sessionId}. (+5 more) +Cohesion: 0.27 +Nodes (10): get_wallet_performance(), Compute time-weighted return, volatility, and dividends for a wallet or ticker., Compute time-weighted return, volatility, and dividends for a wallet or ticker., fetchCachedClose(), fetchMarketDividends(), fetchPadraoCloses(), stocksApiBase(), stocksApiHeaders() (+2 more) ### Community 536 - "Community 536" -Cohesion: 0.12 -Nodes (10): initialize(), initialize(), memoryMaintenance(), OrunmilaService, initialize(), MCPDetectMiddleware, StocksAPIService, initialize() (+2 more) +Cohesion: 0.33 +Nodes (3): initialize(), MCPDetectMiddleware, StocksAPIService + +### Community 538 - "Community 538" +Cohesion: 0.25 +Nodes (8): Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the sandbox filesystem. Args: path: Absolute pa, Read a file from the sandbox filesystem. Args: path: Absolute pa, Read a file from the workspace. Args: path: Path to the file (e., read_file() ### Community 539 - "Community 539" Cohesion: 0.22 @@ -1880,8 +1899,8 @@ Cohesion: 0.29 Nodes (6): code:python (import argparse), code:bash (git add bench/bench_memory_vector.py), Global Constraints, Lane 4: Before/After Bench Implementation Plan, Task 1: Bench script with synthetic scale sweep, Task 2: Record baseline and post-lane numbers ### Community 541 - "Community 541" -Cohesion: 0.22 -Nodes (8): Historical query with a year range., Historical query with a year range., Historical query with a year range., Historical query with a year range., Historical query with a year range., Historical query with a year range., Historical query with a year range., Historical query with a year range. +Cohesion: 0.17 +Nodes (7): Different query parameters should not share cache, Cache should expire after TTL, Tests for query result caching, CacheManager should track cached queries, Query cache should have configurable TTL, getCachedStocks should support column filtering, TestQueryCaching ### Community 542 - "Community 542" Cohesion: 0.5 @@ -1891,13 +1910,17 @@ Nodes (3): at, label, rows Cohesion: 0.2 Nodes (9): Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132)., Invalid date format raises exception (line 132). (+1 more) +### Community 544 - "Community 544" +Cohesion: 0.18 +Nodes (11): client(), TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with stocks router + verifyAPIKey + getCurrentUser overrides., TestClient with all routers mounted — no lifespan (no DB/service init). O (+3 more) + ### Community 545 - "Community 545" Cohesion: 0.29 Nodes (7): code:python (def test_split_cliff_no_fake_loss_on_adjusted_series(monkeyp), code:python (def test_snapshot_includes_received_and_cash_gain(dbSession,), code:python (def test_history_merges_dividend_receipts(dbSession, sampleU), code:python (def test_ex_div_methodology_decides_received_stacking(dbSess), code:python (def ex_div_smoothing_verdict(padrao_before: float, padrao_af), code:bash (git add main/app/wallet/manager.py main/controller/wallet_co), Task 12: Split-cliff regression test + snapshot/history dividend extension + final gate ### Community 546 - "Community 546" -Cohesion: 0.23 -Nodes (9): Same input → same hash., Different inputs → different hashes., Returns 32-char hex string., TestContentHash, ALL(), content_hash(), contentHash(), MD5 hash for change detection. (+1 more) +Cohesion: 0.29 +Nodes (6): GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422., GET /cotations without search returns 422. ### Community 547 - "Community 547" Cohesion: 0.33 @@ -1951,42 +1974,26 @@ Nodes (3): Current code (exact), Lane contracts (interfaces between lanes), Vect Cohesion: 0.5 Nodes (4): code:python (import pytest), code:python (import logging), code:bash (git add main/app/wallet/prices.py tests/test_wallet_prices.p), Task 6: Price client — one batched STOCKS_API fetch per snapshot -### Community 560 - "Community 560" -Cohesion: 0.47 -Nodes (5): create_memory(), createMemory(), _downloadModel(), embed(), getEmbeddingModel() - ### Community 561 - "Community 561" -Cohesion: 0.09 -Nodes (17): client(), pytest_configure(), TestClient with all routers mounted — no lifespan (no DB/service init). O, Set required env vars before test collection. config.py eagerly instantia, Reset slowapi in-memory rate limiter between every test., Set required env vars before test collection. config.py eagerly instantia, TestClient with all routers mounted — no lifespan (no DB/service init). O, TestClient with all routers mounted — no lifespan (no DB/service init). O (+9 more) - -### Community 562 - "Community 562" -Cohesion: 0.18 -Nodes (10): execute_code(), list_files(), Execute Python code in an isolated sandbox. Use for quantitative analysis, s, Read a file from the workspace. Args: path: Path to the file (e.g.,, Write a file to the workspace. Use this to save data files (CSV, JSON, scrip, List files in the workspace directory. Args: path: Directory path t, Get a download link for a workspace file to share with the user. Use this w, read_file() (+2 more) +Cohesion: 0.1 +Nodes (9): Pytest Testing, pytest_configure(), Set required env vars before test collection. config.py eagerly instantia, Reset slowapi in-memory rate limiter between every test., Set required env vars before test collection. config.py eagerly instantia, Set required env vars before test collection. config.py eagerly instantia, _reset_rate_limiter(), Tests for main/utils/http_session.py — covers all branches. (+1 more) ### Community 563 - "Community 563" -Cohesion: 0.2 -Nodes (9): Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., Covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: UserManager.getC, Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval. (+1 more) +Cohesion: 0.33 +Nodes (5): Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Every function in TOOL_REGISTRY must have Gemini-safe signatures. Custom cl, Regression: HarnessState must never leak into tool signatures., Regression: HarnessState must never leak into tool signatures., TestGeminiCompatibility ### Community 564 - "Community 564" -Cohesion: 0.25 -Nodes (35): Base, BaseModel, EarningsSync, WalletCreate, OrunmilaSandbox, Earning, Holding, Snapshot (+27 more) +Cohesion: 0.27 +Nodes (33): Base, BaseModel, EarningsSync, WalletCreate, Earning, Holding, Snapshot, Target (+25 more) ### Community 565 - "Community 565" Cohesion: 0.33 Nodes (6): Tests covering key.py lines 48-66., Tests covering key.py lines 48-66., Tests covering key.py lines 48-66., Tests covering key.py lines 48-66., Tests covering key.py lines 48-66., TestCreateKey -### Community 566 - "Community 566" -Cohesion: 0.29 -Nodes (6): Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., Covers line 18: GET /stocks/health., TestStocksApiHealth - ### Community 567 - "Community 567" Cohesion: 0.14 Nodes (11): Integration tests for the verifyAPIKey function., Test successful API key verification., Integration tests for the verifyAPIKey function., Test API key verification when quota is exceeded., Test API key verification with invalid key., Test API key verification with missing key., Test API key verification with invalid key., Test that API key system can be disabled. (+3 more) -### Community 568 - "Community 568" -Cohesion: 0.08 -Nodes (6): Store a value in state. Marks state as changed for context injection., Verify the actual async tool functions have correct signatures., TOOL_REGISTRY pattern must work correctly., TestMemoryToolFunctions, TestToolRegistry, TestMemoryToolFunctions - ### Community 569 - "Community 569" Cohesion: 0.39 Nodes (8): _build_error_response(), buildErrorResponse(), generic_exception_handler(), genericExceptionHandler(), http_exception_handler(), httpExceptionHandler(), validation_exception_handler(), validationExceptionHandler() @@ -2000,24 +2007,28 @@ Cohesion: 0.25 Nodes (8): code:python (TIPO_MAP = {"Dividendo": "Div", "JCP": "JSCP", "Juros Sobre ), code:python (from freezegun import freeze_time), code:bash (git add main/service/wallet_service.py main/controller/walle), code:python (def _flat_series_with_one_div(url, params=None, headers=None), code:bash (git add main/service/wallet_service.py main/controller/walle), Goal 2 — P2 earnings + performance (starts only after Goal 1 complete), Task P2-2: Earnings sync (accrue + transition, pull-based), Task P2-3: Performance windows (on-demand reconstruction, no new table) ### Community 572 - "Community 572" -Cohesion: 0.24 -Nodes (5): lifespan(), status(), checkDatabaseConnection(), checkSingleDb(), runMigrations() +Cohesion: 0.33 +Nodes (5): replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34). ### Community 573 - "Community 573" Cohesion: 0.29 Nodes (6): Global Constraints, Goal 3 — P3+ assist + narration (starts only after Goal 2 complete), Mansa Wallet Implementation Plan (P1 + P2 + P3+), Task P3-0: Write the P3+ detailed plan (required before P3-1/P3-2), Task P3-1: Ratings-assist tuning (gated on the P3+ plan), Task P3-2: Orunmila narration tools (gated on the P3+ plan) ### Community 574 - "Community 574" -Cohesion: 0.06 -Nodes (30): memoryMaintenance(), create_memories(), Zero access but score still above threshold → not archived., Even with low score, if accessed → not archived., Even with low score, if accessed → not archived., Already archived memories are skipped., Already archived memories are skipped., Decay happens first, then archive check with new scores. (+22 more) +Cohesion: 0.12 +Nodes (13): create_memories(), Decay happens first, then archive check with new scores., Decay happens first, then archive check with new scores., 89 days with low score → not archived (need > 90)., 89 days with low score → not archived (need > 90)., Helper to create memories with controlled baseScore, lastAccessedAt, accessCount, Helper to create memories with controlled baseScore, lastAccessedAt, accessCount, Decay applies to ALL active memories, not just accessed ones. (+5 more) ### Community 575 - "Community 575" Cohesion: 0.13 Nodes (8): create_entry_route(), delete_entry_route(), list_earnings_route(), list_entries_route(), serialize_earning(), serialize_entry(), serialize_holding(), update_entry_route() +### Community 576 - "Community 576" +Cohesion: 0.1 +Nodes (5): FastAPI, Tests for inline pagination params (used in user + prometheus controllers)., TestPaginationParams, PaginationParams, createWallet() + ### Community 577 - "Community 577" -Cohesion: 0.29 -Nodes (6): Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., Covers line 35: GET /stocks/historical., TestStocksApiHistorical +Cohesion: 0.33 +Nodes (5): Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is. ### Community 578 - "Community 578" Cohesion: 0.29 @@ -2039,10 +2050,6 @@ Nodes (8): 1. Feature inventory + nav structure, 2. User lifecycle end-to-end, 3 Cohesion: 0.13 Nodes (14): 1.1 Functional (per surface; tags: EXISTS = build on it, PARTIAL = half reusable, MISSING = greenfield), 1.2 Non-functional, 1. Requirements, 2. Domain model, 3. API contracts (all under `/api/wallet`; chain: `main/controller/wallet_controller.py` → `main/service/wallet_service.py::` → `main/models/wallet.py::`; auth `Depends(UserManager.getCurrentUser)` + `Depends(getSession)` throughout), 4. Phased build plan (writing-plans: each phase independently reviewable; reviewer PASS per phase), 5. Risks / assumptions (honest flags carried over — do not treat as fact), 6.1 DB & migrations (`user_db`) — READY, 2 actions (+6 more) -### Community 584 - "Community 584" -Cohesion: 0.43 -Nodes (4): _extractCredential(), _introspectUrl(), introspectUser(), _serviceToken() - ### Community 585 - "Community 585" Cohesion: 0.33 Nodes (5): Environment, Standing rules (do not re-derive), Swarm protocol (all three goals), The three goals (sequential — one at a time, never parallel), Wallet Orchestrator Prompt (P1 + P2 + P3+ — one goal per scope) @@ -2060,16 +2067,20 @@ Cohesion: 0.33 Nodes (5): Tests for optimized search filtering, Tests for optimized search filtering, Filter should use ticker index for O(1) lookup, Filter should use ticker index for O(1) lookup, TestFilterBySearchTerms ### Community 589 - "Community 589" -Cohesion: 0.29 -Nodes (6): Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers line 16: empty password raises ValueError. +Cohesion: 0.22 +Nodes (7): Integration tests for all query optimizations, Integration tests for all query optimizations, All optimizations should be implemented, All optimizations should be implemented, Query filter should use ticker index, Query filter should use ticker index, TestQueryOptimization + +### Community 590 - "Community 590" +Cohesion: 0.43 +Nodes (4): _extractCredential(), _introspectUrl(), introspectUser(), _serviceToken() ### Community 591 - "Community 591" Cohesion: 0.4 Nodes (4): 0. Purpose and constraints, Next actions (not in scope here), nginx Scaling Plan — reverse proxy + response cache for `/stocks`, and the multi-server evolution, Open decisions (blocking or product-owned) ### Community 592 - "Community 592" -Cohesion: 0.29 -Nodes (6): Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 48-49: jwt.ExpiredSignatureError. +Cohesion: 0.4 +Nodes (4): getGoogleSSO(), googleLogin(), test_get_google_sso_default_redirect(), test_get_google_sso_with_redirect() ### Community 593 - "Community 593" Cohesion: 0.5 @@ -2107,21 +2118,17 @@ Nodes (5): code:python (def test_permission_enum_values():), code:python (class Cohesion: 0.4 Nodes (5): code:python (import requests), code:python (import os), code:python (def fetchCachedClose(ticker: str) -> float | None:), code:bash (git add main/service/wallet_service.py main/controller/walle), Task 7: Positions — live-price join over HTTP -### Community 602 - "Community 602" -Cohesion: 0.29 -Nodes (6): Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation. - ### Community 603 - "Community 603" -Cohesion: 0.47 -Nodes (3): TestCleanup, cleanup(), Close the main thread's session at interpreter shutdown. +Cohesion: 0.29 +Nodes (6): Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers lines 48-49: user not in DB., Covers line 16: empty password raises ValueError. ### Community 604 - "Community 604" -Cohesion: 0.4 -Nodes (5): initialize(), P5: register the scraper cron jobs on the shared scheduler. Kept in this, registerScraperJobs(), runScraper(), ScraperService +Cohesion: 0.29 +Nodes (6): Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 65-67: unexpected exception., Covers lines 48-49: jwt.ExpiredSignatureError. ### Community 605 - "Community 605" -Cohesion: 0.33 -Nodes (5): replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34)., replaceNan handles direct float NaN values (line 34). +Cohesion: 0.4 +Nodes (5): execute_code(), Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis,, Execute Python code in an isolated sandbox. Use for quantitative analysis, ### Community 606 - "Community 606" Cohesion: 0.2 @@ -2135,29 +2142,33 @@ Nodes (4): code:python (from fastapi import Depends, FastAPI), code:python (impo Cohesion: 0.5 Nodes (4): code:python (from main.models.wallet import Earning), code:python (class Earning(Base):), code:bash (git add main/models/wallet.py migrations/versions/_wall), Task P2-1: `Earning` model + second migration revision -### Community 610 - "Community 610" +### Community 609 - "Community 609" Cohesion: 0.33 -Nodes (6): Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., Covers line 47: GET /stocks/fundamental., TestStocksApiFundamental +Nodes (3): batchCosineSimilarity(), contentHash(), normalizeRows() + +### Community 610 - "Community 610" +Cohesion: 0.2 +Nodes (9): Covers lines 66, 68-72, 74: GET /user/sessions., Covers lines 66, 68-72, 74: GET /user/sessions., Covers lines 66, 68-72, 74: full sessions listing., Covers lines 66, 68-72, 74: full sessions listing., Covers lines 66, 68-72, 74: GET /user/sessions., Covers lines 66, 68-72, 74: full sessions listing., Covers lines 66, 68-72, 74: GET /user/sessions., Covers lines 66, 68-72, 74: full sessions listing. (+1 more) ### Community 611 - "Community 611" -Cohesion: 0.5 -Nodes (4): code:python (from main.models.base import Base), code:python (from sqlalchemy import Column, Date, Enum, ForeignKey, Integ), code:bash (git add main/models/wallet.py tests/test_wallet_models.py), Task 2: Wallet ORM models (5 tables, `user_db`) +Cohesion: 0.29 +Nodes (6): Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation., Covers lines 37-38, 46, 51, 58 (sessionId is None): skips session validation. ### Community 612 - "Community 612" Cohesion: 0.67 Nodes (3): code:python (def test_summary_math_and_snapshot_upsert(dbSession, monkeyp), code:bash (git add main/service/wallet_service.py main/controller/walle), Task 8: Summary + snapshots + allocation + targets + ratings ### Community 613 - "Community 613" -Cohesion: 0.07 -Nodes (22): Tests for connection pool configuration, Tests for connection pool configuration, Stocks engine should have optimized pool settings, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Tests for lazy JSON deserialization, Query manager should have deserialize method, Query manager should have deserialize method (+14 more) +Cohesion: 0.11 +Nodes (15): Tests for connection pool configuration, Tests for connection pool configuration, Stocks engine should have optimized pool settings, Stocks engine should have optimized pool settings, Tests for lazy JSON deserialization, Tests for lazy JSON deserialization, Query manager should have deserialize method, Query manager should have deserialize method (+7 more) ### Community 614 - "Community 614" Cohesion: 0.33 -Nodes (5): Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is., Non-JSON-dict/list string is left as-is. +Nodes (6): Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., TestAddRoleToUser ### Community 616 - "Community 616" -Cohesion: 0.33 -Nodes (6): Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 13, 17, 19-20, 22-27: UserManager.addRoleToUser., Covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval., TestAddRoleToUser +Cohesion: 0.4 +Nodes (5): list_files(), List files in the workspace directory. Args: path: Directory pat, List files in the workspace directory. Args: path: Directory pat, List files in the workspace directory. Args: path: Directory pat, List files in the workspace directory. Args: path: Directory pat ### Community 617 - "Community 617" Cohesion: 0.33 @@ -2169,7 +2180,7 @@ Nodes (16): baseFrame(), deserializeJsonColumns(), envelope(), fetchLivePayload( ### Community 620 - "Community 620" Cohesion: 0.33 -Nodes (5): Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 45-51: verifyAccessToken with expired and invalid tokens., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 48-49: jwt.ExpiredSignatureError., Covers lines 48-49: jwt.ExpiredSignatureError. +Nodes (5): Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers line 27: user already has the role., Covers lines 42-44: session validation fails. ### Community 621 - "Community 621" Cohesion: 0.33 @@ -2180,46 +2191,46 @@ Cohesion: 0.5 Nodes (4): code:python ("""add wallet_holdings and wallet_lots tables), code:python (import main.models.wallet), code:bash (git add migrations/versions/wallet_tables_20260904_add_walle), Task 2: Alembic migration for wallet tables ### Community 625 - "Community 625" -Cohesion: 0.67 -Nodes (3): checkServiceConnection — success, not found, errors., checkServiceConnection — success, not found, errors., TestCheckServiceConnection +Cohesion: 0.33 +Nodes (5): Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails., Covers lines 42-44: session validation fails. ### Community 627 - "Community 627" -Cohesion: 0.33 -Nodes (6): makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., TestMakeChatIncludesMemoryTools +Cohesion: 0.29 +Nodes (6): Exercises the tzinfo-is-None branch (line 144-148)., Exercises the tzinfo-is-None branch (line 144-148)., Exercises the tzinfo-is-None branch (line 144-148)., Exercises the tzinfo-is-None branch (line 144-148)., Exercises the tzinfo-is-None branch (line 144-148)., Exercises the tzinfo-is-None branch (line 144-148). ### Community 628 - "Community 628" -Cohesion: 0.4 -Nodes (5): Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., Read a file from the workspace. Args: path: Path to the file (e., read_file() - -### Community 629 - "Community 629" -Cohesion: 0.67 -Nodes (3): checkMySqlConnection — success, errors, engine=None paths., checkMySqlConnection — success, errors, engine=None paths., TestCheckMySqlConnection +Cohesion: 0.29 +Nodes (6): Exercises the expiresAt-is-None branch (line 143)., Exercises the expiresAt-is-None branch (line 143)., Exercises the expiresAt-is-None branch (line 143)., Exercises the expiresAt-is-None branch (line 143)., Exercises the expiresAt-is-None branch (line 143)., Exercises the expiresAt-is-None branch (line 143). ### Community 630 - "Community 630" -Cohesion: 0.67 -Nodes (3): countTokens(), _get_tokenizer(), Count tokens using Gemini's local tokenizer. Accurate for Portuguese. +Cohesion: 0.33 +Nodes (6): makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., makeChat must include MEMORY_TOOLS alongside MCP sessions., TestMakeChatIncludesMemoryTools -### Community 631 - "Community 631" -Cohesion: 0.67 -Nodes (3): get_wallet_rebalance(), Show weight-share rebalance deltas per ticker (buy/sell/hold). Read-only:, Show weight-share rebalance deltas per ticker (buy/sell/hold). Read-only: +### Community 632 - "Community 632" +Cohesion: 0.5 +Nodes (3): getWalletIdentity(), requireWalletOwnership(), resolveRawToken() + +### Community 633 - "Community 633" +Cohesion: 0.5 +Nodes (4): code:python (def test_compra_average_includes_costs(dbSession):), code:python (from datetime import date), code:bash (git add main/service/wallet_service.py main/controller/walle), Task 6: Entries ledger + holdings recalc (avg-price engine) ### Community 634 - "Community 634" Cohesion: 0.4 Nodes (5): Category 8: Testing Gaps (MEDIUM), Issue 8.1 — No integration tests for full request lifecycle, Issue 8.2 — No tests for scraper, stocks query, or cache, Issue 8.3 — No tests for Google OAuth callback, Issue 8.4 — No tests for session cleanup ## Knowledge Gaps -- **3490 isolated node(s):** `$schema`, `style`, `rsc`, `tsx`, `config` (+3485 more) +- **3493 isolated node(s):** `$schema`, `style`, `rsc`, `tsx`, `config` (+3488 more) These have ≤1 connection - possible missing edges or undocumented components. -- **242 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. +- **243 thin communities (<3 nodes) omitted from report** — run `graphify query` to explore isolated nodes. ## Suggested Questions _Questions this graph is uniquely positioned to answer:_ -- **Why does `FastAPI` connect `Community 528` to `Community 129`, `Community 519`, `Community 18`, `Community 147`, `Community 536`, `Community 152`, `Community 26`, `Community 157`, `Community 33`, `Community 34`, `Community 40`, `Community 43`, `Community 54`, `Community 569`, `Community 58`, `Community 572`, `Community 575`, `Community 576`, `Community 67`, `Community 68`, `Community 71`, `Community 584`, `Community 73`, `Community 84`, `Community 477`, `Community 101`, `Community 504`, `Community 618`, `Community 234`, `Community 491`, `Community 500`, `Community 501`, `Community 502`, `Community 120`?** - _High betweenness centrality (0.060) - this node is a cross-community bridge._ -- **Why does `Pytest Testing` connect `Community 49` to `Authentication Core`, `Frontend Components`, `Community 129`, `Data Models & Types`, `Community 135`, `Community 138`, `Community 140`, `Community 528`, `Community 18`, `Community 147`, `Community 21`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 29`, `Community 32`, `Community 33`, `Community 40`, `Community 44`, `Community 561`, `Community 51`, `Community 59`, `Community 188`, `Community 61`, `Community 574`, `Community 576`, `Community 72`, `Community 586`, `Community 590`, `Community 595`, `Community 599`, `Community 93`, `Community 477`, `Community 100`, `Community 613`, `Community 102`, `Community 504`, `Community 107`, `Community 491`, `Community 500`, `Community 503`, `Community 120`?** - _High betweenness centrality (0.059) - this node is a cross-community bridge._ -- **Why does `Config` connect `Community 564` to `Frontend Components`, `Community 102`, `Community 122`, `Community 137`, `Community 105`, `Community 140`, `Community 45`, `Community 524`, `Community 80`, `Community 29`, `Community 538`, `Community 87`, `Community 474`, `Community 604`, `Community 189`?** +- **Why does `Pytest Testing` connect `Community 561` to `Authentication Core`, `Frontend Components`, `Community 129`, `Data Models & Types`, `Community 131`, `Community 135`, `Community 138`, `Community 140`, `Community 527`, `Community 18`, `Community 147`, `Community 24`, `Community 25`, `Community 26`, `Community 27`, `Community 29`, `Community 32`, `Community 33`, `Community 40`, `Community 44`, `Community 49`, `Community 51`, `Community 59`, `Community 188`, `Community 61`, `Community 574`, `Community 576`, `Community 72`, `Community 586`, `Community 595`, `Community 599`, `Community 93`, `Community 477`, `Community 98`, `Community 100`, `Community 613`, `Community 102`, `Community 231`, `Community 504`, `Community 107`, `Community 491`, `Community 500`, `Community 503`, `Community 120`?** + _High betweenness centrality (0.070) - this node is a cross-community bridge._ +- **Why does `FastAPI` connect `Community 576` to `Community 129`, `Community 528`, `Community 18`, `Community 147`, `Community 152`, `Community 26`, `Community 33`, `Community 34`, `Community 40`, `Community 172`, `Community 54`, `Community 569`, `Community 58`, `Community 59`, `Community 575`, `Community 67`, `Community 68`, `Community 197`, `Community 71`, `Community 73`, `Community 590`, `Community 84`, `Community 120`, `Community 477`, `Community 98`, `Community 101`, `Community 504`, `Community 618`, `Community 107`, `Community 234`, `Community 491`, `Community 112`, `Community 500`, `Community 501`, `Community 632`?** + _High betweenness centrality (0.063) - this node is a cross-community bridge._ +- **Why does `UserManager` connect `Community 45` to `Prometheus Agent`, `Prometheus Memory`, `Community 140`, `Community 141`, `User Roles & Permissions`, `Community 528`, `Community 529`, `Community 148`, `Community 22`, `Community 28`, `Community 37`, `Community 47`, `Community 565`, `Community 58`, `Community 61`, `Community 63`, `Community 194`, `Community 72`, `Community 596`, `Community 610`, `Community 99`, `Community 614`, `Community 493`, `Community 112`, `Community 498`, `Community 114`, `Community 120`, `Community 511`?** _High betweenness centrality (0.034) - this node is a cross-community bridge._ - **Are the 72 inferred relationships involving `StocksCacheManager` (e.g. with `TestStocksCacheManager` and `TestVerifyAPIKey`) actually correct?** _`StocksCacheManager` has 72 INFERRED edges - model-reasoned connections that need verification._ diff --git a/graphify-out/graph.json b/graphify-out/graph.json index bb8a8c2e..da973be1 100644 --- a/graphify-out/graph.json +++ b/graphify-out/graph.json @@ -264,7 +264,7 @@ "source_file": "run.py", "source_location": "L1", "id": "run_py", - "community": 572, + "community": 59, "norm_label": "run.py" }, { @@ -273,7 +273,7 @@ "source_file": "run.py", "source_location": "L29", "id": "server_run_lifespan", - "community": 572, + "community": 59, "norm_label": "lifespan()" }, { @@ -282,7 +282,7 @@ "source_file": "run.py", "source_location": "L82", "id": "server_run_health", - "community": 572, + "community": 59, "norm_label": "health()" }, { @@ -291,16 +291,16 @@ "source_file": "run.py", "source_location": "L87", "id": "server_run_status", - "community": 572, + "community": 59, "norm_label": "status()" }, { "label": "triggerScraper()", "file_type": "code", "source_file": "run.py", - "source_location": "L121", + "source_location": "L122", "id": "server_run_triggerscraper", - "community": 572, + "community": 59, "norm_label": "triggerscraper()" }, { @@ -2190,7 +2190,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L1", "id": "main_app_authentication_authentication_py", - "community": 43, + "community": 112, "norm_label": "authentication.py" }, { @@ -2199,7 +2199,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L14", "id": "authentication_authentication_authenticationmanager", - "community": 45, + "community": 112, "norm_label": "authenticationmanager" }, { @@ -2217,7 +2217,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L51", "id": "authentication_authentication_authenticategoogleuser", - "community": 43, + "community": 112, "norm_label": "authenticategoogleuser()" }, { @@ -2235,7 +2235,7 @@ "source_file": "main/app/authentication/authentication.py", "source_location": "L79", "id": "authentication_authentication_resolveuniqueusername", - "community": 43, + "community": 112, "norm_label": "resolveuniqueusername()" }, { @@ -2253,7 +2253,7 @@ "source_file": "main/app/authentication/introspect.py", "source_location": "L1", "id": "main_app_authentication_introspect_py", - "community": 528, + "community": 172, "norm_label": "introspect.py" }, { @@ -2262,7 +2262,7 @@ "source_file": "main/app/authentication/introspect.py", "source_location": "L14", "id": "authentication_introspect_introspecttoken", - "community": 528, + "community": 172, "norm_label": "introspecttoken()" }, { @@ -2271,7 +2271,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L1", "id": "main_app_authentication_session_py", - "community": 44, + "community": 523, "norm_label": "session.py" }, { @@ -2280,7 +2280,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L13", "id": "authentication_session_parsedevicefields", - "community": 44, + "community": 523, "norm_label": "parsedevicefields()" }, { @@ -2289,7 +2289,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L30", "id": "authentication_session_sessionmanager", - "community": 29, + "community": 112, "norm_label": "sessionmanager" }, { @@ -2298,7 +2298,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L32", "id": "authentication_session_createsession", - "community": 44, + "community": 523, "norm_label": "createsession()" }, { @@ -2307,7 +2307,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L68", "id": "authentication_session_getusersessions", - "community": 44, + "community": 523, "norm_label": "getusersessions()" }, { @@ -2316,7 +2316,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L73", "id": "authentication_session_getsessionbyid", - "community": 44, + "community": 523, "norm_label": "getsessionbyid()" }, { @@ -2325,7 +2325,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L80", "id": "authentication_session_getcurrentsession", - "community": 44, + "community": 523, "norm_label": "getcurrentsession()" }, { @@ -2334,7 +2334,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L92", "id": "authentication_session_revokesession", - "community": 44, + "community": 523, "norm_label": "revokesession()" }, { @@ -2343,7 +2343,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L109", "id": "authentication_session_revokeallsessions", - "community": 44, + "community": 523, "norm_label": "revokeallsessions()" }, { @@ -2352,7 +2352,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L122", "id": "authentication_session_revokeallexcept", - "community": 44, + "community": 523, "norm_label": "revokeallexcept()" }, { @@ -2361,7 +2361,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L132", "id": "authentication_session_updatelastactive", - "community": 44, + "community": 523, "norm_label": "updatelastactive()" }, { @@ -2370,7 +2370,7 @@ "source_file": "main/app/authentication/session.py", "source_location": "L142", "id": "authentication_session_validatesession", - "community": 44, + "community": 523, "norm_label": "validatesession()" }, { @@ -2379,7 +2379,7 @@ "source_file": "main/app/authentication/sso.py", "source_location": "L1", "id": "main_app_authentication_sso_py", - "community": 58, + "community": 592, "norm_label": "sso.py" }, { @@ -2388,7 +2388,7 @@ "source_file": "main/app/authentication/sso.py", "source_location": "L6", "id": "authentication_sso_getgooglesso", - "community": 58, + "community": 592, "norm_label": "getgooglesso()" }, { @@ -2397,7 +2397,7 @@ "source_file": "main/app/authentication/util.py", "source_location": "L1", "id": "main_app_authentication_util_py", - "community": 528, + "community": 107, "norm_label": "util.py" }, { @@ -2433,7 +2433,7 @@ "source_file": "main/app/authentication/util.py", "source_location": "L44", "id": "authentication_util_verifyaccesstoken", - "community": 528, + "community": 172, "norm_label": "verifyaccesstoken()" }, { @@ -2487,7 +2487,7 @@ "source_file": "main/app/orunmila/agent.py", "source_location": "L208", "id": "orunmila_agent_orunmila", - "community": 45, + "community": 502, "norm_label": "orunmila" }, { @@ -2532,7 +2532,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L1", "id": "main_app_orunmila_chat_py", - "community": 231, + "community": 502, "norm_label": "chat.py" }, { @@ -2541,7 +2541,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L13", "id": "orunmila_chat_orunmilachatmanager", - "community": 45, + "community": 502, "norm_label": "orunmilachatmanager" }, { @@ -2550,7 +2550,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L15", "id": "orunmila_chat_getusersessions", - "community": 231, + "community": 502, "norm_label": "getusersessions()" }, { @@ -2559,7 +2559,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L34", "id": "orunmila_chat_createsession", - "community": 231, + "community": 502, "norm_label": "createsession()" }, { @@ -2568,7 +2568,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L42", "id": "orunmila_chat_updatesessiontitle", - "community": 231, + "community": 502, "norm_label": "updatesessiontitle()" }, { @@ -2577,7 +2577,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L53", "id": "orunmila_chat_appendhistory", - "community": 231, + "community": 502, "norm_label": "appendhistory()" }, { @@ -2586,7 +2586,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L72", "id": "orunmila_chat_gethistory", - "community": 231, + "community": 502, "norm_label": "gethistory()" }, { @@ -2595,7 +2595,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L93", "id": "orunmila_chat_deletesession", - "community": 231, + "community": 502, "norm_label": "deletesession()" }, { @@ -2604,7 +2604,7 @@ "source_file": "main/app/orunmila/chat.py", "source_location": "L107", "id": "orunmila_chat_verifysessionownership", - "community": 231, + "community": 502, "norm_label": "verifysessionownership()" }, { @@ -2937,7 +2937,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L64", "id": "orunmila_memory_memorycandidate", - "community": 45, + "community": 502, "norm_label": "memorycandidate" }, { @@ -3036,7 +3036,7 @@ "source_file": "main/app/orunmila/memory.py", "source_location": "L194", "id": "orunmila_memory_orunmilamemory", - "community": 45, + "community": 502, "norm_label": "orunmilamemory" }, { @@ -3171,7 +3171,7 @@ "source_file": "main/app/orunmila/sandbox.py", "source_location": "L51", "id": "orunmila_sandbox_sandboxmanager", - "community": 564, + "community": 234, "norm_label": "sandboxmanager" }, { @@ -3441,7 +3441,7 @@ "source_file": "main/app/orunmila/vector.py", "source_location": "L51", "id": "orunmila_vector_contenthash", - "community": 88, + "community": 609, "norm_label": "contenthash()" }, { @@ -3558,7 +3558,7 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L1", "id": "main_app_orunmila_tools_sandbox_py", - "community": 562, + "community": 234, "norm_label": "sandbox.py" }, { @@ -3567,7 +3567,7 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L11", "id": "tools_sandbox_execute_code", - "community": 562, + "community": 234, "norm_label": "execute_code()" }, { @@ -3576,7 +3576,7 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L32", "id": "tools_sandbox_read_file", - "community": 562, + "community": 234, "norm_label": "read_file()" }, { @@ -3585,7 +3585,7 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L46", "id": "tools_sandbox_write_file", - "community": 562, + "community": 234, "norm_label": "write_file()" }, { @@ -3594,7 +3594,7 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L62", "id": "tools_sandbox_list_files", - "community": 562, + "community": 234, "norm_label": "list_files()" }, { @@ -3603,7 +3603,7 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L75", "id": "tools_sandbox_serve_file", - "community": 562, + "community": 234, "norm_label": "serve_file()" }, { @@ -3612,7 +3612,7 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L12", "id": "tools_sandbox_rationale_12", - "community": 562, + "community": 234, "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis, s" }, { @@ -3621,7 +3621,7 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L33", "id": "tools_sandbox_rationale_33", - "community": 562, + "community": 234, "norm_label": "read a file from the workspace. args: path: path to the file (e.g.," }, { @@ -3630,7 +3630,7 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L47", "id": "tools_sandbox_rationale_47", - "community": 562, + "community": 234, "norm_label": "write a file to the workspace. use this to save data files (csv, json, scrip" }, { @@ -3639,7 +3639,7 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L63", "id": "tools_sandbox_rationale_63", - "community": 562, + "community": 234, "norm_label": "list files in the workspace directory. args: path: directory path t" }, { @@ -3648,7 +3648,7 @@ "source_file": "main/app/orunmila/tools/sandbox.py", "source_location": "L76", "id": "tools_sandbox_rationale_76", - "community": 562, + "community": 234, "norm_label": "get a download link for a workspace file to share with the user. use this w" }, { @@ -3718,7 +3718,7 @@ "label": "wallet_rebalance()", "file_type": "code", "source_file": "main/app/orunmila/tools/wallet.py", - "source_location": "L187", + "source_location": "L185", "id": "tools_wallet_wallet_rebalance", "community": 101, "norm_label": "wallet_rebalance()" @@ -3763,8 +3763,8 @@ "label": "Compute time-weighted return, volatility, and dividends for a wallet or ticker.", "file_type": "rationale", "source_file": "main/app/orunmila/tools/wallet.py", - "source_location": "L151", - "id": "tools_wallet_rationale_151", + "source_location": "L149", + "id": "tools_wallet_rationale_149", "community": 101, "norm_label": "compute time-weighted return, volatility, and dividends for a wallet or ticker." }, @@ -3772,8 +3772,8 @@ "label": "Show weight-share rebalance deltas per ticker (buy/sell/hold). Read-only: n", "file_type": "rationale", "source_file": "main/app/orunmila/tools/wallet.py", - "source_location": "L188", - "id": "tools_wallet_rationale_188", + "source_location": "L186", + "id": "tools_wallet_rationale_186", "community": 101, "norm_label": "show weight-share rebalance deltas per ticker (buy/sell/hold). read-only: n" }, @@ -3790,7 +3790,7 @@ "label": "dispatchToolCall()", "file_type": "code", "source_file": "main/app/orunmila/tools/__init__.py", - "source_location": "L28", + "source_location": "L35", "id": "tools_init_dispatchtoolcall", "community": 165, "norm_label": "dispatchtoolcall()" @@ -4080,7 +4080,7 @@ "source_file": "main/app/stocks_api/cache.py", "source_location": "L47", "id": "stocks_api_cache_stockscachemanager_cachescheduler", - "community": 222, + "community": 82, "norm_label": ".cachescheduler()" }, { @@ -4440,7 +4440,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L17", "id": "stocks_api_util_dedupabbrev", - "community": 73, + "community": 186, "norm_label": "dedupabbrev()" }, { @@ -4449,7 +4449,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L26", "id": "stocks_api_util_autoabbreviate", - "community": 73, + "community": 186, "norm_label": "autoabbreviate()" }, { @@ -4458,7 +4458,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L49", "id": "stocks_api_util_generateabbreviations", - "community": 73, + "community": 186, "norm_label": "generateabbreviations()" }, { @@ -4494,7 +4494,7 @@ "source_file": "main/app/stocks_api/util.py", "source_location": "L98", "id": "stocks_api_util_detectnestedfields", - "community": 73, + "community": 186, "norm_label": "detectnestedfields()" }, { @@ -4503,7 +4503,7 @@ "source_file": "main/app/user/user.py", "source_location": "L1", "id": "main_app_user_user_py", - "community": 519, + "community": 528, "norm_label": "user.py" }, { @@ -4521,7 +4521,7 @@ "source_file": "main/app/user/user.py", "source_location": "L17", "id": "user_user_getroleslist", - "community": 519, + "community": 528, "norm_label": "getroleslist()" }, { @@ -4530,7 +4530,7 @@ "source_file": "main/app/user/user.py", "source_location": "L23", "id": "user_user_getcurrentuser", - "community": 519, + "community": 528, "norm_label": "getcurrentuser()" }, { @@ -4674,7 +4674,7 @@ "source_file": "main/app/wallet/market_data.py", "source_location": "L1", "id": "main_app_wallet_market_data_py", - "community": 518, + "community": 535, "norm_label": "market_data.py" }, { @@ -4701,7 +4701,7 @@ "source_file": "main/app/wallet/market_data.py", "source_location": "L48", "id": "wallet_market_data_fetchmarketdividends", - "community": 518, + "community": 535, "norm_label": "fetchmarketdividends()" }, { @@ -4710,7 +4710,7 @@ "source_file": "main/app/wallet/market_data.py", "source_location": "L68", "id": "wallet_market_data_fetchpadraocloses", - "community": 518, + "community": 535, "norm_label": "fetchpadraocloses()" }, { @@ -4719,7 +4719,7 @@ "source_file": "main/app/wallet/performance.py", "source_location": "L1", "id": "main_app_wallet_performance_py", - "community": 518, + "community": 535, "norm_label": "performance.py" }, { @@ -4737,7 +4737,7 @@ "source_file": "main/app/wallet/performance.py", "source_location": "L29", "id": "wallet_performance_cachedperformance", - "community": 518, + "community": 535, "norm_label": "cachedperformance()" }, { @@ -4746,7 +4746,7 @@ "source_file": "main/app/wallet/performance.py", "source_location": "L154", "id": "wallet_performance_getperformance", - "community": 518, + "community": 535, "norm_label": "getperformance()" }, { @@ -4780,7 +4780,7 @@ "label": "weightOf()", "file_type": "code", "source_file": "main/app/wallet/positions.py", - "source_location": "L54", + "source_location": "L47", "id": "wallet_positions_weightof", "community": 482, "norm_label": "weightof()" @@ -4789,7 +4789,7 @@ "label": "pricePass()", "file_type": "code", "source_file": "main/app/wallet/positions.py", - "source_location": "L58", + "source_location": "L51", "id": "wallet_positions_pricepass", "community": 482, "norm_label": "pricepass()" @@ -4798,7 +4798,7 @@ "label": "rebalanceDeltas()", "file_type": "code", "source_file": "main/app/wallet/positions.py", - "source_location": "L80", + "source_location": "L73", "id": "wallet_positions_rebalancedeltas", "community": 482, "norm_label": "rebalancedeltas()" @@ -4807,7 +4807,7 @@ "label": "getPositions()", "file_type": "code", "source_file": "main/app/wallet/positions.py", - "source_location": "L96", + "source_location": "L88", "id": "wallet_positions_getpositions", "community": 482, "norm_label": "getpositions()" @@ -4816,29 +4816,11 @@ "label": "getRebalance()", "file_type": "code", "source_file": "main/app/wallet/positions.py", - "source_location": "L141", + "source_location": "L133", "id": "wallet_positions_getrebalance", "community": 482, "norm_label": "getrebalance()" }, - { - "label": "XANGO quality score per ticker (0-100 scale). One fundamental read per", - "file_type": "rationale", - "source_file": "main/app/wallet/positions.py", - "source_location": "L23", - "id": "wallet_positions_rationale_23", - "community": 637, - "norm_label": "xango quality score per ticker (0-100 scale). one fundamental read per" - }, - { - "label": "Weight-share deltas on backend floats: target_i = w_i/\u03a3w, targetEquity = target_", - "file_type": "rationale", - "source_file": "main/app/wallet/positions.py", - "source_location": "L83", - "id": "wallet_positions_rationale_83", - "community": 626, - "norm_label": "weight-share deltas on backend floats: target_i = w_i/\u03c3w, targetequity = target_" - }, { "label": "summary.py", "file_type": "code", @@ -4917,7 +4899,7 @@ "source_file": "main/app/wallet/wallets.py", "source_location": "L1", "id": "main_app_wallet_wallets_py", - "community": 152, + "community": 576, "norm_label": "wallets.py" }, { @@ -4944,7 +4926,7 @@ "source_file": "main/app/wallet/wallets.py", "source_location": "L20", "id": "wallet_wallets_createwallet", - "community": 152, + "community": 576, "norm_label": "createwallet()" }, { @@ -4953,18 +4935,9 @@ "source_file": "main/app/wallet/wallets.py", "source_location": "L28", "id": "wallet_wallets_listwallets", - "community": 152, + "community": 576, "norm_label": "listwallets()" }, - { - "label": "wallet_service.py", - "file_type": "code", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L1", - "id": "main_app_wallet_wallet_service_py", - "community": 68, - "norm_label": "wallet_service.py" - }, { "label": "authentication_controller.py", "file_type": "code", @@ -5043,7 +5016,7 @@ "source_file": "main/controller/authentication_controller.py", "source_location": "L154", "id": "controller_authentication_controller_introspect", - "community": 528, + "community": 172, "norm_label": "introspect()" }, { @@ -5052,7 +5025,7 @@ "source_file": "main/controller/authentication_controller.py", "source_location": "L180", "id": "controller_authentication_controller_googlelogin", - "community": 58, + "community": 592, "norm_label": "googlelogin()" }, { @@ -5178,7 +5151,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L1", "id": "main_controller_stocksapi_controller_py", - "community": 157, + "community": 197, "norm_label": "stocksapi_controller.py" }, { @@ -5187,7 +5160,7 @@ "source_file": "main/controller/stocksapi_controller.py", "source_location": "L28", "id": "controller_stocksapi_controller_health", - "community": 157, + "community": 197, "norm_label": "health()" }, { @@ -5574,7 +5547,7 @@ "source_file": "main/models/memory.py", "source_location": "L8", "id": "models_memory_orunmilamemory", - "community": 45, + "community": 502, "norm_label": "orunmilamemory" }, { @@ -5592,7 +5565,7 @@ "source_file": "main/models/orunmila.py", "source_location": "L1", "id": "main_models_orunmila_py", - "community": 231, + "community": 502, "norm_label": "orunmila.py" }, { @@ -5601,7 +5574,7 @@ "source_file": "main/models/orunmila.py", "source_location": "L7", "id": "models_orunmila_orunmilasession", - "community": 231, + "community": 502, "norm_label": "orunmilasession" }, { @@ -5619,7 +5592,7 @@ "source_file": "main/models/sandbox.py", "source_location": "L5", "id": "models_sandbox_orunmilasandbox", - "community": 564, + "community": 234, "norm_label": "orunmilasandbox" }, { @@ -5761,7 +5734,7 @@ "label": "Transaction", "file_type": "code", "source_file": "main/models/wallet.py", - "source_location": "L45", + "source_location": "L43", "id": "models_wallet_transaction", "community": 564, "norm_label": "transaction" @@ -5770,7 +5743,7 @@ "label": "Target", "file_type": "code", "source_file": "main/models/wallet.py", - "source_location": "L60", + "source_location": "L58", "id": "models_wallet_target", "community": 564, "norm_label": "target" @@ -5779,7 +5752,7 @@ "label": "Snapshot", "file_type": "code", "source_file": "main/models/wallet.py", - "source_location": "L72", + "source_location": "L70", "id": "models_wallet_snapshot", "community": 564, "norm_label": "snapshot" @@ -5788,7 +5761,7 @@ "label": "Earning", "file_type": "code", "source_file": "main/models/wallet.py", - "source_location": "L89", + "source_location": "L87", "id": "models_wallet_earning", "community": 564, "norm_label": "earning" @@ -5799,7 +5772,7 @@ "source_file": "main/service/authentication_service.py", "source_location": "L1", "id": "main_service_authentication_service_py", - "community": 536, + "community": 222, "norm_label": "authentication_service.py" }, { @@ -5817,7 +5790,7 @@ "source_file": "main/service/authentication_service.py", "source_location": "L7", "id": "service_authentication_service_initialize", - "community": 536, + "community": 222, "norm_label": "initialize()" }, { @@ -5826,7 +5799,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L1", "id": "main_service_orunmila_service_py", - "community": 536, + "community": 222, "norm_label": "orunmila_service.py" }, { @@ -5835,7 +5808,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L23", "id": "service_orunmila_service_memorymaintenance", - "community": 536, + "community": 88, "norm_label": "memorymaintenance()" }, { @@ -5844,7 +5817,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L65", "id": "service_orunmila_service_orunmilaservice", - "community": 536, + "community": 222, "norm_label": "orunmilaservice" }, { @@ -5853,7 +5826,7 @@ "source_file": "main/service/orunmila_service.py", "source_location": "L67", "id": "service_orunmila_service_initialize", - "community": 536, + "community": 222, "norm_label": "initialize()" }, { @@ -5862,7 +5835,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L1", "id": "main_service_scraper_service_py", - "community": 604, + "community": 474, "norm_label": "scraper_service.py" }, { @@ -5871,7 +5844,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L13", "id": "service_scraper_service_runscraper", - "community": 604, + "community": 474, "norm_label": "runscraper()" }, { @@ -5880,7 +5853,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L23", "id": "service_scraper_service_registerscraperjobs", - "community": 604, + "community": 474, "norm_label": "registerscraperjobs()" }, { @@ -5889,7 +5862,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L49", "id": "service_scraper_service_scraperservice", - "community": 604, + "community": 474, "norm_label": "scraperservice" }, { @@ -5898,7 +5871,7 @@ "source_file": "main/service/scraper_service.py", "source_location": "L51", "id": "service_scraper_service_initialize", - "community": 604, + "community": 474, "norm_label": "initialize()" }, { @@ -6015,7 +5988,7 @@ "source_file": "main/service/wallet_service.py", "source_location": "L11", "id": "service_wallet_service_initialize", - "community": 536, + "community": 222, "norm_label": "initialize()" }, { @@ -6024,7 +5997,7 @@ "source_file": "main/utils/connectivity.py", "source_location": "L1", "id": "main_utils_connectivity_py", - "community": 572, + "community": 59, "norm_label": "connectivity.py" }, { @@ -6033,7 +6006,7 @@ "source_file": "main/utils/connectivity.py", "source_location": "L11", "id": "utils_connectivity_checkdatabaseconnection", - "community": 572, + "community": 59, "norm_label": "checkdatabaseconnection()" }, { @@ -6123,7 +6096,7 @@ "source_file": "main/utils/errors.py", "source_location": "L64", "id": "utils_errors_registererrorhandlers", - "community": 493, + "community": 120, "norm_label": "registererrorhandlers()" }, { @@ -6204,7 +6177,7 @@ "source_file": "main/utils/migrator.py", "source_location": "L1", "id": "main_utils_migrator_py", - "community": 572, + "community": 59, "norm_label": "migrator.py" }, { @@ -6213,7 +6186,7 @@ "source_file": "main/utils/migrator.py", "source_location": "L8", "id": "utils_migrator_runmigrations", - "community": 572, + "community": 59, "norm_label": "runmigrations()" }, { @@ -6258,7 +6231,7 @@ "source_file": "main/utils/roles.py", "source_location": "L1", "id": "main_utils_roles_py", - "community": 584, + "community": 590, "norm_label": "roles.py" }, { @@ -6267,7 +6240,7 @@ "source_file": "main/utils/roles.py", "source_location": "L5", "id": "utils_roles_permission", - "community": 45, + "community": 140, "norm_label": "permission" }, { @@ -6285,7 +6258,7 @@ "source_file": "main/utils/roles.py", "source_location": "L15", "id": "utils_roles_all", - "community": 546, + "community": 131, "norm_label": "all()" }, { @@ -6303,7 +6276,7 @@ "source_file": "main/utils/roles.py", "source_location": "L31", "id": "utils_roles_checkaccess", - "community": 584, + "community": 590, "norm_label": "checkaccess()" }, { @@ -6312,7 +6285,7 @@ "source_file": "main/utils/roles.py", "source_location": "L44", "id": "utils_roles_requirepermission", - "community": 584, + "community": 590, "norm_label": "requirepermission()" }, { @@ -6348,7 +6321,7 @@ "source_file": "main/utils/service_manager.py", "source_location": "L1", "id": "main_utils_service_manager_py", - "community": 536, + "community": 59, "norm_label": "service_manager.py" }, { @@ -6357,7 +6330,7 @@ "source_file": "main/utils/service_manager.py", "source_location": "L19", "id": "utils_service_manager_getapp", - "community": 536, + "community": 222, "norm_label": "getapp()" }, { @@ -6366,7 +6339,7 @@ "source_file": "main/utils/service_manager.py", "source_location": "L43", "id": "utils_service_manager_runall", - "community": 536, + "community": 59, "norm_label": "runall()" }, { @@ -6375,7 +6348,7 @@ "source_file": "main/utils/models/loader.py", "source_location": "L1", "id": "main_utils_models_loader_py", - "community": 560, + "community": 222, "norm_label": "loader.py" }, { @@ -6384,7 +6357,7 @@ "source_file": "main/utils/models/loader.py", "source_location": "L12", "id": "models_loader_getembeddingmodel", - "community": 560, + "community": 222, "norm_label": "getembeddingmodel()" }, { @@ -6828,6 +6801,42 @@ "community": 243, "norm_label": "add prometheus_sandboxes table revision id: d3e4f5a6b7c8 revises: c2e4f6a8b0" }, + { + "label": "d4e5f6a7b8c9_drop_dead_holding_columns.py", + "file_type": "code", + "source_file": "migrations/versions/d4e5f6a7b8c9_drop_dead_holding_columns.py", + "source_location": "L1", + "id": "migrations_versions_d4e5f6a7b8c9_drop_dead_holding_columns_py", + "community": 629, + "norm_label": "d4e5f6a7b8c9_drop_dead_holding_columns.py" + }, + { + "label": "upgrade()", + "file_type": "code", + "source_file": "migrations/versions/d4e5f6a7b8c9_drop_dead_holding_columns.py", + "source_location": "L24", + "id": "versions_d4e5f6a7b8c9_drop_dead_holding_columns_upgrade", + "community": 629, + "norm_label": "upgrade()" + }, + { + "label": "downgrade()", + "file_type": "code", + "source_file": "migrations/versions/d4e5f6a7b8c9_drop_dead_holding_columns.py", + "source_location": "L32", + "id": "versions_d4e5f6a7b8c9_drop_dead_holding_columns_downgrade", + "community": 629, + "norm_label": "downgrade()" + }, + { + "label": "drop dead holding columns Revision ID: d4e5f6a7b8c9 Revises: c4d1e8f2a917 Creat", + "file_type": "rationale", + "source_file": "migrations/versions/d4e5f6a7b8c9_drop_dead_holding_columns.py", + "source_location": "L1", + "id": "versions_d4e5f6a7b8c9_drop_dead_holding_columns_rationale_1", + "community": 629, + "norm_label": "drop dead holding columns revision id: d4e5f6a7b8c9 revises: c4d1e8f2a917 creat" + }, { "label": "e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories.py", "file_type": "code", @@ -12783,7 +12792,7 @@ "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", "source_location": "L131", "id": "plans_2026_09_30_wallet_p1_task_2_wallet_orm_models_5_tables_user_db", - "community": 611, + "community": 530, "norm_label": "task 2: wallet orm models (5 tables, `user_db`)" }, { @@ -12792,7 +12801,7 @@ "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", "source_location": "L143", "id": "plans_2026_09_30_wallet_p1_codeblock_5", - "community": 611, + "community": 530, "norm_label": "code:python (from main.models.base import base)" }, { @@ -12801,7 +12810,7 @@ "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", "source_location": "L172", "id": "plans_2026_09_30_wallet_p1_codeblock_6", - "community": 611, + "community": 530, "norm_label": "code:python (from sqlalchemy import column, date, enum, foreignkey, integ)" }, { @@ -12810,7 +12819,7 @@ "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", "source_location": "L258", "id": "plans_2026_09_30_wallet_p1_codeblock_7", - "community": 611, + "community": 530, "norm_label": "code:bash (git add main/models/wallet.py tests/test_wallet_models.py)" }, { @@ -12945,7 +12954,7 @@ "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", "source_location": "L627", "id": "plans_2026_09_30_wallet_p1_task_6_entries_ledger_holdings_recalc_avg_price_engine", - "community": 530, + "community": 633, "norm_label": "task 6: entries ledger + holdings recalc (avg-price engine)" }, { @@ -12954,7 +12963,7 @@ "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", "source_location": "L642", "id": "plans_2026_09_30_wallet_p1_codeblock_19", - "community": 530, + "community": 633, "norm_label": "code:python (def test_compra_average_includes_costs(dbsession):)" }, { @@ -12963,7 +12972,7 @@ "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", "source_location": "L691", "id": "plans_2026_09_30_wallet_p1_codeblock_20", - "community": 530, + "community": 633, "norm_label": "code:python (from datetime import date)" }, { @@ -12972,7 +12981,7 @@ "source_file": "docs/superpowers/plans/2026-09-30-wallet-p1.md", "source_location": "L782", "id": "plans_2026_09_30_wallet_p1_codeblock_21", - "community": 530, + "community": 633, "norm_label": "code:bash (git add main/service/wallet_service.py main/controller/walle)" }, { @@ -13713,6 +13722,51 @@ "community": 208, "norm_label": "10. plans and follow-ups" }, + { + "label": "Compute time-weighted return, volatility, and dividends for a wallet or ticker.", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L151", + "community": 101, + "norm_label": "compute time-weighted return, volatility, and dividends for a wallet or ticker.", + "id": "tools_wallet_rationale_151" + }, + { + "label": "Show weight-share rebalance deltas per ticker (buy/sell/hold). Read-only: n", + "file_type": "rationale", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L188", + "community": 101, + "norm_label": "show weight-share rebalance deltas per ticker (buy/sell/hold). read-only: n", + "id": "tools_wallet_rationale_188" + }, + { + "label": "wallet_service.py", + "file_type": "code", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L1", + "community": 68, + "norm_label": "wallet_service.py", + "id": "main_app_wallet_wallet_service_py" + }, + { + "label": "XANGO quality score per ticker (0-100 scale). One fundamental read per", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L23", + "community": 637, + "norm_label": "xango quality score per ticker (0-100 scale). one fundamental read per", + "id": "wallet_positions_rationale_23" + }, + { + "label": "Weight-share deltas on backend floats: target_i = w_i/\u03a3w, targetEquity = target_", + "file_type": "rationale", + "source_file": "main/app/wallet/positions.py", + "source_location": "L83", + "community": 626, + "norm_label": "weight-share deltas on backend floats: target_i = w_i/\u03c3w, targetequity = target_", + "id": "wallet_positions_rationale_83" + }, { "label": "Search user's saved memories, preferences, and past analysis context. Use t", "file_type": "rationale", @@ -13808,7 +13862,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L100", - "community": 67, + "community": 605, "norm_label": "execute_code()", "id": "orunmila_tools_execute_code" }, @@ -13817,7 +13871,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L121", - "community": 628, + "community": 67, "norm_label": "read_file()", "id": "orunmila_tools_read_file" }, @@ -13835,7 +13889,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L151", - "community": 67, + "community": 616, "norm_label": "list_files()", "id": "orunmila_tools_list_files" }, @@ -13853,7 +13907,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L189", - "community": 482, + "community": 67, "norm_label": "get_wallet_positions()", "id": "orunmila_tools_get_wallet_positions" }, @@ -13871,7 +13925,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L261", - "community": 67, + "community": 152, "norm_label": "get_wallet_allocation()", "id": "orunmila_tools_get_wallet_allocation" }, @@ -13889,7 +13943,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L354", - "community": 67, + "community": 535, "norm_label": "get_wallet_performance()", "id": "orunmila_tools_get_wallet_performance" }, @@ -13898,7 +13952,7 @@ "file_type": "code", "source_file": "main/app/orunmila/tools.py", "source_location": "L404", - "community": 631, + "community": 67, "norm_label": "get_wallet_rebalance()", "id": "orunmila_tools_get_wallet_rebalance" }, @@ -13934,7 +13988,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L101", - "community": 67, + "community": 605, "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", "id": "orunmila_tools_rationale_101" }, @@ -13943,7 +13997,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L122", - "community": 628, + "community": 67, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "orunmila_tools_rationale_122" }, @@ -13961,7 +14015,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L152", - "community": 67, + "community": 616, "norm_label": "list files in the workspace directory. args: path: directory pat", "id": "orunmila_tools_rationale_152" }, @@ -13979,7 +14033,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L190", - "community": 482, + "community": 67, "norm_label": "list wallet holdings with live prices, equity, allocation, and buy signals.", "id": "orunmila_tools_rationale_190" }, @@ -13997,7 +14051,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L262", - "community": 67, + "community": 152, "norm_label": "break wallet equity down by ticker or asset type. read-only: never mutate", "id": "orunmila_tools_rationale_262" }, @@ -14015,7 +14069,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L357", - "community": 67, + "community": 535, "norm_label": "compute time-weighted return, volatility, and dividends for a wallet or ticker.", "id": "orunmila_tools_rationale_357" }, @@ -14024,7 +14078,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L405", - "community": 631, + "community": 67, "norm_label": "show weight-share rebalance deltas per ticker (buy/sell/hold). read-only:", "id": "orunmila_tools_rationale_405" }, @@ -14069,7 +14123,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L96", - "community": 67, + "community": 605, "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", "id": "orunmila_tools_rationale_96" }, @@ -14078,7 +14132,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L117", - "community": 628, + "community": 67, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "orunmila_tools_rationale_117" }, @@ -14096,7 +14150,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L147", - "community": 67, + "community": 616, "norm_label": "list files in the workspace directory. args: path: directory pat", "id": "orunmila_tools_rationale_147" }, @@ -14114,7 +14168,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L185", - "community": 482, + "community": 67, "norm_label": "list wallet holdings with live prices, equity, allocation, and buy signals.", "id": "orunmila_tools_rationale_185" }, @@ -14132,7 +14186,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L263", - "community": 67, + "community": 152, "norm_label": "break wallet equity down by ticker or asset type. read-only: never mutate", "id": "orunmila_tools_rationale_263" }, @@ -14150,7 +14204,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L364", - "community": 67, + "community": 535, "norm_label": "compute time-weighted return, volatility, and dividends for a wallet or ticker.", "id": "orunmila_tools_rationale_364" }, @@ -14159,7 +14213,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L415", - "community": 631, + "community": 67, "norm_label": "show weight-share rebalance deltas per ticker (buy/sell/hold). read-only:", "id": "orunmila_tools_rationale_415" }, @@ -14168,7 +14222,7 @@ "file_type": "code", "source_file": "main/app/wallet/market_data.py", "source_location": "L42", - "community": 518, + "community": 535, "norm_label": "fetchcachedclose()", "id": "wallet_market_data_fetchcachedclose" }, @@ -14258,7 +14312,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L95", - "community": 67, + "community": 605, "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", "id": "orunmila_tools_rationale_95" }, @@ -14267,7 +14321,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L116", - "community": 628, + "community": 67, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "orunmila_tools_rationale_116" }, @@ -14285,7 +14339,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L146", - "community": 67, + "community": 616, "norm_label": "list files in the workspace directory. args: path: directory pat", "id": "orunmila_tools_rationale_146" }, @@ -14375,7 +14429,7 @@ "file_type": "code", "source_file": "main/app/wallet/auth.py", "source_location": "L1", - "community": 528, + "community": 632, "norm_label": "auth.py", "id": "main_app_wallet_auth_py" }, @@ -14384,7 +14438,7 @@ "file_type": "code", "source_file": "main/app/wallet/auth.py", "source_location": "L13", - "community": 528, + "community": 632, "norm_label": "resolverawtoken()", "id": "wallet_auth_resolverawtoken" }, @@ -14393,7 +14447,7 @@ "file_type": "code", "source_file": "main/app/wallet/auth.py", "source_location": "L26", - "community": 528, + "community": 632, "norm_label": "getwalletidentity()", "id": "wallet_auth_getwalletidentity" }, @@ -14402,7 +14456,7 @@ "file_type": "code", "source_file": "main/app/wallet/auth.py", "source_location": "L30", - "community": 528, + "community": 632, "norm_label": "requirewalletuser()", "id": "wallet_auth_requirewalletuser" }, @@ -14411,7 +14465,7 @@ "file_type": "code", "source_file": "main/app/wallet/auth.py", "source_location": "L36", - "community": 528, + "community": 632, "norm_label": "requirewalletownership()", "id": "wallet_auth_requirewalletownership" }, @@ -14420,7 +14474,7 @@ "file_type": "code", "source_file": "main/app/wallet/market_data.py", "source_location": "L16", - "community": 518, + "community": 535, "norm_label": "stocksapibase()", "id": "wallet_market_data_stocksapibase" }, @@ -14429,7 +14483,7 @@ "file_type": "code", "source_file": "main/app/wallet/market_data.py", "source_location": "L20", - "community": 518, + "community": 535, "norm_label": "stocksapiheaders()", "id": "wallet_market_data_stocksapiheaders" }, @@ -14762,7 +14816,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L94", - "community": 67, + "community": 605, "norm_label": "execute python code in an isolated sandbox. use for quantitative analysis,", "id": "orunmila_tools_rationale_94" }, @@ -14771,7 +14825,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L115", - "community": 628, + "community": 67, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "orunmila_tools_rationale_115" }, @@ -14789,7 +14843,7 @@ "file_type": "rationale", "source_file": "main/app/orunmila/tools.py", "source_location": "L145", - "community": 67, + "community": 616, "norm_label": "list files in the workspace directory. args: path: directory pat", "id": "orunmila_tools_rationale_145" }, @@ -16562,7 +16616,7 @@ "file_type": "code", "source_file": "main/utils/roles.py", "source_location": "L63", - "community": 584, + "community": 590, "norm_label": "_servicetoken()", "id": "utils_roles_servicetoken" }, @@ -16571,7 +16625,7 @@ "file_type": "code", "source_file": "main/utils/roles.py", "source_location": "L69", - "community": 584, + "community": 590, "norm_label": "_introspecturl()", "id": "utils_roles_introspecturl" }, @@ -16580,7 +16634,7 @@ "file_type": "code", "source_file": "main/utils/roles.py", "source_location": "L75", - "community": 584, + "community": 590, "norm_label": "_extractcredential()", "id": "utils_roles_extractcredential" }, @@ -16589,7 +16643,7 @@ "file_type": "code", "source_file": "main/utils/roles.py", "source_location": "L92", - "community": 584, + "community": 590, "norm_label": "introspectuser()", "id": "utils_roles_introspectuser" }, @@ -16643,7 +16697,7 @@ "file_type": "code", "source_file": "main/app/prometheus/agent.py", "source_location": "L208", - "community": 140, + "community": 116, "norm_label": "prometheus", "id": "prometheus_agent_prometheus" }, @@ -16697,7 +16751,7 @@ "file_type": "code", "source_file": "main/app/prometheus/chat.py", "source_location": "L13", - "community": 29, + "community": 112, "norm_label": "prometheuschatmanager", "id": "prometheus_chat_prometheuschatmanager" }, @@ -17102,7 +17156,7 @@ "file_type": "code", "source_file": "main/app/prometheus/memory.py", "source_location": "L90", - "community": 116, + "community": 53, "norm_label": "newtokencache()", "id": "prometheus_memory_newtokencache" }, @@ -17543,7 +17597,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L1", - "community": 525, + "community": 521, "norm_label": "tools.py", "id": "main_app_prometheus_tools_py" }, @@ -17561,7 +17615,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L51", - "community": 136, + "community": 190, "norm_label": "save_memory()", "id": "prometheus_tools_save_memory" }, @@ -17579,7 +17633,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L114", - "community": 221, + "community": 538, "norm_label": "read_file()", "id": "prometheus_tools_read_file" }, @@ -17633,7 +17687,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L52", - "community": 136, + "community": 190, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_52" }, @@ -17651,7 +17705,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L115", - "community": 221, + "community": 538, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_115" }, @@ -17858,7 +17912,7 @@ "file_type": "code", "source_file": "main/controller/prometheus_controller.py", "source_location": "L179", - "community": 69, + "community": 84, "norm_label": "downloadworkspacefile()", "id": "controller_prometheus_controller_downloadworkspacefile" }, @@ -17921,7 +17975,7 @@ "file_type": "code", "source_file": "main/service/prometheus_service.py", "source_location": "L23", - "community": 574, + "community": 503, "norm_label": "memorymaintenance()", "id": "service_prometheus_service_memorymaintenance" }, @@ -18488,7 +18542,7 @@ "file_type": "code", "source_file": "main/app/authentication/session.py", "source_location": "L14", - "community": 44, + "community": 523, "norm_label": "getdevicename()", "id": "authentication_session_getdevicename" }, @@ -18758,7 +18812,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L50", - "community": 136, + "community": 190, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_50" }, @@ -18776,7 +18830,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L112", - "community": 221, + "community": 538, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_112" }, @@ -18794,7 +18848,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L142", - "community": 525, + "community": 521, "norm_label": "list files in the workspace directory. args: path: directory pat", "id": "prometheus_tools_rationale_142" }, @@ -18848,7 +18902,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L49", - "community": 136, + "community": 190, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_49" }, @@ -18866,7 +18920,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L111", - "community": 221, + "community": 538, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_111" }, @@ -18911,7 +18965,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L23", - "community": 157, + "community": 197, "norm_label": "jsonbytesresponse", "id": "controller_stocksapi_controller_jsonbytesresponse" }, @@ -18920,7 +18974,7 @@ "file_type": "code", "source_file": "", "source_location": "", - "community": 157, + "community": 197, "norm_label": "fastapiresponse", "id": "fastapiresponse" }, @@ -18929,7 +18983,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L26", - "community": 157, + "community": 197, "norm_label": ".render()", "id": "controller_stocksapi_controller_jsonbytesresponse_render" }, @@ -19721,7 +19775,7 @@ "file_type": "rationale", "source_file": "main/service/scraper_service.py", "source_location": "L23", - "community": 604, + "community": 474, "norm_label": "p5: register the scraper cron jobs on the shared scheduler. kept in this", "id": "service_scraper_service_rationale_23" }, @@ -21044,7 +21098,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L89", - "community": 538, + "community": 584, "norm_label": "fieldregistry", "id": "prometheus_compact_fieldregistry" }, @@ -21053,7 +21107,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L94", - "community": 538, + "community": 584, "norm_label": ".buildurl()", "id": "prometheus_compact_fieldregistry_buildurl" }, @@ -21062,7 +21116,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L99", - "community": 538, + "community": 584, "norm_label": ".fetchfields()", "id": "prometheus_compact_fieldregistry_fetchfields" }, @@ -21071,7 +21125,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L120", - "community": 538, + "community": 584, "norm_label": ".getfields()", "id": "prometheus_compact_fieldregistry_getfields" }, @@ -21080,7 +21134,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L127", - "community": 538, + "community": 584, "norm_label": ".buildmetricregex()", "id": "prometheus_compact_fieldregistry_buildmetricregex" }, @@ -21089,7 +21143,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L134", - "community": 538, + "community": 584, "norm_label": ".getmetricregex()", "id": "prometheus_compact_fieldregistry_getmetricregex" }, @@ -21098,7 +21152,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L222", - "community": 538, + "community": 80, "norm_label": ".__init__()", "id": "prometheus_compact_prometheuscompactor_init" }, @@ -21125,7 +21179,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L54", - "community": 136, + "community": 190, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_54" }, @@ -21143,7 +21197,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L113", - "community": 221, + "community": 538, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_113" }, @@ -21593,7 +21647,7 @@ "file_type": "code", "source_file": "main/app/authentication/session.py", "source_location": "L124", - "community": 44, + "community": 523, "norm_label": "cleanupexpiredsessions()", "id": "authentication_session_cleanupexpiredsessions" }, @@ -21602,7 +21656,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L139", - "community": 538, + "community": 584, "norm_label": ".invalidate()", "id": "prometheus_compact_fieldregistry_invalidate" }, @@ -21611,7 +21665,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L145", - "community": 538, + "community": 584, "norm_label": ".warmup()", "id": "prometheus_compact_fieldregistry_warmup" }, @@ -21683,7 +21737,7 @@ "file_type": "code", "source_file": "main/app/user/user.py", "source_location": "L22", - "community": 519, + "community": 528, "norm_label": "todict()", "id": "user_user_todict" }, @@ -21692,7 +21746,7 @@ "file_type": "rationale", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L24", - "community": 157, + "community": 197, "norm_label": "sends pre-serialized json bytes without re-encoding (cache-friendly).", "id": "controller_stocksapi_controller_rationale_24" }, @@ -21746,7 +21800,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L1", - "community": 523, + "community": 602, "norm_label": "response_cache.py", "id": "main_app_stocks_api_response_cache_py" }, @@ -21755,7 +21809,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L19", - "community": 523, + "community": 602, "norm_label": "responsecache", "id": "stocks_api_response_cache_responsecache" }, @@ -21764,7 +21818,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L20", - "community": 523, + "community": 602, "norm_label": ".__init__()", "id": "stocks_api_response_cache_responsecache_init" }, @@ -21773,7 +21827,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L29", - "community": 523, + "community": 602, "norm_label": ".makekey()", "id": "stocks_api_response_cache_responsecache_makekey" }, @@ -21782,7 +21836,7 @@ "file_type": "code", "source_file": "main/app/stocks_api/response_cache.py", "source_location": "L34", - "community": 523, + "community": 602, "norm_label": ".get()", "id": "stocks_api_response_cache_responsecache_get" }, @@ -22574,7 +22628,7 @@ "file_type": "code", "source_file": "main/app/prometheus/compact.py", "source_location": "L94", - "community": 538, + "community": 584, "norm_label": ".__new__()", "id": "prometheus_compact_fieldregistry_new" }, @@ -22592,7 +22646,7 @@ "file_type": "code", "source_file": "main/app/user/user.py", "source_location": "L19", - "community": 519, + "community": 528, "norm_label": "addrole()", "id": "user_user_addrole" }, @@ -22601,7 +22655,7 @@ "file_type": "code", "source_file": "main/app/user/user.py", "source_location": "L28", - "community": 519, + "community": 528, "norm_label": "hasrole()", "id": "user_user_hasrole" }, @@ -22610,7 +22664,7 @@ "file_type": "code", "source_file": "main/app/user/user.py", "source_location": "L44", - "community": 519, + "community": 528, "norm_label": "addroletouser()", "id": "user_user_addroletouser" }, @@ -23609,7 +23663,7 @@ "file_type": "code", "source_file": "main/app/prometheus/state.py", "source_location": "L14", - "community": 568, + "community": 186, "norm_label": ".set()", "id": "prometheus_state_harnessstate_set" }, @@ -23663,7 +23717,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L89", - "community": 503, + "community": 231, "norm_label": "get_state()", "id": "prometheus_tools_get_state" }, @@ -23888,7 +23942,7 @@ "file_type": "code", "source_file": "main/utils/connectivity.py", "source_location": "L13", - "community": 572, + "community": 59, "norm_label": "checksingledb()", "id": "utils_connectivity_checksingledb" }, @@ -24257,7 +24311,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tokenizer.py", "source_location": "L1", - "community": 630, + "community": 87, "norm_label": "tokenizer.py", "id": "main_app_prometheus_tokenizer_py" }, @@ -24266,7 +24320,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tokenizer.py", "source_location": "L10", - "community": 630, + "community": 87, "norm_label": "_get_tokenizer()", "id": "prometheus_tokenizer_get_tokenizer" }, @@ -24275,7 +24329,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tokenizer.py", "source_location": "L17", - "community": 630, + "community": 87, "norm_label": "counttokens()", "id": "prometheus_tokenizer_counttokens" }, @@ -24284,7 +24338,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tokenizer.py", "source_location": "L18", - "community": 630, + "community": 87, "norm_label": "count tokens using gemini's local tokenizer. accurate for portuguese.", "id": "prometheus_tokenizer_rationale_18" }, @@ -25076,7 +25130,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L44", - "community": 136, + "community": 190, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_44" }, @@ -25085,7 +25139,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L81", - "community": 503, + "community": 231, "norm_label": "retrieve values from the harness state. use this to recall intermediate results,", "id": "prometheus_tools_rationale_81" }, @@ -31358,7 +31412,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L81", - "community": 561, + "community": 544, "norm_label": "stocks_http_client()", "id": "tests_conftest_stocks_http_client" }, @@ -31367,7 +31421,7 @@ "file_type": "code", "source_file": "tests/conftest.py", "source_location": "L106", - "community": 561, + "community": 544, "norm_label": "client()", "id": "tests_conftest_client" }, @@ -31394,7 +31448,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L82", - "community": 561, + "community": 544, "norm_label": "testclient with stocks router + verifyapikey + getcurrentuser overrides.", "id": "tests_conftest_rationale_82" }, @@ -31403,7 +31457,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L107", - "community": 561, + "community": 544, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_107" }, @@ -32267,7 +32321,7 @@ "file_type": "code", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L8", - "community": 629, + "community": 59, "norm_label": "testcheckmysqlconnection", "id": "tests_test_connectivity_coverage_testcheckmysqlconnection" }, @@ -32357,7 +32411,7 @@ "file_type": "code", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L114", - "community": 625, + "community": 59, "norm_label": "testcheckserviceconnection", "id": "tests_test_connectivity_coverage_testcheckserviceconnection" }, @@ -32447,7 +32501,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L9", - "community": 629, + "community": 59, "norm_label": "checkmysqlconnection \u2014 success, errors, engine=none paths.", "id": "tests_test_connectivity_coverage_rationale_9" }, @@ -32456,7 +32510,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L115", - "community": 625, + "community": 59, "norm_label": "checkserviceconnection \u2014 success, not found, errors.", "id": "tests_test_connectivity_coverage_rationale_115" }, @@ -32564,7 +32618,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L146", - "community": 45, + "community": 120, "norm_label": "testregisterendpoint", "id": "tests_test_controllers_coverage_testregisterendpoint" }, @@ -32609,7 +32663,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L215", - "community": 45, + "community": 120, "norm_label": "testloginendpoint", "id": "tests_test_controllers_coverage_testloginendpoint" }, @@ -32636,7 +32690,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L257", - "community": 45, + "community": 120, "norm_label": "testlogoutendpoint", "id": "tests_test_controllers_coverage_testlogoutendpoint" }, @@ -32726,7 +32780,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L390", - "community": 45, + "community": 120, "norm_label": "testgooglecallback", "id": "tests_test_controllers_coverage_testgooglecallback" }, @@ -32798,7 +32852,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L541", - "community": 45, + "community": 47, "norm_label": "testgetme", "id": "tests_test_controllers_coverage_testgetme" }, @@ -32807,7 +32861,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L544", - "community": 45, + "community": 47, "norm_label": ".test_get_me()", "id": "tests_test_controllers_coverage_testgetme_test_get_me" }, @@ -32888,7 +32942,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L614", - "community": 45, + "community": 610, "norm_label": "testgetsessions", "id": "tests_test_controllers_coverage_testgetsessions" }, @@ -32897,7 +32951,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L617", - "community": 63, + "community": 610, "norm_label": ".test_get_sessions()", "id": "tests_test_controllers_coverage_testgetsessions_test_get_sessions" }, @@ -32906,7 +32960,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L668", - "community": 45, + "community": 493, "norm_label": "testgetcurrentsession", "id": "tests_test_controllers_coverage_testgetcurrentsession" }, @@ -32915,7 +32969,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L671", - "community": 63, + "community": 493, "norm_label": ".test_get_current_session_found()", "id": "tests_test_controllers_coverage_testgetcurrentsession_test_get_current_session_found" }, @@ -32924,7 +32978,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L704", - "community": 63, + "community": 493, "norm_label": ".test_get_current_session_not_found()", "id": "tests_test_controllers_coverage_testgetcurrentsession_test_get_current_session_not_found" }, @@ -32969,7 +33023,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L805", - "community": 45, + "community": 498, "norm_label": "testrevokeallsessions", "id": "tests_test_controllers_coverage_testrevokeallsessions" }, @@ -32978,7 +33032,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L808", - "community": 63, + "community": 498, "norm_label": ".test_revoke_all_sessions()", "id": "tests_test_controllers_coverage_testrevokeallsessions_test_revoke_all_sessions" }, @@ -33005,7 +33059,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L849", - "community": 45, + "community": 99, "norm_label": "testprometheusgetsessions", "id": "tests_test_controllers_coverage_testprometheusgetsessions" }, @@ -33023,7 +33077,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L867", - "community": 45, + "community": 99, "norm_label": "testprometheuscreatesession", "id": "tests_test_controllers_coverage_testprometheuscreatesession" }, @@ -33032,7 +33086,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L870", - "community": 45, + "community": 99, "norm_label": ".test_create_session()", "id": "tests_test_controllers_coverage_testprometheuscreatesession_test_create_session" }, @@ -33077,7 +33131,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L915", - "community": 256, + "community": 498, "norm_label": "testprometheusgethistory", "id": "tests_test_controllers_coverage_testprometheusgethistory" }, @@ -33086,7 +33140,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L918", - "community": 256, + "community": 498, "norm_label": ".test_get_history_found()", "id": "tests_test_controllers_coverage_testprometheusgethistory_test_get_history_found" }, @@ -33095,7 +33149,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L962", - "community": 256, + "community": 498, "norm_label": ".test_get_history_not_found()", "id": "tests_test_controllers_coverage_testprometheusgethistory_test_get_history_not_found" }, @@ -33104,7 +33158,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L997", - "community": 535, + "community": 99, "norm_label": "testprometheusdeletesession", "id": "tests_test_controllers_coverage_testprometheusdeletesession" }, @@ -33113,7 +33167,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1000", - "community": 535, + "community": 99, "norm_label": ".test_delete_session_success()", "id": "tests_test_controllers_coverage_testprometheusdeletesession_test_delete_session_success" }, @@ -33122,7 +33176,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1010", - "community": 535, + "community": 99, "norm_label": ".test_delete_session_not_found()", "id": "tests_test_controllers_coverage_testprometheusdeletesession_test_delete_session_not_found" }, @@ -33140,7 +33194,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1023", - "community": 148, + "community": 99, "norm_label": ".test_chat_new_session()", "id": "tests_test_controllers_coverage_testprometheuschat_test_chat_new_session" }, @@ -33176,7 +33230,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1144", - "community": 566, + "community": 45, "norm_label": "teststocksapihealth", "id": "tests_test_controllers_coverage_teststocksapihealth" }, @@ -33185,7 +33239,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1147", - "community": 566, + "community": 45, "norm_label": ".test_health()", "id": "tests_test_controllers_coverage_teststocksapihealth_test_health" }, @@ -33194,7 +33248,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1158", - "community": 577, + "community": 14, "norm_label": "teststocksapihistorical", "id": "tests_test_controllers_coverage_teststocksapihistorical" }, @@ -33203,7 +33257,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1161", - "community": 577, + "community": 14, "norm_label": ".test_get_historical()", "id": "tests_test_controllers_coverage_teststocksapihistorical_test_get_historical" }, @@ -33212,7 +33266,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1172", - "community": 610, + "community": 14, "norm_label": "teststocksapifundamental", "id": "tests_test_controllers_coverage_teststocksapifundamental" }, @@ -33266,7 +33320,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1229", - "community": 616, + "community": 614, "norm_label": "testaddroletouser", "id": "tests_test_controllers_coverage_testaddroletouser" }, @@ -33284,7 +33338,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1249", - "community": 529, + "community": 620, "norm_label": ".test_add_role_already_has_role()", "id": "tests_test_controllers_coverage_testaddroletouser_test_add_role_already_has_role" }, @@ -33302,7 +33356,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1275", - "community": 563, + "community": 529, "norm_label": "testgetcurrentuser", "id": "tests_test_controllers_coverage_testgetcurrentuser" }, @@ -33311,7 +33365,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1278", - "community": 563, + "community": 529, "norm_label": "._make_mock_request()", "id": "tests_test_controllers_coverage_testgetcurrentuser_make_mock_request" }, @@ -33320,7 +33374,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1282", - "community": 563, + "community": 529, "norm_label": ".test_get_current_user_valid_session()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_valid_session" }, @@ -33329,7 +33383,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1307", - "community": 529, + "community": 625, "norm_label": ".test_get_current_user_session_revoked()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_session_revoked" }, @@ -33338,7 +33392,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1323", - "community": 589, + "community": 603, "norm_label": ".test_get_current_user_not_found()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_not_found" }, @@ -33347,7 +33401,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1340", - "community": 592, + "community": 604, "norm_label": ".test_get_current_user_generic_exception()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_generic_exception" }, @@ -33356,7 +33410,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1357", - "community": 602, + "community": 611, "norm_label": ".test_get_current_user_no_session_id()", "id": "tests_test_controllers_coverage_testgetcurrentuser_test_get_current_user_no_session_id" }, @@ -33374,7 +33428,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1384", - "community": 43, + "community": 45, "norm_label": ".test_empty_password_raises()", "id": "tests_test_controllers_coverage_testhashpasswordempty_test_empty_password_raises" }, @@ -33383,7 +33437,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1391", - "community": 45, + "community": 194, "norm_label": "testverifyaccesstoken", "id": "tests_test_controllers_coverage_testverifyaccesstoken" }, @@ -33392,7 +33446,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1394", - "community": 620, + "community": 194, "norm_label": ".test_expired_token()", "id": "tests_test_controllers_coverage_testverifyaccesstoken_test_expired_token" }, @@ -33401,7 +33455,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1410", - "community": 194, + "community": 172, "norm_label": ".test_invalid_token()", "id": "tests_test_controllers_coverage_testverifyaccesstoken_test_invalid_token" }, @@ -33509,7 +33563,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L147", - "community": 45, + "community": 120, "norm_label": "covers lines 44-54, 63, 66-71: register success, valueerror, generic exception.", "id": "tests_test_controllers_coverage_rationale_147" }, @@ -33554,7 +33608,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L216", - "community": 45, + "community": 120, "norm_label": "covers lines 87-93, 102: login success and failure paths.", "id": "tests_test_controllers_coverage_rationale_216" }, @@ -33581,7 +33635,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L258", - "community": 45, + "community": 120, "norm_label": "covers lines 107, 109-130, 133: logout token extraction and revocation.", "id": "tests_test_controllers_coverage_rationale_258" }, @@ -33599,7 +33653,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L281", - "community": 45, + "community": 120, "norm_label": "covers lines 111-113: token extracted from authorization bearer header.", "id": "tests_test_controllers_coverage_rationale_281" }, @@ -33671,7 +33725,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L391", - "community": 45, + "community": 120, "norm_label": "covers lines 155-156, 158, 160-168, 170-177, 179-184, 186, 190-204: googlecallba", "id": "tests_test_controllers_coverage_rationale_391" }, @@ -33734,7 +33788,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L542", - "community": 45, + "community": 47, "norm_label": "covers line 24: get /user/me returns currentuser.", "id": "tests_test_controllers_coverage_rationale_542" }, @@ -33761,7 +33815,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L615", - "community": 45, + "community": 610, "norm_label": "covers lines 66, 68-72, 74: get /user/sessions.", "id": "tests_test_controllers_coverage_rationale_615" }, @@ -33770,7 +33824,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L618", - "community": 63, + "community": 610, "norm_label": "covers lines 66, 68-72, 74: full sessions listing.", "id": "tests_test_controllers_coverage_rationale_618" }, @@ -33779,7 +33833,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L669", - "community": 45, + "community": 493, "norm_label": "covers lines 100-104, 106: get /user/sessions/current.", "id": "tests_test_controllers_coverage_rationale_669" }, @@ -33788,7 +33842,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L672", - "community": 63, + "community": 493, "norm_label": "covers lines 100-104, 106: session found.", "id": "tests_test_controllers_coverage_rationale_672" }, @@ -33797,7 +33851,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L705", - "community": 63, + "community": 493, "norm_label": "covers line 104: session not found.", "id": "tests_test_controllers_coverage_rationale_705" }, @@ -33842,7 +33896,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L806", - "community": 45, + "community": 498, "norm_label": "covers lines 143, 145, 147-148: post /user/sessions/revoke-all.", "id": "tests_test_controllers_coverage_rationale_806" }, @@ -33851,7 +33905,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L809", - "community": 63, + "community": 498, "norm_label": "covers lines 143, 145, 147-148.", "id": "tests_test_controllers_coverage_rationale_809" }, @@ -33869,7 +33923,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L850", - "community": 45, + "community": 99, "norm_label": "covers lines 33-36: get /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_850" }, @@ -33878,7 +33932,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L868", - "community": 45, + "community": 99, "norm_label": "covers line 52: post /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_868" }, @@ -33923,7 +33977,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L916", - "community": 256, + "community": 498, "norm_label": "covers lines 77, 83-84, 86: get /prometheus/history/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_916" }, @@ -33932,7 +33986,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L919", - "community": 256, + "community": 498, "norm_label": "covers lines 77, 86: session found with history.", "id": "tests_test_controllers_coverage_rationale_919" }, @@ -33941,7 +33995,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L963", - "community": 256, + "community": 498, "norm_label": "covers lines 83-84: session not found.", "id": "tests_test_controllers_coverage_rationale_963" }, @@ -33950,7 +34004,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L998", - "community": 535, + "community": 99, "norm_label": "covers lines 95-98: delete /prometheus/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_998" }, @@ -33959,7 +34013,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1001", - "community": 535, + "community": 99, "norm_label": "covers lines 95-98: session deleted.", "id": "tests_test_controllers_coverage_rationale_1001" }, @@ -33968,7 +34022,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1011", - "community": 535, + "community": 99, "norm_label": "covers lines 96-97: session not found.", "id": "tests_test_controllers_coverage_rationale_1011" }, @@ -33986,7 +34040,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1024", - "community": 148, + "community": 99, "norm_label": "covers lines 118-119: sessionid is none, new session created.", "id": "tests_test_controllers_coverage_rationale_1024" }, @@ -34022,7 +34076,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1145", - "community": 566, + "community": 45, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1145" }, @@ -34031,7 +34085,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1159", - "community": 577, + "community": 14, "norm_label": "covers line 35: get /stocks/historical.", "id": "tests_test_controllers_coverage_rationale_1159" }, @@ -34040,7 +34094,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1173", - "community": 610, + "community": 14, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1173" }, @@ -34085,7 +34139,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1230", - "community": 616, + "community": 614, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1230" }, @@ -34103,7 +34157,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1250", - "community": 14, + "community": 620, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1250" }, @@ -34121,7 +34175,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1276", - "community": 563, + "community": 529, "norm_label": "covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: usermanager.getc", "id": "tests_test_controllers_coverage_rationale_1276" }, @@ -34130,7 +34184,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1283", - "community": 563, + "community": 529, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1283" }, @@ -34139,7 +34193,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1308", - "community": 529, + "community": 625, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1308" }, @@ -34148,7 +34202,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1324", - "community": 589, + "community": 603, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1324" }, @@ -34157,7 +34211,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1341", - "community": 592, + "community": 604, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1341" }, @@ -34166,7 +34220,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1358", - "community": 602, + "community": 611, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1358" }, @@ -34175,7 +34229,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1382", - "community": 45, + "community": 194, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1382" }, @@ -34184,7 +34238,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1392", - "community": 45, + "community": 194, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1392" }, @@ -34193,7 +34247,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1395", - "community": 620, + "community": 194, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1395" }, @@ -34202,7 +34256,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1411", - "community": 194, + "community": 172, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1411" }, @@ -35093,7 +35147,7 @@ "file_type": "code", "source_file": "tests/test_harness_state.py", "source_location": "L1", - "community": 49, + "community": 561, "norm_label": "test_harness_state.py", "id": "tests_test_harness_state_py" }, @@ -35201,7 +35255,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L1", - "community": 590, + "community": 561, "norm_label": "test_http_session_coverage.py", "id": "tests_test_http_session_coverage_py" }, @@ -35210,7 +35264,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L8", - "community": 590, + "community": 561, "norm_label": "testgetsession", "id": "tests_test_http_session_coverage_testgetsession" }, @@ -35219,7 +35273,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L9", - "community": 590, + "community": 561, "norm_label": ".test_returns_same_session()", "id": "tests_test_http_session_coverage_testgetsession_test_returns_same_session" }, @@ -35228,7 +35282,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L16", - "community": 590, + "community": 561, "norm_label": ".test_returns_requests_session()", "id": "tests_test_http_session_coverage_testgetsession_test_returns_requests_session" }, @@ -35237,7 +35291,7 @@ "file_type": "rationale", "source_file": "tests/test_http_session_coverage.py", "source_location": "L1", - "community": 590, + "community": 561, "norm_label": "tests for main/utils/http_session.py \u2014 covers all branches.", "id": "tests_test_http_session_coverage_rationale_1" }, @@ -35930,7 +35984,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L84", - "community": 574, + "community": 256, "norm_label": "testarchive", "id": "tests_test_memory_maintenance_testarchive" }, @@ -35939,7 +35993,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L85", - "community": 574, + "community": 256, "norm_label": ".test_dead_memory_archived()", "id": "tests_test_memory_maintenance_testarchive_test_dead_memory_archived" }, @@ -35948,7 +36002,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L92", - "community": 574, + "community": 256, "norm_label": ".test_low_score_but_recent_not_archived()", "id": "tests_test_memory_maintenance_testarchive_test_low_score_but_recent_not_archived" }, @@ -35957,7 +36011,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L99", - "community": 574, + "community": 256, "norm_label": ".test_zero_access_but_high_score_not_archived()", "id": "tests_test_memory_maintenance_testarchive_test_zero_access_but_high_score_not_archived" }, @@ -35966,7 +36020,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L106", - "community": 574, + "community": 256, "norm_label": ".test_accessed_memory_not_archived()", "id": "tests_test_memory_maintenance_testarchive_test_accessed_memory_not_archived" }, @@ -35975,7 +36029,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L113", - "community": 574, + "community": 256, "norm_label": ".test_already_archived_not_double_archived()", "id": "tests_test_memory_maintenance_testarchive_test_already_archived_not_double_archived" }, @@ -35984,7 +36038,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L123", - "community": 574, + "community": 256, "norm_label": ".test_multiple_users_independent_archive()", "id": "tests_test_memory_maintenance_testarchive_test_multiple_users_independent_archive" }, @@ -36011,7 +36065,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L143", - "community": 574, + "community": 635, "norm_label": ".test_score_above_threshold_after_decay_not_archived()", "id": "tests_test_memory_maintenance_testdecayandarchivetogether_test_score_above_threshold_after_decay_not_archived" }, @@ -36056,7 +36110,7 @@ "file_type": "code", "source_file": "tests/test_memory_maintenance.py", "source_location": "L171", - "community": 574, + "community": 503, "norm_label": ".test_no_memories_does_not_crash()", "id": "tests_test_memory_maintenance_testemptydatabase_test_no_memories_does_not_crash" }, @@ -36092,7 +36146,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L86", - "community": 574, + "community": 256, "norm_label": "score below threshold + accesscount=0 + 90+ days \u2192 archived.", "id": "tests_test_memory_maintenance_rationale_86" }, @@ -36101,7 +36155,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L93", - "community": 574, + "community": 256, "norm_label": "low score but accessed recently \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_93" }, @@ -36110,7 +36164,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L100", - "community": 574, + "community": 256, "norm_label": "zero access but score still above threshold \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_100" }, @@ -36119,7 +36173,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L107", - "community": 574, + "community": 256, "norm_label": "even with low score, if accessed \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_107" }, @@ -36128,7 +36182,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L114", - "community": 574, + "community": 256, "norm_label": "already archived memories are skipped.", "id": "tests_test_memory_maintenance_rationale_114" }, @@ -36146,7 +36200,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L144", - "community": 574, + "community": 635, "norm_label": "score that decays to >= threshold stays alive. 0.12 * 0.90 = 0.108 >= 0.1.", "id": "tests_test_memory_maintenance_rationale_144" }, @@ -36479,7 +36533,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L60", - "community": 568, + "community": 186, "norm_label": ".test_memory_tool_names_unchanged()", "id": "tests_test_memory_tools_wiring_testmemorytoolfunctions_test_memory_tool_names_unchanged" }, @@ -36488,7 +36542,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L64", - "community": 568, + "community": 49, "norm_label": "testtoolregistry", "id": "tests_test_memory_tools_wiring_testtoolregistry" }, @@ -36497,7 +36551,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L67", - "community": 568, + "community": 49, "norm_label": ".test_registry_contains_memory_tools()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_contains_memory_tools" }, @@ -36506,7 +36560,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L71", - "community": 568, + "community": 49, "norm_label": ".test_registry_values_are_callable()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_values_are_callable" }, @@ -36515,7 +36569,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L75", - "community": 568, + "community": 49, "norm_label": ".test_registry_matches_tool_names()", "id": "tests_test_memory_tools_wiring_testtoolregistry_test_registry_matches_tool_names" }, @@ -36524,7 +36578,7 @@ "file_type": "code", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L79", - "community": 627, + "community": 630, "norm_label": "testmakechatincludesmemorytools", "id": "tests_test_memory_tools_wiring_testmakechatincludesmemorytools" }, @@ -36596,7 +36650,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L65", - "community": 568, + "community": 49, "norm_label": "tool_registry pattern must work correctly.", "id": "tests_test_memory_tools_wiring_rationale_65" }, @@ -36605,7 +36659,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L80", - "community": 627, + "community": 630, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_80" }, @@ -37199,7 +37253,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L39", - "community": 576, + "community": 562, "norm_label": "testinlinepagination", "id": "tests_test_pagination_testinlinepagination" }, @@ -37208,7 +37262,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L40", - "community": 576, + "community": 562, "norm_label": ".test_defaults()", "id": "tests_test_pagination_testinlinepagination_test_defaults" }, @@ -37217,7 +37271,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L48", - "community": 576, + "community": 562, "norm_label": ".test_custom_limit()", "id": "tests_test_pagination_testinlinepagination_test_custom_limit" }, @@ -37226,7 +37280,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L54", - "community": 576, + "community": 562, "norm_label": ".test_custom_offset()", "id": "tests_test_pagination_testinlinepagination_test_custom_offset" }, @@ -37235,7 +37289,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L61", - "community": 576, + "community": 562, "norm_label": ".test_limit_and_offset()", "id": "tests_test_pagination_testinlinepagination_test_limit_and_offset" }, @@ -37244,7 +37298,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L69", - "community": 576, + "community": 562, "norm_label": ".test_limit_exceeds_max_rejected()", "id": "tests_test_pagination_testinlinepagination_test_limit_exceeds_max_rejected" }, @@ -37253,7 +37307,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L73", - "community": 576, + "community": 562, "norm_label": ".test_limit_zero_rejected()", "id": "tests_test_pagination_testinlinepagination_test_limit_zero_rejected" }, @@ -37262,7 +37316,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L77", - "community": 576, + "community": 562, "norm_label": ".test_negative_offset_rejected()", "id": "tests_test_pagination_testinlinepagination_test_negative_offset_rejected" }, @@ -37271,7 +37325,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L81", - "community": 576, + "community": 562, "norm_label": ".test_offset_beyond_total()", "id": "tests_test_pagination_testinlinepagination_test_offset_beyond_total" }, @@ -37280,7 +37334,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L86", - "community": 576, + "community": 562, "norm_label": ".test_limit_equals_max()", "id": "tests_test_pagination_testinlinepagination_test_limit_equals_max" }, @@ -37307,7 +37361,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L26", - "community": 29, + "community": 112, "norm_label": "testprometheusinit", "id": "tests_test_prometheus_auth_coverage_testprometheusinit" }, @@ -37325,7 +37379,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L41", - "community": 29, + "community": 112, "norm_label": "testprometheussendmessage", "id": "tests_test_prometheus_auth_coverage_testprometheussendmessage" }, @@ -37388,7 +37442,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L248", - "community": 29, + "community": 112, "norm_label": ".test_init()", "id": "tests_test_prometheus_auth_coverage_testprometheuschatmanager_test_init" }, @@ -37550,7 +37604,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L469", - "community": 29, + "community": 519, "norm_label": "testauthenticationmanager", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager" }, @@ -37568,7 +37622,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L485", - "community": 29, + "community": 519, "norm_label": ".test_create_user_account_no_password_no_google()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_create_user_account_no_password_no_google" }, @@ -37577,7 +37631,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L496", - "community": 29, + "community": 519, "norm_label": ".test_create_user_account_username_taken()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_create_user_account_username_taken" }, @@ -37586,7 +37640,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L510", - "community": 29, + "community": 519, "norm_label": ".test_create_user_account_email_taken()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_create_user_account_email_taken" }, @@ -37604,7 +37658,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L539", - "community": 29, + "community": 519, "norm_label": ".test_create_user_account_with_google_id()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_create_user_account_with_google_id" }, @@ -37613,7 +37667,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L548", - "community": 29, + "community": 519, "norm_label": ".test_authenticate_google_user_found()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_authenticate_google_user_found" }, @@ -37622,7 +37676,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L563", - "community": 29, + "community": 519, "norm_label": ".test_authenticate_google_user_not_found()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_authenticate_google_user_not_found" }, @@ -37631,7 +37685,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L572", - "community": 29, + "community": 519, "norm_label": ".test_authenticate_google_user_exception()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_authenticate_google_user_exception" }, @@ -37658,7 +37712,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L611", - "community": 29, + "community": 519, "norm_label": ".test_authenticate_user_not_found()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_authenticate_user_not_found" }, @@ -37667,7 +37721,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L620", - "community": 29, + "community": 519, "norm_label": ".test_authenticate_user_no_password_hash()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_authenticate_user_no_password_hash" }, @@ -37676,7 +37730,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L631", - "community": 29, + "community": 519, "norm_label": ".test_authenticate_user_exception()", "id": "tests_test_prometheus_auth_coverage_testauthenticationmanager_test_authenticate_user_exception" }, @@ -37865,7 +37919,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L881", - "community": 60, + "community": 627, "norm_label": ".test_validate_session_expired_naive_tz()", "id": "tests_test_prometheus_auth_coverage_testsessionmanager_test_validate_session_expired_naive_tz" }, @@ -37874,7 +37928,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L895", - "community": 60, + "community": 628, "norm_label": ".test_validate_session_no_expiry()", "id": "tests_test_prometheus_auth_coverage_testsessionmanager_test_validate_session_no_expiry" }, @@ -37883,7 +37937,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L914", - "community": 29, + "community": 112, "norm_label": "testsso", "id": "tests_test_prometheus_auth_coverage_testsso" }, @@ -37892,7 +37946,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L919", - "community": 58, + "community": 592, "norm_label": "test_get_google_sso_with_redirect()", "id": "tests_test_prometheus_auth_coverage_test_get_google_sso_with_redirect" }, @@ -37901,7 +37955,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L938", - "community": 58, + "community": 592, "norm_label": "test_get_google_sso_default_redirect()", "id": "tests_test_prometheus_auth_coverage_test_get_google_sso_default_redirect" }, @@ -37919,7 +37973,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L42", - "community": 29, + "community": 112, "norm_label": "cover streammessage in agent.py.", "id": "tests_test_prometheus_auth_coverage_rationale_42" }, @@ -37955,7 +38009,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L470", - "community": 29, + "community": 519, "norm_label": "cover all methods in authentication.py (lines 13-75).", "id": "tests_test_prometheus_auth_coverage_rationale_470" }, @@ -37973,7 +38027,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L882", - "community": 60, + "community": 627, "norm_label": "exercises the tzinfo-is-none branch (line 144-148).", "id": "tests_test_prometheus_auth_coverage_rationale_882" }, @@ -37982,7 +38036,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L896", - "community": 60, + "community": 628, "norm_label": "exercises the expiresat-is-none branch (line 143).", "id": "tests_test_prometheus_auth_coverage_rationale_896" }, @@ -37991,7 +38045,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L915", - "community": 29, + "community": 112, "norm_label": "cover getgooglesso (lines 6-14).", "id": "tests_test_prometheus_auth_coverage_rationale_915" }, @@ -38018,7 +38072,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L44", - "community": 568, + "community": 518, "norm_label": "testmemorytoolfunctions", "id": "tests_test_prometheus_tools_testmemorytoolfunctions" }, @@ -38027,7 +38081,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L45", - "community": 568, + "community": 518, "norm_label": ".test_search_memory_has_docstring()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_search_memory_has_docstring" }, @@ -38036,7 +38090,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L49", - "community": 568, + "community": 518, "norm_label": ".test_save_memory_has_docstring()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_save_memory_has_docstring" }, @@ -38045,7 +38099,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L53", - "community": 568, + "community": 518, "norm_label": ".test_search_memory_signature()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_search_memory_signature" }, @@ -38054,7 +38108,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L59", - "community": 568, + "community": 518, "norm_label": ".test_save_memory_signature()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_save_memory_signature" }, @@ -38063,7 +38117,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L66", - "community": 568, + "community": 518, "norm_label": ".test_search_memory_has_type_hints()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_search_memory_has_type_hints" }, @@ -38072,7 +38126,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L71", - "community": 568, + "community": 518, "norm_label": ".test_save_memory_has_type_hints()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_save_memory_has_type_hints" }, @@ -38081,7 +38135,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L77", - "community": 568, + "community": 518, "norm_label": ".test_memory_tools_is_list_of_callables()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_memory_tools_is_list_of_callables" }, @@ -38090,7 +38144,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L83", - "community": 568, + "community": 518, "norm_label": ".test_memory_tool_names_unchanged()", "id": "tests_test_prometheus_tools_testmemorytoolfunctions_test_memory_tool_names_unchanged" }, @@ -38180,7 +38234,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L126", - "community": 100, + "community": 563, "norm_label": "testgeminicompatibility", "id": "tests_test_prometheus_tools_testgeminicompatibility" }, @@ -38198,7 +38252,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L135", - "community": 100, + "community": 563, "norm_label": ".test_no_harnessstate_in_any_signature()", "id": "tests_test_prometheus_tools_testgeminicompatibility_test_no_harnessstate_in_any_signature" }, @@ -38207,7 +38261,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L151", - "community": 100, + "community": 631, "norm_label": "testtoolregistry", "id": "tests_test_prometheus_tools_testtoolregistry" }, @@ -38216,7 +38270,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L152", - "community": 100, + "community": 631, "norm_label": ".test_registry_contains_memory_tools()", "id": "tests_test_prometheus_tools_testtoolregistry_test_registry_contains_memory_tools" }, @@ -38225,7 +38279,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L156", - "community": 100, + "community": 631, "norm_label": ".test_registry_values_are_callable()", "id": "tests_test_prometheus_tools_testtoolregistry_test_registry_values_are_callable" }, @@ -38234,7 +38288,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L160", - "community": 100, + "community": 631, "norm_label": ".test_registry_matches_tool_names()", "id": "tests_test_prometheus_tools_testtoolregistry_test_registry_matches_tool_names" }, @@ -38252,7 +38306,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_tools.py", "source_location": "L127", - "community": 100, + "community": 563, "norm_label": "every function in tool_registry must have gemini-safe signatures. custom cl", "id": "tests_test_prometheus_tools_rationale_127" }, @@ -38261,7 +38315,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_tools.py", "source_location": "L136", - "community": 100, + "community": 563, "norm_label": "regression: harnessstate must never leak into tool signatures.", "id": "tests_test_prometheus_tools_rationale_136" }, @@ -38639,7 +38693,7 @@ "file_type": "code", "source_file": "tests/test_roles.py", "source_location": "L1", - "community": 49, + "community": 527, "norm_label": "test_roles.py", "id": "tests_test_roles_py" }, @@ -38648,7 +38702,7 @@ "file_type": "code", "source_file": "tests/test_roles.py", "source_location": "L4", - "community": 45, + "community": 527, "norm_label": "testpermission", "id": "tests_test_roles_testpermission" }, @@ -38657,7 +38711,7 @@ "file_type": "code", "source_file": "tests/test_roles.py", "source_location": "L5", - "community": 45, + "community": 527, "norm_label": ".test_permission_enum_values()", "id": "tests_test_roles_testpermission_test_permission_enum_values" }, @@ -38666,7 +38720,7 @@ "file_type": "code", "source_file": "tests/test_roles.py", "source_location": "L10", - "community": 45, + "community": 527, "norm_label": ".test_permission_all_includes_all()", "id": "tests_test_roles_testpermission_test_permission_all_includes_all" }, @@ -39413,7 +39467,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L6", - "community": 544, + "community": 566, "norm_label": "testsandboxtooldefinitions", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions" }, @@ -39422,7 +39476,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L7", - "community": 544, + "community": 566, "norm_label": ".test_execute_code_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_execute_code_in_registry" }, @@ -39431,7 +39485,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L10", - "community": 544, + "community": 566, "norm_label": ".test_read_file_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_read_file_in_registry" }, @@ -39440,7 +39494,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L13", - "community": 544, + "community": 566, "norm_label": ".test_write_file_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_write_file_in_registry" }, @@ -39449,7 +39503,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L16", - "community": 544, + "community": 566, "norm_label": ".test_list_files_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_list_files_in_registry" }, @@ -39458,7 +39512,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L19", - "community": 544, + "community": 566, "norm_label": ".test_execute_code_has_docstring()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_execute_code_has_docstring" }, @@ -39890,7 +39944,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L1", - "community": 503, + "community": 231, "norm_label": "test_state_tools.py", "id": "tests_test_state_tools_py" }, @@ -39980,7 +40034,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L60", - "community": 503, + "community": 231, "norm_label": "testgetstate", "id": "tests_test_state_tools_testgetstate" }, @@ -39989,7 +40043,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L62", - "community": 503, + "community": 231, "norm_label": "test_get_state_specific_key()", "id": "tests_test_state_tools_test_get_state_specific_key" }, @@ -39998,7 +40052,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L69", - "community": 503, + "community": 231, "norm_label": "test_get_state_all()", "id": "tests_test_state_tools_test_get_state_all" }, @@ -40007,7 +40061,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L77", - "community": 503, + "community": 231, "norm_label": "test_get_state_missing_key()", "id": "tests_test_state_tools_test_get_state_missing_key" }, @@ -40016,7 +40070,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L83", - "community": 503, + "community": 231, "norm_label": "test_get_state_no_state()", "id": "tests_test_state_tools_test_get_state_no_state" }, @@ -40025,7 +40079,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L88", - "community": 503, + "community": 231, "norm_label": "testsetstate", "id": "tests_test_state_tools_testsetstate" }, @@ -40034,7 +40088,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L90", - "community": 503, + "community": 231, "norm_label": "test_set_state()", "id": "tests_test_state_tools_test_set_state" }, @@ -40052,7 +40106,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L102", - "community": 503, + "community": 231, "norm_label": "teststatedispatch", "id": "tests_test_state_tools_teststatedispatch" }, @@ -40061,7 +40115,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L104", - "community": 49, + "community": 231, "norm_label": "test_dispatch_get_state()", "id": "tests_test_state_tools_test_dispatch_get_state" }, @@ -40070,7 +40124,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L114", - "community": 503, + "community": 231, "norm_label": "test_dispatch_set_state()", "id": "tests_test_state_tools_test_dispatch_set_state" }, @@ -40592,7 +40646,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L419", - "community": 605, + "community": 572, "norm_label": ".test_deserialize_float_nan_direct()", "id": "tests_test_stocks_api_coverage_testdeserializejsoncolumns_test_deserialize_float_nan_direct" }, @@ -40601,7 +40655,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L433", - "community": 614, + "community": 577, "norm_label": ".test_deserialize_non_nan_float()", "id": "tests_test_stocks_api_coverage_testdeserializejsoncolumns_test_deserialize_non_nan_float" }, @@ -40628,7 +40682,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L473", - "community": 3, + "community": 520, "norm_label": ".test_deserialize_multiple_special_cols_with_none()", "id": "tests_test_stocks_api_coverage_testdeserializejsoncolumns_test_deserialize_multiple_special_cols_with_none" }, @@ -40853,7 +40907,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L686", - "community": 541, + "community": 28, "norm_label": ".test_historical_with_date_range()", "id": "tests_test_stocks_api_coverage_testqueryhistorical_test_historical_with_date_range" }, @@ -40871,7 +40925,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L701", - "community": 112, + "community": 63, "norm_label": ".test_historical_requires_search_fields_or_dates()", "id": "tests_test_stocks_api_coverage_testqueryhistorical_test_historical_requires_search_fields_or_dates" }, @@ -40880,7 +40934,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L712", - "community": 112, + "community": 63, "norm_label": "testqueryfundamental", "id": "tests_test_stocks_api_coverage_testqueryfundamental" }, @@ -40898,7 +40952,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L725", - "community": 112, + "community": 63, "norm_label": ".test_cache_not_initialized_raises_503()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_cache_not_initialized_raises_503" }, @@ -40952,7 +41006,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L766", - "community": 190, + "community": 39, "norm_label": ".test_fundamental_with_invalid_date()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_with_invalid_date" }, @@ -40997,7 +41051,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L802", - "community": 112, + "community": 63, "norm_label": ".test_fundamental_exception_returns_500()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_exception_returns_500" }, @@ -41006,7 +41060,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L819", - "community": 17, + "community": 39, "norm_label": ".test_fundamental_empty_search_string_no_dedup()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_empty_search_string_no_dedup" }, @@ -41015,7 +41069,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L828", - "community": 17, + "community": 39, "norm_label": ".test_fundamental_no_time_column()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_no_time_column" }, @@ -41024,7 +41078,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L841", - "community": 39, + "community": 17, "norm_label": ".test_fundamental_date_range_two_dates()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_date_range_two_dates" }, @@ -41051,7 +41105,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L882", - "community": 17, + "community": 39, "norm_label": ".test_fundamental_search_multiple_terms()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_search_multiple_terms" }, @@ -41060,7 +41114,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L890", - "community": 39, + "community": 17, "norm_label": ".test_fundamental_search_fallback_string_match()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_search_fallback_string_match" }, @@ -41069,7 +41123,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L898", - "community": 39, + "community": 17, "norm_label": ".test_fundamental_dates_one_date()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_dates_one_date" }, @@ -41078,7 +41132,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L913", - "community": 112, + "community": 63, "norm_label": ".test_fundamental_excludes_cotacao_10y()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_excludes_cotacao_10y" }, @@ -41096,7 +41150,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L963", - "community": 112, + "community": 3, "norm_label": ".test_fundamental_requires_search_fields_or_dates()", "id": "tests_test_stocks_api_coverage_testqueryfundamental_test_fundamental_requires_search_fields_or_dates" }, @@ -41258,7 +41312,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1139", - "community": 521, + "community": 10, "norm_label": ".test_cotations_http_route()", "id": "tests_test_stocks_api_coverage_testquerycotations_test_cotations_http_route" }, @@ -41348,7 +41402,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1265", - "community": 493, + "community": 22, "norm_label": ".test_http_route_search_required()", "id": "tests_test_stocks_api_coverage_testquerylivecotation_test_http_route_search_required" }, @@ -41384,7 +41438,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1315", - "community": 493, + "community": 546, "norm_label": ".test_cotations_search_required()", "id": "tests_test_stocks_api_coverage_testquerylivecotation_test_cotations_search_required" }, @@ -41546,7 +41600,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L420", - "community": 605, + "community": 572, "norm_label": "replacenan handles direct float nan values (line 34).", "id": "tests_test_stocks_api_coverage_rationale_420" }, @@ -41555,7 +41609,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L434", - "community": 614, + "community": 577, "norm_label": "non-json-dict/list string is left as-is.", "id": "tests_test_stocks_api_coverage_rationale_434" }, @@ -41582,7 +41636,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L474", - "community": 3, + "community": 520, "norm_label": "all four special_cols should parse correctly when mixed with none.", "id": "tests_test_stocks_api_coverage_rationale_474" }, @@ -41654,7 +41708,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L687", - "community": 541, + "community": 28, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_687" }, @@ -41672,7 +41726,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L702", - "community": 112, + "community": 63, "norm_label": "calling with all none returns 400.", "id": "tests_test_stocks_api_coverage_rationale_702" }, @@ -41681,7 +41735,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L713", - "community": 112, + "community": 63, "norm_label": "tests covering query.py lines 142-202.", "id": "tests_test_stocks_api_coverage_rationale_713" }, @@ -41690,7 +41744,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L767", - "community": 190, + "community": 39, "norm_label": "invalid date -> inner 400 passes through (not wrapped as 500).", "id": "tests_test_stocks_api_coverage_rationale_767" }, @@ -41699,7 +41753,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L820", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_820" }, @@ -41708,7 +41762,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L829", - "community": 17, + "community": 39, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_829" }, @@ -41717,7 +41771,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L842", - "community": 190, + "community": 17, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_842" }, @@ -41744,7 +41798,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L883", - "community": 17, + "community": 39, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_883" }, @@ -41753,7 +41807,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L891", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_891" }, @@ -41762,7 +41816,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L899", - "community": 39, + "community": 17, "norm_label": "len(daterange) == 1 -> per-ticker closest snapshot.", "id": "tests_test_stocks_api_coverage_rationale_899" }, @@ -41771,7 +41825,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L914", - "community": 112, + "community": 63, "norm_label": "cotacao 10y padrao and cotacao 10y ajustada belong to /cotations, not /fundament", "id": "tests_test_stocks_api_coverage_rationale_914" }, @@ -41825,7 +41879,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1140", - "community": 521, + "community": 10, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1140" }, @@ -41843,7 +41897,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1266", - "community": 493, + "community": 22, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1266" }, @@ -41852,7 +41906,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1316", - "community": 493, + "community": 546, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1316" }, @@ -43094,7 +43148,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L1", - "community": 574, + "community": 503, "norm_label": "test_type_aware_decay.py", "id": "tests_test_type_aware_decay_py" }, @@ -43103,7 +43157,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L11", - "community": 574, + "community": 503, "norm_label": "_create()", "id": "tests_test_type_aware_decay_create" }, @@ -43112,7 +43166,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L29", - "community": 574, + "community": 503, "norm_label": "testtypeawaredecay", "id": "tests_test_type_aware_decay_testtypeawaredecay" }, @@ -43121,7 +43175,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L30", - "community": 574, + "community": 503, "norm_label": ".test_preference_decays_slowly()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_preference_decays_slowly" }, @@ -43130,7 +43184,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L36", - "community": 574, + "community": 503, "norm_label": ".test_context_decays_fast()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_context_decays_fast" }, @@ -43139,7 +43193,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L42", - "community": 574, + "community": 503, "norm_label": ".test_analysis_decays_normally()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_analysis_decays_normally" }, @@ -43148,7 +43202,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L48", - "community": 574, + "community": 503, "norm_label": ".test_feedback_decays_medium()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_feedback_decays_medium" }, @@ -43157,7 +43211,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L54", - "community": 574, + "community": 503, "norm_label": ".test_unknown_type_uses_default()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_unknown_type_uses_default" }, @@ -43166,7 +43220,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L60", - "community": 574, + "community": 503, "norm_label": ".test_mixed_types_all_correct()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_mixed_types_all_correct" }, @@ -43175,7 +43229,7 @@ "file_type": "code", "source_file": "tests/test_type_aware_decay.py", "source_location": "L76", - "community": 574, + "community": 503, "norm_label": ".test_preference_survives_longer()", "id": "tests_test_type_aware_decay_testtypeawaredecay_test_preference_survives_longer" }, @@ -43184,7 +43238,7 @@ "file_type": "rationale", "source_file": "tests/test_type_aware_decay.py", "source_location": "L77", - "community": 574, + "community": 503, "norm_label": "after 10 cycles, preference (0.99^10) > context (0.90^10).", "id": "tests_test_type_aware_decay_rationale_77" }, @@ -43193,7 +43247,7 @@ "file_type": "code", "source_file": "tests/test_user_deps.py", "source_location": "L1", - "community": 528, + "community": 98, "norm_label": "test_user_deps.py", "id": "tests_test_user_deps_py" }, @@ -43328,7 +43382,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L1", - "community": 21, + "community": 131, "norm_label": "test_vector_utils.py", "id": "tests_test_vector_utils_py" }, @@ -43382,7 +43436,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L38", - "community": 546, + "community": 131, "norm_label": "testcontenthash", "id": "tests_test_vector_utils_testcontenthash" }, @@ -43391,7 +43445,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L39", - "community": 546, + "community": 131, "norm_label": ".test_deterministic()", "id": "tests_test_vector_utils_testcontenthash_test_deterministic" }, @@ -43400,7 +43454,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L42", - "community": 546, + "community": 131, "norm_label": ".test_different_inputs()", "id": "tests_test_vector_utils_testcontenthash_test_different_inputs" }, @@ -43409,7 +43463,7 @@ "file_type": "code", "source_file": "tests/test_vector_utils.py", "source_location": "L45", - "community": 546, + "community": 131, "norm_label": ".test_hex_format()", "id": "tests_test_vector_utils_testcontenthash_test_hex_format" }, @@ -44768,7 +44822,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1138", - "community": 566, + "community": 45, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1138" }, @@ -44777,7 +44831,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1152", - "community": 577, + "community": 14, "norm_label": "covers line 35: get /stocks/historical.", "id": "tests_test_controllers_coverage_rationale_1152" }, @@ -44786,7 +44840,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1166", - "community": 610, + "community": 14, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1166" }, @@ -44831,7 +44885,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1223", - "community": 616, + "community": 614, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1223" }, @@ -44849,7 +44903,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1243", - "community": 529, + "community": 620, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1243" }, @@ -44867,7 +44921,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1269", - "community": 563, + "community": 529, "norm_label": "covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: usermanager.getc", "id": "tests_test_controllers_coverage_rationale_1269" }, @@ -44876,7 +44930,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1301", - "community": 529, + "community": 625, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1301" }, @@ -44885,7 +44939,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1317", - "community": 589, + "community": 603, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1317" }, @@ -44894,7 +44948,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1334", - "community": 592, + "community": 604, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1334" }, @@ -44903,7 +44957,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1351", - "community": 602, + "community": 611, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1351" }, @@ -44921,7 +44975,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1385", - "community": 620, + "community": 194, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1385" }, @@ -44930,7 +44984,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1388", - "community": 620, + "community": 194, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1388" }, @@ -44939,7 +44993,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1404", - "community": 194, + "community": 172, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1404" }, @@ -45002,7 +45056,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L502", - "community": 29, + "community": 519, "norm_label": "cover all methods in authentication.py (lines 13-75).", "id": "tests_test_prometheus_auth_coverage_rationale_502" }, @@ -45020,7 +45074,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L914", - "community": 60, + "community": 627, "norm_label": "exercises the tzinfo-is-none branch (line 144-148).", "id": "tests_test_prometheus_auth_coverage_rationale_914" }, @@ -45029,7 +45083,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L928", - "community": 60, + "community": 628, "norm_label": "exercises the expiresat-is-none branch (line 143).", "id": "tests_test_prometheus_auth_coverage_rationale_928" }, @@ -45038,7 +45092,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L947", - "community": 29, + "community": 112, "norm_label": "cover getgooglesso (lines 6-14).", "id": "tests_test_prometheus_auth_coverage_rationale_947" }, @@ -45074,7 +45128,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L42", - "community": 136, + "community": 190, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_42" }, @@ -45083,7 +45137,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L79", - "community": 503, + "community": 231, "norm_label": "retrieve values from the harness state. use this to recall intermediate results,", "id": "prometheus_tools_rationale_79" }, @@ -45092,7 +45146,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L147", - "community": 221, + "community": 538, "norm_label": "read a file from the workspace. args: path: path to the file (e.", "id": "prometheus_tools_rationale_147" }, @@ -45398,7 +45452,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L131", - "community": 221, + "community": 538, "norm_label": "read a file from the sandbox filesystem. args: path: absolute pa", "id": "prometheus_tools_rationale_131" }, @@ -45596,7 +45650,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L130", - "community": 221, + "community": 538, "norm_label": "read a file from the sandbox filesystem. args: path: absolute pa", "id": "prometheus_tools_rationale_130" }, @@ -45605,7 +45659,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L7", - "community": 8, + "community": 560, "norm_label": "testagentsandboxintegration", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration" }, @@ -45614,7 +45668,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L8", - "community": 8, + "community": 560, "norm_label": ".test_build_system_prompt_includes_sandbox_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_includes_sandbox_instructions" }, @@ -45623,7 +45677,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L14", - "community": 8, + "community": 560, "norm_label": ".test_build_system_prompt_includes_state_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_includes_state_instructions" }, @@ -45632,7 +45686,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L19", - "community": 8, + "community": 560, "norm_label": ".test_build_system_prompt_with_state()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_with_state" }, @@ -45731,7 +45785,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L41", - "community": 136, + "community": 190, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_41" }, @@ -45740,7 +45794,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L78", - "community": 503, + "community": 231, "norm_label": "retrieve values from the harness state. use this to recall intermediate results,", "id": "prometheus_tools_rationale_78" }, @@ -47945,7 +47999,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_tools.py", "source_location": "L119", - "community": 100, + "community": 221, "norm_label": "test_set_state_no_state_returns_error()", "id": "tests_test_prometheus_tools_test_set_state_no_state_returns_error" }, @@ -47963,7 +48017,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_tools.py", "source_location": "L128", - "community": 100, + "community": 563, "norm_label": "every function in tool_registry must have gemini-safe signatures. custom cl", "id": "tests_test_prometheus_tools_rationale_128" }, @@ -47972,7 +48026,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_tools.py", "source_location": "L137", - "community": 100, + "community": 563, "norm_label": "regression: harnessstate must never leak into tool signatures.", "id": "tests_test_prometheus_tools_rationale_137" }, @@ -48089,7 +48143,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L139", - "community": 525, + "community": 521, "norm_label": "read_sandbox_file()", "id": "prometheus_tools_read_sandbox_file" }, @@ -48098,7 +48152,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L151", - "community": 525, + "community": 521, "norm_label": "upload_to_sandbox()", "id": "prometheus_tools_upload_to_sandbox" }, @@ -48107,7 +48161,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L165", - "community": 525, + "community": 521, "norm_label": "check_cache()", "id": "prometheus_tools_check_cache" }, @@ -48134,7 +48188,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L140", - "community": 525, + "community": 521, "norm_label": "read a file from the sandbox filesystem. args: path: absolute pa", "id": "prometheus_tools_rationale_140" }, @@ -48143,7 +48197,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L152", - "community": 525, + "community": 521, "norm_label": "upload a file to the sandbox filesystem. use this to push data files (csv,", "id": "prometheus_tools_rationale_152" }, @@ -48152,7 +48206,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L166", - "community": 525, + "community": 521, "norm_label": "check if a computed result exists in the cache. use before executing expens", "id": "prometheus_tools_rationale_166" }, @@ -48161,7 +48215,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L9", - "community": 8, + "community": 560, "norm_label": ".test_build_system_prompt_no_state()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_no_state" }, @@ -48170,7 +48224,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L20", - "community": 8, + "community": 560, "norm_label": ".test_build_system_prompt_empty_state()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_build_system_prompt_empty_state" }, @@ -48179,7 +48233,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L25", - "community": 8, + "community": 560, "norm_label": ".test_system_prompt_includes_state_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_system_prompt_includes_state_instructions" }, @@ -48188,7 +48242,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L30", - "community": 8, + "community": 560, "norm_label": ".test_system_prompt_includes_sandbox_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_system_prompt_includes_sandbox_instructions" }, @@ -48197,7 +48251,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L34", - "community": 8, + "community": 560, "norm_label": ".test_system_prompt_includes_cache_instructions()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_system_prompt_includes_cache_instructions" }, @@ -48206,7 +48260,7 @@ "file_type": "code", "source_file": "tests/test_agent_sandbox_integration.py", "source_location": "L38", - "community": 8, + "community": 560, "norm_label": ".test_makechat_uses_tool_registry()", "id": "tests_test_agent_sandbox_integration_testagentsandboxintegration_test_makechat_uses_tool_registry" }, @@ -48674,7 +48728,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L12", - "community": 544, + "community": 566, "norm_label": ".test_read_sandbox_file_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_read_sandbox_file_in_registry" }, @@ -48683,7 +48737,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L15", - "community": 544, + "community": 566, "norm_label": ".test_check_cache_in_registry()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_check_cache_in_registry" }, @@ -48692,7 +48746,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L23", - "community": 544, + "community": 566, "norm_label": ".test_read_sandbox_file_has_docstring()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_read_sandbox_file_has_docstring" }, @@ -48701,7 +48755,7 @@ "file_type": "code", "source_file": "tests/test_sandbox_tools.py", "source_location": "L28", - "community": 544, + "community": 566, "norm_label": ".test_check_cache_has_docstring()", "id": "tests_test_sandbox_tools_testsandboxtooldefinitions_test_check_cache_has_docstring" }, @@ -49430,7 +49484,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L77", - "community": 503, + "community": 231, "norm_label": "retrieve values from the harness state. use this to recall intermediate results,", "id": "prometheus_tools_rationale_77" }, @@ -49493,7 +49547,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L104", - "community": 503, + "community": 231, "norm_label": "executestatetool()", "id": "prometheus_tools_executestatetool" }, @@ -49511,7 +49565,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L39", - "community": 136, + "community": 190, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_39" }, @@ -49538,7 +49592,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L54", - "community": 503, + "community": 231, "norm_label": "testexecutestatetool", "id": "tests_test_state_tools_testexecutestatetool" }, @@ -49547,7 +49601,7 @@ "file_type": "code", "source_file": "tests/test_state_tools.py", "source_location": "L84", - "community": 503, + "community": 231, "norm_label": "test_unknown_tool()", "id": "tests_test_state_tools_test_unknown_tool" }, @@ -49574,7 +49628,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/state.py", "source_location": "L22", - "community": 568, + "community": 186, "norm_label": "store a value in state. marks state as changed for context injection.", "id": "prometheus_state_rationale_22" }, @@ -49637,7 +49691,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L38", - "community": 136, + "community": 190, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_38" }, @@ -49691,7 +49745,7 @@ "file_type": "code", "source_file": "main/app/prometheus/tools.py", "source_location": "L46", - "community": 525, + "community": 116, "norm_label": "executememorytool()", "id": "prometheus_tools_executememorytool" }, @@ -49700,7 +49754,7 @@ "file_type": "rationale", "source_file": "main/app/prometheus/tools.py", "source_location": "L29", - "community": 136, + "community": 190, "norm_label": "store a memory about the user's preferences, analysis results, or feedback.", "id": "prometheus_tools_rationale_29" }, @@ -49835,7 +49889,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L52", - "community": 627, + "community": 630, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_52" }, @@ -49871,7 +49925,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L57", - "community": 627, + "community": 630, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_57" }, @@ -49925,7 +49979,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L85", - "community": 574, + "community": 256, "norm_label": "score below threshold + accesscount=0 + 90+ days \u2192 archived.", "id": "tests_test_memory_maintenance_rationale_85" }, @@ -49934,7 +49988,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L92", - "community": 574, + "community": 256, "norm_label": "low score but accessed recently \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_92" }, @@ -49943,7 +49997,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L99", - "community": 574, + "community": 256, "norm_label": "zero access but score still above threshold \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_99" }, @@ -49952,7 +50006,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L106", - "community": 574, + "community": 256, "norm_label": "even with low score, if accessed \u2192 not archived.", "id": "tests_test_memory_maintenance_rationale_106" }, @@ -49961,7 +50015,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L113", - "community": 574, + "community": 256, "norm_label": "already archived memories are skipped.", "id": "tests_test_memory_maintenance_rationale_113" }, @@ -49979,7 +50033,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_maintenance.py", "source_location": "L143", - "community": 574, + "community": 635, "norm_label": "score that decays to >= threshold stays alive. 0.11 * 0.95 = 0.1045 >= 0.1.", "id": "tests_test_memory_maintenance_rationale_143" }, @@ -49997,7 +50051,7 @@ "file_type": "code", "source_file": "main/utils/models/loader.py", "source_location": "L23", - "community": 560, + "community": 116, "norm_label": "embed()", "id": "models_loader_embed" }, @@ -50177,7 +50231,7 @@ "file_type": "code", "source_file": "main/utils/models/loader.py", "source_location": "L11", - "community": 560, + "community": 222, "norm_label": "_downloadmodel()", "id": "models_loader_downloadmodel" }, @@ -50303,7 +50357,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1270", - "community": 563, + "community": 529, "norm_label": "covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: usermanager.getc", "id": "tests_test_controllers_coverage_rationale_1270" }, @@ -50312,7 +50366,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1277", - "community": 616, + "community": 614, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1277" }, @@ -50321,7 +50375,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1302", - "community": 529, + "community": 625, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1302" }, @@ -50330,7 +50384,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1318", - "community": 589, + "community": 603, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1318" }, @@ -50339,7 +50393,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1335", - "community": 592, + "community": 604, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1335" }, @@ -50348,7 +50402,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1352", - "community": 602, + "community": 611, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1352" }, @@ -50366,7 +50420,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1386", - "community": 45, + "community": 194, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1386" }, @@ -50375,7 +50429,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1389", - "community": 592, + "community": 604, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1389" }, @@ -50384,7 +50438,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1405", - "community": 194, + "community": 172, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1405" }, @@ -50636,7 +50690,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L56", - "community": 627, + "community": 630, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_56" }, @@ -50672,7 +50726,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L20", - "community": 546, + "community": 131, "norm_label": "contenthash()", "id": "utils_vector_contenthash" }, @@ -50969,7 +51023,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_tools_wiring.py", "source_location": "L48", - "community": 627, + "community": 630, "norm_label": "makechat must include memory_tools alongside mcp sessions.", "id": "tests_test_memory_tools_wiring_rationale_48" }, @@ -51068,7 +51122,7 @@ "file_type": "code", "source_file": "main/controller/prometheus_controller.py", "source_location": "L177", - "community": 560, + "community": 116, "norm_label": "creatememory()", "id": "controller_prometheus_controller_creatememory" }, @@ -51140,7 +51194,7 @@ "file_type": "code", "source_file": "tests/test_memory_controller.py", "source_location": "L38", - "community": 493, + "community": 72, "norm_label": ".test_get_memories_rejects_basic_user()", "id": "tests_test_memory_controller_testmemorycontrollerroutes_test_get_memories_rejects_basic_user" }, @@ -51239,7 +51293,7 @@ "file_type": "rationale", "source_file": "main/utils/vector.py", "source_location": "L19", - "community": 546, + "community": 131, "norm_label": "md5 hash for change detection.", "id": "utils_vector_rationale_19" }, @@ -51878,7 +51932,7 @@ "file_type": "code", "source_file": "main/controller/prometheus_controller.py", "source_location": "L177", - "community": 560, + "community": 116, "norm_label": "create_memory()", "id": "controller_prometheus_controller_create_memory" }, @@ -51932,7 +51986,7 @@ "file_type": "code", "source_file": "main/utils/vector.py", "source_location": "L41", - "community": 546, + "community": 131, "norm_label": "content_hash()", "id": "utils_vector_content_hash" }, @@ -51968,7 +52022,7 @@ "file_type": "rationale", "source_file": "main/utils/vector.py", "source_location": "L42", - "community": 546, + "community": 131, "norm_label": "md5 hash for change detection.", "id": "utils_vector_rationale_42" }, @@ -52022,7 +52076,7 @@ "file_type": "rationale", "source_file": "tests/test_memory_controller.py", "source_location": "L47", - "community": 493, + "community": 72, "norm_label": "get /memories requires use_prometheus (basic user role denied).", "id": "tests_test_memory_controller_rationale_47" }, @@ -52463,7 +52517,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L101", - "community": 546, + "community": 131, "norm_label": "same input \u2192 same hash.", "id": "tests_test_vector_utils_rationale_101" }, @@ -52472,7 +52526,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L105", - "community": 546, + "community": 131, "norm_label": "different inputs \u2192 different hashes.", "id": "tests_test_vector_utils_rationale_105" }, @@ -52481,7 +52535,7 @@ "file_type": "rationale", "source_file": "tests/test_vector_utils.py", "source_location": "L109", - "community": 546, + "community": 131, "norm_label": "returns 32-char hex string.", "id": "tests_test_vector_utils_rationale_109" }, @@ -52760,7 +52814,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L492", - "community": 29, + "community": 519, "norm_label": "cover all methods in authentication.py (lines 13-75).", "id": "tests_test_prometheus_auth_coverage_rationale_492" }, @@ -52778,7 +52832,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L904", - "community": 60, + "community": 627, "norm_label": "exercises the tzinfo-is-none branch (line 144-148).", "id": "tests_test_prometheus_auth_coverage_rationale_904" }, @@ -52787,7 +52841,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L918", - "community": 60, + "community": 628, "norm_label": "exercises the expiresat-is-none branch (line 143).", "id": "tests_test_prometheus_auth_coverage_rationale_918" }, @@ -52796,7 +52850,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L937", - "community": 29, + "community": 112, "norm_label": "cover getgooglesso (lines 6-14).", "id": "tests_test_prometheus_auth_coverage_rationale_937" }, @@ -53039,7 +53093,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L27", - "community": 29, + "community": 112, "norm_label": "cover __init__ and updatedates.", "id": "tests_test_prometheus_auth_coverage_rationale_27" }, @@ -53048,7 +53102,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L58", - "community": 29, + "community": 112, "norm_label": "cover sendmessage and streammessage in agent.py.", "id": "tests_test_prometheus_auth_coverage_rationale_58" }, @@ -53066,7 +53120,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L398", - "community": 29, + "community": 519, "norm_label": "cover all methods in authentication.py (lines 13-75).", "id": "tests_test_prometheus_auth_coverage_rationale_398" }, @@ -53084,7 +53138,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L810", - "community": 60, + "community": 627, "norm_label": "exercises the tzinfo-is-none branch (line 144-148).", "id": "tests_test_prometheus_auth_coverage_rationale_810" }, @@ -53093,7 +53147,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L824", - "community": 60, + "community": 628, "norm_label": "exercises the expiresat-is-none branch (line 143).", "id": "tests_test_prometheus_auth_coverage_rationale_824" }, @@ -53102,7 +53156,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L843", - "community": 29, + "community": 112, "norm_label": "cover getgooglesso (lines 6-14).", "id": "tests_test_prometheus_auth_coverage_rationale_843" }, @@ -53111,7 +53165,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L26", - "community": 29, + "community": 112, "norm_label": "testprometheusgeneratorinit", "id": "tests_test_prometheus_auth_coverage_testprometheusgeneratorinit" }, @@ -53120,7 +53174,7 @@ "file_type": "code", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L57", - "community": 29, + "community": 112, "norm_label": "testprometheusgeneratorexecuteworkflow", "id": "tests_test_prometheus_auth_coverage_testprometheusgeneratorexecuteworkflow" }, @@ -53309,7 +53363,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L664", - "community": 29, + "community": 519, "norm_label": "cover all methods in authentication.py (lines 13-75).", "id": "tests_test_prometheus_auth_coverage_rationale_664" }, @@ -53327,7 +53381,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L1076", - "community": 60, + "community": 627, "norm_label": "exercises the tzinfo-is-none branch (line 144-148).", "id": "tests_test_prometheus_auth_coverage_rationale_1076" }, @@ -53336,7 +53390,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L1090", - "community": 60, + "community": 628, "norm_label": "exercises the expiresat-is-none branch (line 143).", "id": "tests_test_prometheus_auth_coverage_rationale_1090" }, @@ -53345,7 +53399,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L1109", - "community": 29, + "community": 112, "norm_label": "cover getgooglesso (lines 6-14).", "id": "tests_test_prometheus_auth_coverage_rationale_1109" }, @@ -53471,7 +53525,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L74", - "community": 561, + "community": 544, "norm_label": "testclient with stocks router + verifyapikey + getcurrentuser overrides.", "id": "tests_conftest_rationale_74" }, @@ -53480,7 +53534,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L99", - "community": 561, + "community": 544, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_99" }, @@ -53507,7 +53561,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L538", - "community": 45, + "community": 47, "norm_label": "covers line 24: get /user/me returns currentuser.", "id": "tests_test_controllers_coverage_rationale_538" }, @@ -53534,7 +53588,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L611", - "community": 45, + "community": 610, "norm_label": "covers lines 66, 68-72, 74: get /user/sessions.", "id": "tests_test_controllers_coverage_rationale_611" }, @@ -53543,7 +53597,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L614", - "community": 63, + "community": 610, "norm_label": "covers lines 66, 68-72, 74: full sessions listing.", "id": "tests_test_controllers_coverage_rationale_614" }, @@ -53552,7 +53606,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L665", - "community": 45, + "community": 493, "norm_label": "covers lines 100-104, 106: get /user/sessions/current.", "id": "tests_test_controllers_coverage_rationale_665" }, @@ -53561,7 +53615,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L668", - "community": 63, + "community": 493, "norm_label": "covers lines 100-104, 106: session found.", "id": "tests_test_controllers_coverage_rationale_668" }, @@ -53570,7 +53624,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L701", - "community": 63, + "community": 493, "norm_label": "covers line 104: session not found.", "id": "tests_test_controllers_coverage_rationale_701" }, @@ -53615,7 +53669,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L802", - "community": 45, + "community": 498, "norm_label": "covers lines 143, 145, 147-148: post /user/sessions/revoke-all.", "id": "tests_test_controllers_coverage_rationale_802" }, @@ -53624,7 +53678,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L805", - "community": 63, + "community": 498, "norm_label": "covers lines 143, 145, 147-148.", "id": "tests_test_controllers_coverage_rationale_805" }, @@ -53642,7 +53696,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L846", - "community": 45, + "community": 99, "norm_label": "covers lines 33-36: get /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_846" }, @@ -53651,7 +53705,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L864", - "community": 45, + "community": 99, "norm_label": "covers line 52: post /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_864" }, @@ -53696,7 +53750,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L912", - "community": 256, + "community": 498, "norm_label": "covers lines 77, 83-84, 86: get /prometheus/history/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_912" }, @@ -53705,7 +53759,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L915", - "community": 256, + "community": 498, "norm_label": "covers lines 77, 86: session found with history.", "id": "tests_test_controllers_coverage_rationale_915" }, @@ -53714,7 +53768,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L959", - "community": 256, + "community": 498, "norm_label": "covers lines 83-84: session not found.", "id": "tests_test_controllers_coverage_rationale_959" }, @@ -53723,7 +53777,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L994", - "community": 535, + "community": 99, "norm_label": "covers lines 95-98: delete /prometheus/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_994" }, @@ -53732,7 +53786,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L997", - "community": 535, + "community": 99, "norm_label": "covers lines 95-98: session deleted.", "id": "tests_test_controllers_coverage_rationale_997" }, @@ -53741,7 +53795,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1007", - "community": 535, + "community": 99, "norm_label": "covers lines 96-97: session not found.", "id": "tests_test_controllers_coverage_rationale_1007" }, @@ -53759,7 +53813,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1020", - "community": 148, + "community": 99, "norm_label": "covers lines 111-112: sessionid is none, new session created.", "id": "tests_test_controllers_coverage_rationale_1020" }, @@ -53795,7 +53849,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1134", - "community": 566, + "community": 45, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1134" }, @@ -53804,7 +53858,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1148", - "community": 577, + "community": 14, "norm_label": "covers line 35: get /stocks/historical.", "id": "tests_test_controllers_coverage_rationale_1148" }, @@ -53813,7 +53867,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1162", - "community": 610, + "community": 14, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1162" }, @@ -53858,7 +53912,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1219", - "community": 616, + "community": 614, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1219" }, @@ -53876,7 +53930,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1239", - "community": 529, + "community": 620, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1239" }, @@ -53894,7 +53948,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1266", - "community": 563, + "community": 529, "norm_label": "covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: usermanager.getc", "id": "tests_test_controllers_coverage_rationale_1266" }, @@ -53903,7 +53957,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1273", - "community": 563, + "community": 529, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1273" }, @@ -53912,7 +53966,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1298", - "community": 529, + "community": 625, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1298" }, @@ -53921,7 +53975,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1314", - "community": 589, + "community": 603, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1314" }, @@ -53930,7 +53984,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1331", - "community": 592, + "community": 604, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1331" }, @@ -53939,7 +53993,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1348", - "community": 602, + "community": 611, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1348" }, @@ -53948,7 +54002,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1372", - "community": 589, + "community": 603, "norm_label": "covers line 16: empty password raises valueerror.", "id": "tests_test_controllers_coverage_rationale_1372" }, @@ -53957,7 +54011,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1401", - "community": 194, + "community": 172, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1401" }, @@ -54119,7 +54173,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L536", - "community": 45, + "community": 47, "norm_label": "covers line 24: get /user/me returns currentuser.", "id": "tests_test_controllers_coverage_rationale_536" }, @@ -54146,7 +54200,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L609", - "community": 45, + "community": 610, "norm_label": "covers lines 66, 68-72, 74: get /user/sessions.", "id": "tests_test_controllers_coverage_rationale_609" }, @@ -54155,7 +54209,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L612", - "community": 63, + "community": 610, "norm_label": "covers lines 66, 68-72, 74: full sessions listing.", "id": "tests_test_controllers_coverage_rationale_612" }, @@ -54164,7 +54218,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L663", - "community": 45, + "community": 493, "norm_label": "covers lines 100-104, 106: get /user/sessions/current.", "id": "tests_test_controllers_coverage_rationale_663" }, @@ -54173,7 +54227,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L666", - "community": 63, + "community": 493, "norm_label": "covers lines 100-104, 106: session found.", "id": "tests_test_controllers_coverage_rationale_666" }, @@ -54182,7 +54236,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L699", - "community": 63, + "community": 493, "norm_label": "covers line 104: session not found.", "id": "tests_test_controllers_coverage_rationale_699" }, @@ -54227,7 +54281,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L800", - "community": 45, + "community": 498, "norm_label": "covers lines 143, 145, 147-148: post /user/sessions/revoke-all.", "id": "tests_test_controllers_coverage_rationale_800" }, @@ -54236,7 +54290,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L803", - "community": 63, + "community": 498, "norm_label": "covers lines 143, 145, 147-148.", "id": "tests_test_controllers_coverage_rationale_803" }, @@ -54254,7 +54308,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L844", - "community": 45, + "community": 99, "norm_label": "covers lines 33-36: get /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_844" }, @@ -54263,7 +54317,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L862", - "community": 45, + "community": 99, "norm_label": "covers line 52: post /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_862" }, @@ -54308,7 +54362,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L910", - "community": 256, + "community": 498, "norm_label": "covers lines 77, 83-84, 86: get /prometheus/history/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_910" }, @@ -54317,7 +54371,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L913", - "community": 256, + "community": 498, "norm_label": "covers lines 77, 86: session found with history.", "id": "tests_test_controllers_coverage_rationale_913" }, @@ -54326,7 +54380,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L957", - "community": 256, + "community": 498, "norm_label": "covers lines 83-84: session not found.", "id": "tests_test_controllers_coverage_rationale_957" }, @@ -54335,7 +54389,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L992", - "community": 535, + "community": 99, "norm_label": "covers lines 95-98: delete /prometheus/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_992" }, @@ -54344,7 +54398,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L995", - "community": 535, + "community": 99, "norm_label": "covers lines 95-98: session deleted.", "id": "tests_test_controllers_coverage_rationale_995" }, @@ -54353,7 +54407,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1005", - "community": 535, + "community": 99, "norm_label": "covers lines 96-97: session not found.", "id": "tests_test_controllers_coverage_rationale_1005" }, @@ -54371,7 +54425,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1018", - "community": 148, + "community": 99, "norm_label": "covers lines 111-112: sessionid is none, new session created.", "id": "tests_test_controllers_coverage_rationale_1018" }, @@ -54407,7 +54461,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1133", - "community": 566, + "community": 45, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1133" }, @@ -54416,7 +54470,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1147", - "community": 577, + "community": 14, "norm_label": "covers line 35: get /stocks/historical.", "id": "tests_test_controllers_coverage_rationale_1147" }, @@ -54425,7 +54479,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1161", - "community": 610, + "community": 14, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1161" }, @@ -54461,7 +54515,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1218", - "community": 616, + "community": 614, "norm_label": "covers lines 13, 17, 19-20, 22-27: usermanager.addroletouser.", "id": "tests_test_controllers_coverage_rationale_1218" }, @@ -54479,7 +54533,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1238", - "community": 529, + "community": 620, "norm_label": "covers line 27: user already has the role.", "id": "tests_test_controllers_coverage_rationale_1238" }, @@ -54497,7 +54551,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1265", - "community": 563, + "community": 529, "norm_label": "covers lines 34, 36-38, 40-44, 46, 48-49, 51, 58-59, 61, 63-67: usermanager.getc", "id": "tests_test_controllers_coverage_rationale_1265" }, @@ -54506,7 +54560,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1272", - "community": 563, + "community": 529, "norm_label": "covers lines 36-38, 40-44, 46, 48-49, 51, 58-59, 61: successful user retrieval.", "id": "tests_test_controllers_coverage_rationale_1272" }, @@ -54515,7 +54569,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1297", - "community": 529, + "community": 620, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1297" }, @@ -54524,7 +54578,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1313", - "community": 589, + "community": 603, "norm_label": "covers lines 48-49: user not in db.", "id": "tests_test_controllers_coverage_rationale_1313" }, @@ -54533,7 +54587,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1330", - "community": 592, + "community": 604, "norm_label": "covers lines 65-67: unexpected exception.", "id": "tests_test_controllers_coverage_rationale_1330" }, @@ -54542,7 +54596,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1347", - "community": 602, + "community": 611, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1347" }, @@ -54560,7 +54614,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1381", - "community": 45, + "community": 194, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1381" }, @@ -54569,7 +54623,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1384", - "community": 620, + "community": 194, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1384" }, @@ -54578,7 +54632,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1400", - "community": 194, + "community": 172, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1400" }, @@ -55046,7 +55100,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L496", - "community": 605, + "community": 572, "norm_label": "replacenan handles direct float nan values (line 34).", "id": "tests_test_stocks_api_coverage_rationale_496" }, @@ -55055,7 +55109,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L510", - "community": 614, + "community": 577, "norm_label": "non-json-dict/list string is left as-is.", "id": "tests_test_stocks_api_coverage_rationale_510" }, @@ -55082,7 +55136,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L550", - "community": 3, + "community": 520, "norm_label": "all four special_cols should parse correctly when mixed with none.", "id": "tests_test_stocks_api_coverage_rationale_550" }, @@ -55163,7 +55217,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L778", - "community": 112, + "community": 63, "norm_label": "calling with all none returns 400.", "id": "tests_test_stocks_api_coverage_rationale_778" }, @@ -55172,7 +55226,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L789", - "community": 112, + "community": 63, "norm_label": "tests covering query.py lines 142-202.", "id": "tests_test_stocks_api_coverage_rationale_789" }, @@ -55181,7 +55235,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L843", - "community": 190, + "community": 39, "norm_label": "invalid date -> inner 400 passes through (not wrapped as 500).", "id": "tests_test_stocks_api_coverage_rationale_843" }, @@ -55190,7 +55244,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L896", - "community": 39, + "community": 17, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_896" }, @@ -55199,7 +55253,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L905", - "community": 39, + "community": 17, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_905" }, @@ -55208,7 +55262,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L918", - "community": 39, + "community": 17, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_918" }, @@ -55235,7 +55289,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L959", - "community": 17, + "community": 39, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_959" }, @@ -55244,7 +55298,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L967", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_967" }, @@ -55253,7 +55307,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L975", - "community": 39, + "community": 17, "norm_label": "len(daterange) == 1 -> per-ticker closest snapshot.", "id": "tests_test_stocks_api_coverage_rationale_975" }, @@ -55262,7 +55316,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L990", - "community": 112, + "community": 63, "norm_label": "cotacao 10y padrao and cotacao 10y ajustada belong to /cotations, not /fundament", "id": "tests_test_stocks_api_coverage_rationale_990" }, @@ -55316,7 +55370,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1216", - "community": 521, + "community": 10, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1216" }, @@ -55334,7 +55388,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1342", - "community": 493, + "community": 22, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1342" }, @@ -55343,7 +55397,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1392", - "community": 493, + "community": 546, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1392" }, @@ -55469,7 +55523,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1344", - "community": 493, + "community": 22, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1344" }, @@ -55478,7 +55532,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1394", - "community": 493, + "community": 546, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1394" }, @@ -55658,7 +55712,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1400", - "community": 493, + "community": 22, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1400" }, @@ -55667,7 +55721,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1468", - "community": 493, + "community": 546, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1468" }, @@ -55811,7 +55865,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L495", - "community": 605, + "community": 572, "norm_label": "replacenan handles direct float nan values (line 34).", "id": "tests_test_stocks_api_coverage_rationale_495" }, @@ -55820,7 +55874,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L509", - "community": 614, + "community": 577, "norm_label": "non-json-dict/list string is left as-is.", "id": "tests_test_stocks_api_coverage_rationale_509" }, @@ -55847,7 +55901,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L549", - "community": 3, + "community": 520, "norm_label": "all four special_cols should parse correctly when mixed with none.", "id": "tests_test_stocks_api_coverage_rationale_549" }, @@ -55919,7 +55973,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L762", - "community": 541, + "community": 28, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_762" }, @@ -55937,7 +55991,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L777", - "community": 112, + "community": 63, "norm_label": "calling with all none returns 400.", "id": "tests_test_stocks_api_coverage_rationale_777" }, @@ -55946,7 +56000,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L788", - "community": 112, + "community": 63, "norm_label": "tests covering query.py lines 142-202.", "id": "tests_test_stocks_api_coverage_rationale_788" }, @@ -55955,7 +56009,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L895", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_895" }, @@ -55964,7 +56018,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L904", - "community": 17, + "community": 39, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_904" }, @@ -55973,7 +56027,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L917", - "community": 39, + "community": 17, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_917" }, @@ -55991,7 +56045,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L956", - "community": 17, + "community": 39, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_956" }, @@ -56000,7 +56054,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L964", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_964" }, @@ -56009,7 +56063,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L972", - "community": 39, + "community": 17, "norm_label": "len(daterange) == 1 -> single date filter.", "id": "tests_test_stocks_api_coverage_rationale_972" }, @@ -56018,7 +56072,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L986", - "community": 112, + "community": 63, "norm_label": "cotacao 10y padrao and cotacao 10y ajustada belong to /cotations, not /fundament", "id": "tests_test_stocks_api_coverage_rationale_986" }, @@ -56072,7 +56126,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1212", - "community": 521, + "community": 10, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1212" }, @@ -56090,7 +56144,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1396", - "community": 493, + "community": 22, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1396" }, @@ -56099,7 +56153,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1464", - "community": 493, + "community": 546, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1464" }, @@ -56126,7 +56180,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1388", - "community": 493, + "community": 22, "norm_label": "get /stocks/realtime-cotation without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1388" }, @@ -56135,7 +56189,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1456", - "community": 493, + "community": 546, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1456" }, @@ -56171,7 +56225,7 @@ "file_type": "code", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1297", - "community": 493, + "community": 120, "norm_label": ".test_cotations_search_required()", "id": "tests_test_stocks_api_coverage_testquerycotations_test_cotations_search_required" }, @@ -56180,7 +56234,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1298", - "community": 493, + "community": 120, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1298" }, @@ -56216,7 +56270,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1210", - "community": 521, + "community": 10, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1210" }, @@ -56225,7 +56279,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1288", - "community": 493, + "community": 120, "norm_label": "get /cotations without search returns 422.", "id": "tests_test_stocks_api_coverage_rationale_1288" }, @@ -56234,7 +56288,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L832", - "community": 17, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_832" }, @@ -56243,7 +56297,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L885", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_885" }, @@ -56252,7 +56306,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L894", - "community": 17, + "community": 39, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_894" }, @@ -56261,7 +56315,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L907", - "community": 39, + "community": 17, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_907" }, @@ -56279,7 +56333,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L946", - "community": 17, + "community": 39, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_946" }, @@ -56288,7 +56342,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L954", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_954" }, @@ -56297,7 +56351,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L962", - "community": 39, + "community": 17, "norm_label": "len(daterange) == 1 -> single date filter.", "id": "tests_test_stocks_api_coverage_rationale_962" }, @@ -56306,7 +56360,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L976", - "community": 112, + "community": 63, "norm_label": "cotacao 10y padrao and cotacao 10y ajustada belong to /cotations, not /fundament", "id": "tests_test_stocks_api_coverage_rationale_976" }, @@ -56360,7 +56414,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1191", - "community": 521, + "community": 10, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1191" }, @@ -56891,7 +56945,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1170", - "community": 521, + "community": 10, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1170" }, @@ -56936,7 +56990,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1141", - "community": 521, + "community": 10, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1141" }, @@ -56999,7 +57053,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L63", - "community": 157, + "community": 197, "norm_label": "getrealtimecotation()", "id": "controller_stocksapi_controller_getrealtimecotation" }, @@ -57017,7 +57071,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L1148", - "community": 521, + "community": 10, "norm_label": "hit the actual /stocks/cotations http endpoint with adjusted=false.", "id": "tests_test_stocks_api_coverage_rationale_1148" }, @@ -57044,7 +57098,7 @@ "file_type": "code", "source_file": "main/app/prometheus/chat.py", "source_location": "L14", - "community": 29, + "community": 112, "norm_label": ".__init__()", "id": "prometheus_chat_prometheuschatmanager_init" }, @@ -57107,7 +57161,7 @@ "file_type": "code", "source_file": "main/controller/stocksapi_controller.py", "source_location": "L23", - "community": 157, + "community": 197, "norm_label": "apikeytest()", "id": "controller_stocksapi_controller_apikeytest" }, @@ -57161,7 +57215,7 @@ "file_type": "code", "source_file": "main/utils/http_session.py", "source_location": "L18", - "community": 603, + "community": 184, "norm_label": "cleanup()", "id": "utils_http_session_cleanup" }, @@ -57170,7 +57224,7 @@ "file_type": "code", "source_file": "main/utils/pagination.py", "source_location": "L1", - "community": 502, + "community": 576, "norm_label": "pagination.py", "id": "main_utils_pagination_py" }, @@ -57179,7 +57233,7 @@ "file_type": "code", "source_file": "main/utils/pagination.py", "source_location": "L4", - "community": 502, + "community": 576, "norm_label": "paginationparams", "id": "utils_pagination_paginationparams" }, @@ -57188,7 +57242,7 @@ "file_type": "code", "source_file": "main/utils/pagination.py", "source_location": "L5", - "community": 502, + "community": 576, "norm_label": ".__init__()", "id": "utils_pagination_paginationparams_init" }, @@ -57206,7 +57260,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L75", - "community": 561, + "community": 544, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_75" }, @@ -57386,7 +57440,7 @@ "file_type": "code", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1194", - "community": 45, + "community": 14, "norm_label": "teststocksapikeytest", "id": "tests_test_controllers_coverage_teststocksapikeytest" }, @@ -57431,7 +57485,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L148", - "community": 45, + "community": 120, "norm_label": "covers lines 44-54, 63, 66-71: register success, valueerror, generic exception.", "id": "tests_test_controllers_coverage_rationale_148" }, @@ -57458,7 +57512,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L228", - "community": 45, + "community": 120, "norm_label": "covers lines 87-93, 102: login success and failure paths.", "id": "tests_test_controllers_coverage_rationale_228" }, @@ -57566,7 +57620,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L425", - "community": 45, + "community": 120, "norm_label": "covers lines 155-156, 158, 160-168, 170-177, 179-184, 186, 190-204: googlecallba", "id": "tests_test_controllers_coverage_rationale_425" }, @@ -57611,7 +57665,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L581", - "community": 45, + "community": 47, "norm_label": "covers line 24: get /user/me returns currentuser.", "id": "tests_test_controllers_coverage_rationale_581" }, @@ -57638,7 +57692,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L654", - "community": 45, + "community": 610, "norm_label": "covers lines 66, 68-72, 74: get /user/sessions.", "id": "tests_test_controllers_coverage_rationale_654" }, @@ -57647,7 +57701,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L657", - "community": 63, + "community": 610, "norm_label": "covers lines 66, 68-72, 74: full sessions listing.", "id": "tests_test_controllers_coverage_rationale_657" }, @@ -57656,7 +57710,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L708", - "community": 45, + "community": 493, "norm_label": "covers lines 100-104, 106: get /user/sessions/current.", "id": "tests_test_controllers_coverage_rationale_708" }, @@ -57665,7 +57719,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L711", - "community": 63, + "community": 493, "norm_label": "covers lines 100-104, 106: session found.", "id": "tests_test_controllers_coverage_rationale_711" }, @@ -57674,7 +57728,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L744", - "community": 63, + "community": 493, "norm_label": "covers line 104: session not found.", "id": "tests_test_controllers_coverage_rationale_744" }, @@ -57719,7 +57773,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L845", - "community": 45, + "community": 498, "norm_label": "covers lines 143, 145, 147-148: post /user/sessions/revoke-all.", "id": "tests_test_controllers_coverage_rationale_845" }, @@ -57728,7 +57782,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L848", - "community": 63, + "community": 498, "norm_label": "covers lines 143, 145, 147-148.", "id": "tests_test_controllers_coverage_rationale_848" }, @@ -57746,7 +57800,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L889", - "community": 45, + "community": 99, "norm_label": "covers lines 33-36: get /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_889" }, @@ -57755,7 +57809,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L907", - "community": 45, + "community": 99, "norm_label": "covers line 52: post /prometheus/sessions.", "id": "tests_test_controllers_coverage_rationale_907" }, @@ -57800,7 +57854,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L955", - "community": 256, + "community": 498, "norm_label": "covers lines 77, 83-84, 86: get /prometheus/history/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_955" }, @@ -57809,7 +57863,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L958", - "community": 256, + "community": 498, "norm_label": "covers lines 77, 86: session found with history.", "id": "tests_test_controllers_coverage_rationale_958" }, @@ -57818,7 +57872,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1002", - "community": 256, + "community": 498, "norm_label": "covers lines 83-84: session not found.", "id": "tests_test_controllers_coverage_rationale_1002" }, @@ -57827,7 +57881,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1037", - "community": 535, + "community": 99, "norm_label": "covers lines 95-98: delete /prometheus/sessions/{sessionid}.", "id": "tests_test_controllers_coverage_rationale_1037" }, @@ -57836,7 +57890,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1040", - "community": 535, + "community": 99, "norm_label": "covers lines 95-98: session deleted.", "id": "tests_test_controllers_coverage_rationale_1040" }, @@ -57845,7 +57899,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1050", - "community": 535, + "community": 99, "norm_label": "covers lines 96-97: session not found.", "id": "tests_test_controllers_coverage_rationale_1050" }, @@ -57863,7 +57917,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1063", - "community": 148, + "community": 99, "norm_label": "covers lines 111-112: sessionid is none, new session created.", "id": "tests_test_controllers_coverage_rationale_1063" }, @@ -57899,7 +57953,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1181", - "community": 566, + "community": 45, "norm_label": "covers line 18: get /stocks/health.", "id": "tests_test_controllers_coverage_rationale_1181" }, @@ -57917,7 +57971,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1206", - "community": 577, + "community": 14, "norm_label": "covers line 35: get /stocks/historical.", "id": "tests_test_controllers_coverage_rationale_1206" }, @@ -57926,7 +57980,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1220", - "community": 610, + "community": 14, "norm_label": "covers line 47: get /stocks/fundamental.", "id": "tests_test_controllers_coverage_rationale_1220" }, @@ -57980,7 +58034,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1356", - "community": 529, + "community": 625, "norm_label": "covers lines 42-44: session validation fails.", "id": "tests_test_controllers_coverage_rationale_1356" }, @@ -57989,7 +58043,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1406", - "community": 602, + "community": 611, "norm_label": "covers lines 37-38, 46, 51, 58 (sessionid is none): skips session validation.", "id": "tests_test_controllers_coverage_rationale_1406" }, @@ -58007,7 +58061,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1440", - "community": 45, + "community": 194, "norm_label": "covers lines 45-51: verifyaccesstoken with expired and invalid tokens.", "id": "tests_test_controllers_coverage_rationale_1440" }, @@ -58016,7 +58070,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1443", - "community": 620, + "community": 194, "norm_label": "covers lines 48-49: jwt.expiredsignatureerror.", "id": "tests_test_controllers_coverage_rationale_1443" }, @@ -58025,7 +58079,7 @@ "file_type": "rationale", "source_file": "tests/test_controllers_coverage.py", "source_location": "L1459", - "community": 194, + "community": 172, "norm_label": "covers lines 50-51: jwt.invalidtokenerror.", "id": "tests_test_controllers_coverage_rationale_1459" }, @@ -58061,7 +58115,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L9", - "community": 590, + "community": 561, "norm_label": ".test_creates_new_session()", "id": "tests_test_http_session_coverage_testgetsession_test_creates_new_session" }, @@ -58070,7 +58124,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L28", - "community": 603, + "community": 184, "norm_label": "testcleanup", "id": "tests_test_http_session_coverage_testcleanup" }, @@ -58079,7 +58133,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L29", - "community": 603, + "community": 184, "norm_label": ".test_cleanup_closes_session()", "id": "tests_test_http_session_coverage_testcleanup_test_cleanup_closes_session" }, @@ -58088,7 +58142,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L37", - "community": 603, + "community": 184, "norm_label": ".test_cleanup_no_session()", "id": "tests_test_http_session_coverage_testcleanup_test_cleanup_no_session" }, @@ -58097,7 +58151,7 @@ "file_type": "code", "source_file": "tests/test_http_session_coverage.py", "source_location": "L46", - "community": 603, + "community": 184, "norm_label": ".test_cleanup_exception_during_close()", "id": "tests_test_http_session_coverage_testcleanup_test_cleanup_exception_during_close" }, @@ -58124,7 +58178,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L37", - "community": 502, + "community": 576, "norm_label": "testpaginationparams", "id": "tests_test_pagination_testpaginationparams" }, @@ -58133,7 +58187,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L38", - "community": 502, + "community": 576, "norm_label": ".test_defaults()", "id": "tests_test_pagination_testpaginationparams_test_defaults" }, @@ -58142,7 +58196,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L46", - "community": 502, + "community": 576, "norm_label": ".test_custom_limit()", "id": "tests_test_pagination_testpaginationparams_test_custom_limit" }, @@ -58151,7 +58205,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L52", - "community": 502, + "community": 576, "norm_label": ".test_custom_offset()", "id": "tests_test_pagination_testpaginationparams_test_custom_offset" }, @@ -58160,7 +58214,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L59", - "community": 502, + "community": 576, "norm_label": ".test_limit_and_offset()", "id": "tests_test_pagination_testpaginationparams_test_limit_and_offset" }, @@ -58169,7 +58223,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L67", - "community": 502, + "community": 576, "norm_label": ".test_limit_exceeds_max_rejected()", "id": "tests_test_pagination_testpaginationparams_test_limit_exceeds_max_rejected" }, @@ -58178,7 +58232,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L71", - "community": 502, + "community": 576, "norm_label": ".test_limit_zero_rejected()", "id": "tests_test_pagination_testpaginationparams_test_limit_zero_rejected" }, @@ -58187,7 +58241,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L75", - "community": 502, + "community": 576, "norm_label": ".test_negative_offset_rejected()", "id": "tests_test_pagination_testpaginationparams_test_negative_offset_rejected" }, @@ -58196,7 +58250,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L79", - "community": 502, + "community": 576, "norm_label": ".test_offset_beyond_total()", "id": "tests_test_pagination_testpaginationparams_test_offset_beyond_total" }, @@ -58205,7 +58259,7 @@ "file_type": "code", "source_file": "tests/test_pagination.py", "source_location": "L84", - "community": 502, + "community": 576, "norm_label": ".test_limit_equals_max()", "id": "tests_test_pagination_testpaginationparams_test_limit_equals_max" }, @@ -58214,7 +58268,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L28", - "community": 29, + "community": 112, "norm_label": "cover __init__ and updatedates (lines 22-37).", "id": "tests_test_prometheus_auth_coverage_rationale_28" }, @@ -58223,7 +58277,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L59", - "community": 29, + "community": 112, "norm_label": "cover executeworkflow (lines 39-363).", "id": "tests_test_prometheus_auth_coverage_rationale_59" }, @@ -58322,7 +58376,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L665", - "community": 29, + "community": 519, "norm_label": "cover all methods in authentication.py (lines 13-75).", "id": "tests_test_prometheus_auth_coverage_rationale_665" }, @@ -58340,7 +58394,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L1077", - "community": 60, + "community": 627, "norm_label": "exercises the tzinfo-is-none branch (line 144-148).", "id": "tests_test_prometheus_auth_coverage_rationale_1077" }, @@ -58349,7 +58403,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L1091", - "community": 60, + "community": 628, "norm_label": "exercises the expiresat-is-none branch (line 143).", "id": "tests_test_prometheus_auth_coverage_rationale_1091" }, @@ -58358,7 +58412,7 @@ "file_type": "rationale", "source_file": "tests/test_prometheus_auth_coverage.py", "source_location": "L1110", - "community": 29, + "community": 112, "norm_label": "cover getgooglesso (lines 6-14).", "id": "tests_test_prometheus_auth_coverage_rationale_1110" }, @@ -58628,7 +58682,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L494", - "community": 605, + "community": 572, "norm_label": "replacenan handles direct float nan values (line 34).", "id": "tests_test_stocks_api_coverage_rationale_494" }, @@ -58637,7 +58691,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L508", - "community": 614, + "community": 577, "norm_label": "non-json-dict/list string is left as-is.", "id": "tests_test_stocks_api_coverage_rationale_508" }, @@ -58664,7 +58718,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L548", - "community": 3, + "community": 520, "norm_label": "all four special_cols should parse correctly when mixed with none.", "id": "tests_test_stocks_api_coverage_rationale_548" }, @@ -58736,7 +58790,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L761", - "community": 541, + "community": 28, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_761" }, @@ -58754,7 +58808,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L831", - "community": 190, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_831" }, @@ -58763,7 +58817,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L884", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_884" }, @@ -58772,7 +58826,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L893", - "community": 17, + "community": 39, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_893" }, @@ -58781,7 +58835,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L906", - "community": 39, + "community": 17, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_906" }, @@ -58808,7 +58862,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L945", - "community": 17, + "community": 39, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_945" }, @@ -58817,7 +58871,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L953", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_953" }, @@ -58826,7 +58880,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L961", - "community": 39, + "community": 17, "norm_label": "len(daterange) == 1 -> single date filter.", "id": "tests_test_stocks_api_coverage_rationale_961" }, @@ -58997,7 +59051,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L757", - "community": 541, + "community": 28, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_757" }, @@ -59015,7 +59069,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L773", - "community": 112, + "community": 63, "norm_label": "tests covering query.py lines 142-202.", "id": "tests_test_stocks_api_coverage_rationale_773" }, @@ -59024,7 +59078,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L827", - "community": 190, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_827" }, @@ -59033,7 +59087,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L876", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_876" }, @@ -59042,7 +59096,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L898", - "community": 39, + "community": 17, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_898" }, @@ -59069,7 +59123,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L937", - "community": 17, + "community": 39, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_937" }, @@ -59096,7 +59150,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L756", - "community": 541, + "community": 28, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_756" }, @@ -59105,7 +59159,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L772", - "community": 112, + "community": 63, "norm_label": "tests covering query.py lines 142-202.", "id": "tests_test_stocks_api_coverage_rationale_772" }, @@ -59114,7 +59168,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L826", - "community": 190, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_826" }, @@ -59141,7 +59195,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L935", - "community": 17, + "community": 39, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_935" }, @@ -59150,7 +59204,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L943", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_943" }, @@ -59159,7 +59213,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L951", - "community": 39, + "community": 17, "norm_label": "len(daterange) == 1 -> single date filter.", "id": "tests_test_stocks_api_coverage_rationale_951" }, @@ -59231,7 +59285,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L710", - "community": 541, + "community": 28, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_710" }, @@ -59240,7 +59294,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L726", - "community": 112, + "community": 63, "norm_label": "tests covering query.py lines 142-202.", "id": "tests_test_stocks_api_coverage_rationale_726" }, @@ -59249,7 +59303,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L780", - "community": 190, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_780" }, @@ -59258,7 +59312,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L828", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_828" }, @@ -59267,7 +59321,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L837", - "community": 17, + "community": 39, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_837" }, @@ -59276,7 +59330,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L850", - "community": 39, + "community": 17, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_850" }, @@ -59294,7 +59348,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L889", - "community": 17, + "community": 39, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_889" }, @@ -59303,7 +59357,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L897", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_897" }, @@ -59312,7 +59366,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L8", - "community": 629, + "community": 59, "norm_label": "checkmysqlconnection \u2014 success, errors, engine=none paths.", "id": "tests_test_connectivity_coverage_rationale_8" }, @@ -59321,7 +59375,7 @@ "file_type": "rationale", "source_file": "tests/test_connectivity_coverage.py", "source_location": "L105", - "community": 625, + "community": 59, "norm_label": "checkserviceconnection \u2014 success, not found, errors.", "id": "tests_test_connectivity_coverage_rationale_105" }, @@ -59402,7 +59456,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L711", - "community": 541, + "community": 28, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_711" }, @@ -59411,7 +59465,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L727", - "community": 112, + "community": 63, "norm_label": "tests covering query.py lines 142-202.", "id": "tests_test_stocks_api_coverage_rationale_727" }, @@ -59420,7 +59474,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L781", - "community": 190, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_781" }, @@ -59429,7 +59483,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L838", - "community": 17, + "community": 39, "norm_label": "dataframe without time column.", "id": "tests_test_stocks_api_coverage_rationale_838" }, @@ -59438,7 +59492,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L851", - "community": 39, + "community": 17, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_851" }, @@ -59465,7 +59519,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L890", - "community": 17, + "community": 39, "norm_label": "multiple search terms with tickerindex.", "id": "tests_test_stocks_api_coverage_rationale_890" }, @@ -59528,7 +59582,7 @@ "file_type": "code", "source_file": "main/utils/errors.py", "source_location": "L65", - "community": 63, + "community": 498, "norm_label": "register_error_handlers()", "id": "utils_errors_register_error_handlers" }, @@ -59555,7 +59609,7 @@ "file_type": "rationale", "source_file": "main/utils/http_session.py", "source_location": "L23", - "community": 603, + "community": 184, "norm_label": "close the main thread's session at interpreter shutdown.", "id": "utils_http_session_rationale_23" }, @@ -60338,7 +60392,7 @@ "file_type": "rationale", "source_file": "main/utils/errors.py", "source_location": "L68", - "community": 63, + "community": 498, "norm_label": "register exception handlers on the fastapi app. note: httpexception and r", "id": "utils_errors_rationale_68" }, @@ -60428,7 +60482,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L489", - "community": 605, + "community": 572, "norm_label": "replacenan handles direct float nan values (line 34).", "id": "tests_test_stocks_api_coverage_rationale_489" }, @@ -60437,7 +60491,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L503", - "community": 614, + "community": 577, "norm_label": "non-json-dict/list string is left as-is.", "id": "tests_test_stocks_api_coverage_rationale_503" }, @@ -60509,7 +60563,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L705", - "community": 541, + "community": 28, "norm_label": "historical query with a year range.", "id": "tests_test_stocks_api_coverage_rationale_705" }, @@ -60527,7 +60581,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L721", - "community": 112, + "community": 63, "norm_label": "tests covering query.py lines 142-202.", "id": "tests_test_stocks_api_coverage_rationale_721" }, @@ -60536,7 +60590,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L775", - "community": 190, + "community": 39, "norm_label": "invalid date -> inner 400 caught by outer except -> 500.", "id": "tests_test_stocks_api_coverage_rationale_775" }, @@ -60545,7 +60599,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L823", - "community": 17, + "community": 39, "norm_label": "search.strip() == '' should still dedup (line 181).", "id": "tests_test_stocks_api_coverage_rationale_823" }, @@ -60554,7 +60608,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L845", - "community": 39, + "community": 17, "norm_label": "two dates in the range, both valid.", "id": "tests_test_stocks_api_coverage_rationale_845" }, @@ -60581,7 +60635,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L892", - "community": 39, + "community": 17, "norm_label": "search with no index match falls back to string startswith.", "id": "tests_test_stocks_api_coverage_rationale_892" }, @@ -60590,7 +60644,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_api_coverage.py", "source_location": "L900", - "community": 39, + "community": 17, "norm_label": "len(daterange) == 1 -> single date filter.", "id": "tests_test_stocks_api_coverage_rationale_900" }, @@ -60599,7 +60653,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L62", - "community": 561, + "community": 544, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_62" }, @@ -60608,7 +60662,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L61", - "community": 561, + "community": 544, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_61" }, @@ -60617,7 +60671,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L57", - "community": 561, + "community": 544, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_57" }, @@ -60626,7 +60680,7 @@ "file_type": "rationale", "source_file": "tests/conftest.py", "source_location": "L49", - "community": 561, + "community": 544, "norm_label": "testclient with all routers mounted \u2014 no lifespan (no db/service init). o", "id": "tests_conftest_rationale_49" }, @@ -60995,7 +61049,7 @@ "file_type": "rationale", "source_file": "main/utils/errors.py", "source_location": "L67", - "community": 63, + "community": 498, "norm_label": "register exception handlers on the fastapi app. note: httpexception and r", "id": "utils_errors_rationale_67" }, @@ -61004,7 +61058,7 @@ "file_type": "code", "source_file": "main/app/authentication/session.py", "source_location": "L67", - "community": 44, + "community": 523, "norm_label": "getsessionbyidsafe()", "id": "authentication_session_getsessionbyidsafe" }, @@ -61166,7 +61220,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L135", - "community": 613, + "community": 589, "norm_label": "testqueryoptimization", "id": "tests_test_stocks_cache_testqueryoptimization" }, @@ -61175,7 +61229,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L138", - "community": 613, + "community": 589, "norm_label": ".test_all_optimizations_present()", "id": "tests_test_stocks_cache_testqueryoptimization_test_all_optimizations_present" }, @@ -61184,7 +61238,7 @@ "file_type": "code", "source_file": "tests/test_stocks_cache.py", "source_location": "L153", - "community": 613, + "community": 589, "norm_label": ".test_query_filter_uses_optimization()", "id": "tests_test_stocks_cache_testqueryoptimization_test_query_filter_uses_optimization" }, @@ -61436,7 +61490,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L136", - "community": 613, + "community": 589, "norm_label": "integration tests for all query optimizations", "id": "tests_test_stocks_cache_rationale_136" }, @@ -61445,7 +61499,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L139", - "community": 613, + "community": 589, "norm_label": "all optimizations should be implemented", "id": "tests_test_stocks_cache_rationale_139" }, @@ -61454,7 +61508,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L154", - "community": 613, + "community": 589, "norm_label": "query filter should use ticker index", "id": "tests_test_stocks_cache_rationale_154" }, @@ -61724,7 +61778,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L138", - "community": 613, + "community": 589, "norm_label": "integration tests for all query optimizations", "id": "tests_test_stocks_cache_rationale_138" }, @@ -61733,7 +61787,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L141", - "community": 613, + "community": 589, "norm_label": "all optimizations should be implemented", "id": "tests_test_stocks_cache_rationale_141" }, @@ -61742,7 +61796,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_cache.py", "source_location": "L156", - "community": 613, + "community": 589, "norm_label": "query filter should use ticker index", "id": "tests_test_stocks_cache_rationale_156" }, @@ -61985,7 +62039,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L72", - "community": 172, + "community": 541, "norm_label": "testquerycaching", "id": "tests_test_stocks_optimization_testquerycaching" }, @@ -61994,7 +62048,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L75", - "community": 172, + "community": 541, "norm_label": ".test_cache_manager_has_caches_method()", "id": "tests_test_stocks_optimization_testquerycaching_test_cache_manager_has_caches_method" }, @@ -62003,7 +62057,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L83", - "community": 172, + "community": 541, "norm_label": ".test_querycache_ttl_configuration()", "id": "tests_test_stocks_optimization_testquerycaching_test_queryCache_ttl_configuration" }, @@ -62012,7 +62066,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L91", - "community": 172, + "community": 541, "norm_label": ".test_get_cached_stocks_respects_columns_parameter()", "id": "tests_test_stocks_optimization_testquerycaching_test_get_cached_stocks_respects_columns_parameter" }, @@ -62021,7 +62075,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L101", - "community": 172, + "community": 541, "norm_label": ".test_different_queries_not_cached()", "id": "tests_test_stocks_optimization_testquerycaching_test_different_queries_not_cached" }, @@ -62030,7 +62084,7 @@ "file_type": "code", "source_file": "tests/test_stocks_optimization.py", "source_location": "L105", - "community": 172, + "community": 541, "norm_label": ".test_cache_expiry_after_ttl()", "id": "tests_test_stocks_optimization_testquerycaching_test_cache_expiry_after_ttl" }, @@ -62255,7 +62309,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L73", - "community": 172, + "community": 541, "norm_label": "tests for query result caching", "id": "tests_test_stocks_optimization_rationale_73" }, @@ -62264,7 +62318,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L76", - "community": 172, + "community": 541, "norm_label": "cachemanager should track cached queries", "id": "tests_test_stocks_optimization_rationale_76" }, @@ -62273,7 +62327,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L84", - "community": 172, + "community": 541, "norm_label": "query cache should have configurable ttl", "id": "tests_test_stocks_optimization_rationale_84" }, @@ -62282,7 +62336,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L92", - "community": 172, + "community": 541, "norm_label": "getcachedstocks should support column filtering", "id": "tests_test_stocks_optimization_rationale_92" }, @@ -62291,7 +62345,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L102", - "community": 172, + "community": 541, "norm_label": "different query parameters should not share cache", "id": "tests_test_stocks_optimization_rationale_102" }, @@ -62300,7 +62354,7 @@ "file_type": "rationale", "source_file": "tests/test_stocks_optimization.py", "source_location": "L106", - "community": 172, + "community": 541, "norm_label": "cache should expire after ttl", "id": "tests_test_stocks_optimization_rationale_106" }, @@ -62790,7 +62844,7 @@ "label": "FastAPI", "file_type": "rationale", "source_file": "README.md", - "community": 528, + "community": 576, "norm_label": "fastapi", "id": "fastapi" }, @@ -62830,7 +62884,7 @@ "label": "Authentication System", "file_type": "document", "source_file": "docs/authentication.md", - "community": 528, + "community": 107, "norm_label": "authentication system", "id": "authentication" }, @@ -62838,7 +62892,7 @@ "label": "JWT Authentication", "file_type": "rationale", "source_file": "docs/authentication.md", - "community": 528, + "community": 107, "norm_label": "jwt authentication", "id": "jwt" }, @@ -62846,7 +62900,7 @@ "label": "Google OAuth", "file_type": "rationale", "source_file": "docs/authentication.md", - "community": 528, + "community": 107, "norm_label": "google oauth", "id": "google_oauth" }, @@ -62934,7 +62988,7 @@ "label": "Pytest Testing", "file_type": "rationale", "source_file": "pyproject.toml", - "community": 49, + "community": 561, "norm_label": "pytest testing", "id": "pytest" }, @@ -71158,6 +71212,17 @@ "source": "orunmila_sandbox_syncfromsandbox", "target": "orunmila_sandbox_hostpath" }, + { + "relation": "calls", + "context": "call", + "confidence": "INFERRED", + "confidence_score": 0.8, + "source_file": "main/app/orunmila/tools/sandbox.py", + "source_location": "L87", + "weight": 1.0, + "source": "tools_sandbox_serve_file", + "target": "orunmila_sandbox_hostpath" + }, { "relation": "calls", "context": "call", @@ -71973,9 +72038,9 @@ "source_file": "main/app/orunmila/tools/memory.py", "source_location": "L9", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_memory_rationale_9", - "target": "tools_memory_search_memory", - "confidence_score": 1.0 + "target": "tools_memory_search_memory" }, { "relation": "rationale_for", @@ -71993,9 +72058,9 @@ "source_file": "main/app/orunmila/tools/memory.py", "source_location": "L34", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_memory_rationale_34", - "target": "tools_memory_save_memory", - "confidence_score": 1.0 + "target": "tools_memory_save_memory" }, { "relation": "rationale_for", @@ -72134,9 +72199,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L27", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_wallet_py", - "target": "tools_wallet_wallet_positions", - "confidence_score": 1.0 + "target": "tools_wallet_wallet_positions" }, { "relation": "contains", @@ -72144,9 +72209,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L52", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_wallet_py", - "target": "tools_wallet_wallet_summary", - "confidence_score": 1.0 + "target": "tools_wallet_wallet_summary" }, { "relation": "contains", @@ -72154,9 +72219,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L77", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_wallet_py", - "target": "tools_wallet_wallet_allocation", - "confidence_score": 1.0 + "target": "tools_wallet_wallet_allocation" }, { "relation": "contains", @@ -72174,9 +72239,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L148", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_wallet_py", - "target": "tools_wallet_wallet_performance", - "confidence_score": 1.0 + "target": "tools_wallet_wallet_performance" }, { "relation": "contains", @@ -72184,9 +72249,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L187", "weight": 1.0, + "confidence_score": 1.0, "source": "main_app_orunmila_tools_wallet_py", - "target": "tools_wallet_wallet_rebalance", - "confidence_score": 1.0 + "target": "tools_wallet_wallet_rebalance" }, { "relation": "contains", @@ -72245,9 +72310,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L40", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_wallet_wallet_positions", - "target": "tools_wallet_ensureownership", - "confidence_score": 1.0 + "target": "tools_wallet_ensureownership" }, { "relation": "calls", @@ -72256,9 +72321,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L65", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_wallet_wallet_summary", - "target": "tools_wallet_ensureownership", - "confidence_score": 1.0 + "target": "tools_wallet_ensureownership" }, { "relation": "calls", @@ -72267,9 +72332,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L91", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_wallet_wallet_allocation", - "target": "tools_wallet_ensureownership", - "confidence_score": 1.0 + "target": "tools_wallet_ensureownership" }, { "relation": "calls", @@ -72289,9 +72354,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L172", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_wallet_wallet_performance", - "target": "tools_wallet_ensureownership", - "confidence_score": 1.0 + "target": "tools_wallet_ensureownership" }, { "relation": "calls", @@ -72300,9 +72365,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L200", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_wallet_wallet_rebalance", - "target": "tools_wallet_ensureownership", - "confidence_score": 1.0 + "target": "tools_wallet_ensureownership" }, { "relation": "calls", @@ -72365,9 +72430,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L28", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_wallet_rationale_28", - "target": "tools_wallet_wallet_positions", - "confidence_score": 1.0 + "target": "tools_wallet_wallet_positions" }, { "relation": "rationale_for", @@ -72375,9 +72440,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L53", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_wallet_rationale_53", - "target": "tools_wallet_wallet_summary", - "confidence_score": 1.0 + "target": "tools_wallet_wallet_summary" }, { "relation": "rationale_for", @@ -72385,9 +72450,9 @@ "source_file": "main/app/orunmila/tools/wallet.py", "source_location": "L78", "weight": 1.0, + "confidence_score": 1.0, "source": "tools_wallet_rationale_78", - "target": "tools_wallet_wallet_allocation", - "confidence_score": 1.0 + "target": "tools_wallet_wallet_allocation" }, { "relation": "rationale_for", @@ -72403,71 +72468,71 @@ "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "main/app/orunmila/tools/wallet.py", - "source_location": "L151", + "source_location": "L149", "weight": 1.0, - "source": "tools_wallet_rationale_151", - "target": "tools_wallet_wallet_performance", - "confidence_score": 1.0 + "confidence_score": 1.0, + "source": "tools_wallet_rationale_149", + "target": "tools_wallet_wallet_performance" }, { "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "main/app/orunmila/tools/wallet.py", - "source_location": "L188", + "source_location": "L151", "weight": 1.0, - "source": "tools_wallet_rationale_188", - "target": "tools_wallet_wallet_rebalance", - "confidence_score": 1.0 + "confidence_score": 1.0, + "source": "tools_wallet_rationale_151", + "target": "tools_wallet_wallet_performance" }, { "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "main/app/orunmila/tools/wallet.py", - "source_location": "L28", + "source_location": "L186", "weight": 1.0, "confidence_score": 1.0, - "source": "tools_wallet_rationale_28", - "target": "tools_wallet_get_wallet_positions" + "source": "tools_wallet_rationale_186", + "target": "tools_wallet_wallet_rebalance" }, { "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "main/app/orunmila/tools/wallet.py", - "source_location": "L53", + "source_location": "L188", "weight": 1.0, "confidence_score": 1.0, - "source": "tools_wallet_rationale_53", - "target": "tools_wallet_get_wallet_summary" + "source": "tools_wallet_rationale_188", + "target": "tools_wallet_wallet_rebalance" }, { "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "main/app/orunmila/tools/wallet.py", - "source_location": "L78", + "source_location": "L28", "weight": 1.0, "confidence_score": 1.0, - "source": "tools_wallet_rationale_78", - "target": "tools_wallet_get_wallet_allocation" + "source": "tools_wallet_rationale_28", + "target": "tools_wallet_get_wallet_positions" }, { "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "main/app/orunmila/tools/wallet.py", - "source_location": "L151", + "source_location": "L53", "weight": 1.0, "confidence_score": 1.0, - "source": "tools_wallet_rationale_151", - "target": "tools_wallet_get_wallet_performance" + "source": "tools_wallet_rationale_53", + "target": "tools_wallet_get_wallet_summary" }, { "relation": "rationale_for", "confidence": "EXTRACTED", "source_file": "main/app/orunmila/tools/wallet.py", - "source_location": "L188", + "source_location": "L78", "weight": 1.0, "confidence_score": 1.0, - "source": "tools_wallet_rationale_188", - "target": "tools_wallet_get_wallet_rebalance" + "source": "tools_wallet_rationale_78", + "target": "tools_wallet_get_wallet_allocation" }, { "relation": "contains", @@ -78807,327 +78872,6 @@ "source": "wallet_wallets_createwallet", "target": "models_wallet_wallet" }, - { - "relation": "imports_from", - "context": "import", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L13", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "fastapi" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L36", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_fetchxangoscores" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L48", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_scorebuyflag" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L32", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_createwallet" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L40", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_listwallets" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L44", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_entrycreate" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L55", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_entryupdate" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L62", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_getownedwallet" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L72", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_applyentries" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L88", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_recalcholding" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L112", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_addentry" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L138", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_listentries" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L150", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_updateentry" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L172", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_deleteentry" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L193", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_stocksapibase" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L197", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_stocksapiheaders" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L202", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_fetchliveprices" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L227", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_fetchcachedclose" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L247", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_getpositions" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L306", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_targetupsert" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L313", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_ratingupsert" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L319", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_getsummary" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L370", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_getallocation" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L396", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_upserttarget" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L422", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_set_rating" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L433", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_positionatdate" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L440", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_fetchmarketdividends" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L458", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_syncearnings" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L525", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_listearnings" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L536", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_fetchpadraocloses" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L559", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_cachedperformance" - }, - { - "relation": "contains", - "confidence": "EXTRACTED", - "source_file": "main/app/wallet/wallet_service.py", - "source_location": "L662", - "weight": 1.0, - "confidence_score": 1.0, - "source": "main_app_wallet_wallet_service_py", - "target": "wallet_wallet_service_getperformance" - }, { "relation": "imports_from", "context": "import", @@ -86221,6 +85965,36 @@ "source": "migrations_versions_d3e4f5a6b7c8_add_prometheus_sandboxes_py", "target": "versions_d3e4f5a6b7c8_add_prometheus_sandboxes_rationale_1" }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/d4e5f6a7b8c9_drop_dead_holding_columns.py", + "source_location": "L24", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_d4e5f6a7b8c9_drop_dead_holding_columns_py", + "target": "versions_d4e5f6a7b8c9_drop_dead_holding_columns_upgrade" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/d4e5f6a7b8c9_drop_dead_holding_columns.py", + "source_location": "L32", + "weight": 1.0, + "confidence_score": 1.0, + "source": "migrations_versions_d4e5f6a7b8c9_drop_dead_holding_columns_py", + "target": "versions_d4e5f6a7b8c9_drop_dead_holding_columns_downgrade" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "migrations/versions/d4e5f6a7b8c9_drop_dead_holding_columns.py", + "source_location": "L1", + "weight": 1.0, + "confidence_score": 1.0, + "source": "versions_d4e5f6a7b8c9_drop_dead_holding_columns_rationale_1", + "target": "migrations_versions_d4e5f6a7b8c9_drop_dead_holding_columns_py" + }, { "relation": "contains", "confidence": "EXTRACTED", @@ -94101,6 +93875,347 @@ "source": "specs_2026_09_29_nginx_scaling_design_4_topology", "target": "specs_2026_09_29_nginx_scaling_design_codeblock_1" }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L151", + "weight": 1.0, + "confidence_score": 1.0, + "source": "tools_wallet_rationale_151", + "target": "tools_wallet_get_wallet_performance" + }, + { + "relation": "rationale_for", + "confidence": "EXTRACTED", + "source_file": "main/app/orunmila/tools/wallet.py", + "source_location": "L188", + "weight": 1.0, + "confidence_score": 1.0, + "source": "tools_wallet_rationale_188", + "target": "tools_wallet_get_wallet_rebalance" + }, + { + "relation": "imports_from", + "context": "import", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L13", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "fastapi" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L36", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchxangoscores" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L48", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_scorebuyflag" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L32", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_createwallet" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L40", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_listwallets" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L44", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_entrycreate" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L55", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_entryupdate" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L62", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getownedwallet" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L72", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_applyentries" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L88", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_recalcholding" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L112", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_addentry" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L138", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_listentries" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L150", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_updateentry" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L172", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_deleteentry" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L193", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_stocksapibase" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L197", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_stocksapiheaders" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L202", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchliveprices" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L227", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchcachedclose" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L247", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getpositions" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L306", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_targetupsert" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L313", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_ratingupsert" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L319", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getsummary" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L370", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getallocation" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L396", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_upserttarget" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L422", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_set_rating" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L433", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_positionatdate" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L440", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchmarketdividends" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L458", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_syncearnings" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L525", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_listearnings" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L536", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_fetchpadraocloses" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L559", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_cachedperformance" + }, + { + "relation": "contains", + "confidence": "EXTRACTED", + "source_file": "main/app/wallet/wallet_service.py", + "source_location": "L662", + "weight": 1.0, + "confidence_score": 1.0, + "source": "main_app_wallet_wallet_service_py", + "target": "wallet_wallet_service_getperformance" + }, { "relation": "imports_from", "context": "import", @@ -161144,5 +161259,5 @@ "label": "User Authentication & Authorization" } ], - "built_at_commit": "81d7224b5a4be29c33eb5eb30ce425374bf20643" + "built_at_commit": "45768447bc5c0e3ab9d73f95ac48e070c1282704" } \ No newline at end of file diff --git a/graphify-out/manifest.json b/graphify-out/manifest.json index e3822785..fbe2a94f 100644 --- a/graphify-out/manifest.json +++ b/graphify-out/manifest.json @@ -15,8 +15,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\run.py": { - "mtime": 1790822066.405692, - "ast_hash": "c2366bbc2b938c01d94e069076a65f3e", + "mtime": 1790836913.8421538, + "ast_hash": "0a8c5f526c350c25e1ba673a940eeae6", "semantic_hash": "" }, "D:\\Repositories\\server\\frontend\\components.json": { @@ -275,8 +275,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\context.py": { - "mtime": 1790832493.312804, - "ast_hash": "c47a06369cfe9aea8cada08f7942f480", + "mtime": 1790837178.034846, + "ast_hash": "a3d32d5348cca30780655b05b82bce1b", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\memory.py": { @@ -285,18 +285,18 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\sandbox.py": { - "mtime": 1790834443.8187387, - "ast_hash": "6616c6fb85723bc43371ba27538d27da", + "mtime": 1790837097.7105825, + "ast_hash": "69b6182adec6a8eaba174c446f9f4acf", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\wallet.py": { - "mtime": 1790834325.0523524, - "ast_hash": "d7169d2c574c7e44aab4511692dacf9e", + "mtime": 1790834672.9276283, + "ast_hash": "21e96653f817b8341d36b29c691c91d4", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\orunmila\\tools\\__init__.py": { - "mtime": 1790834498.726344, - "ast_hash": "01702bd99310f3a0f6c8e240d91a0022", + "mtime": 1790837111.132924, + "ast_hash": "1af04d6a494cef1950791d9d735a890e", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\scraper_b3\\scraper.py": { @@ -370,18 +370,18 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\wallet\\performance.py": { - "mtime": 1790830223.6296313, + "mtime": 1790834672.9276283, "ast_hash": "c332a654033ce98e7f8a31df3faea5ea", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\wallet\\positions.py": { - "mtime": 1790830807.8044558, - "ast_hash": "382c223221315fa71edb000746126111", + "mtime": 1790834606.0508318, + "ast_hash": "1cd28a3770e7264146c9f40df086a017", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\wallet\\summary.py": { - "mtime": 1790830238.410782, - "ast_hash": "3d1a0ee9db7d69b8f8ce324b3946182f", + "mtime": 1790834672.9296267, + "ast_hash": "8100991706cff4c0e3f4384abe454cdc", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\app\\wallet\\wallets.py": { @@ -389,11 +389,6 @@ "ast_hash": "f52f4d29d146953b6659e346e906da26", "semantic_hash": "" }, - "D:\\Repositories\\server\\main\\app\\wallet\\wallet_service.py": { - "mtime": 1790828956.056157, - "ast_hash": "0596d4a054b5ab48baeb9af24511af41", - "semantic_hash": "" - }, "D:\\Repositories\\server\\main\\controller\\authentication_controller.py": { "mtime": 1790721202.5567384, "ast_hash": "8be9ba65e0116ce4ad4867fcc59bae50", @@ -460,8 +455,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\main\\models\\wallet.py": { - "mtime": 1790814890.9302452, - "ast_hash": "cf13241575f7af9059fb1ef2fb6421ae", + "mtime": 1790836945.7256603, + "ast_hash": "30ffa55bd90e269b39917ec7079107f5", "semantic_hash": "" }, "D:\\Repositories\\server\\main\\service\\authentication_service.py": { @@ -604,6 +599,11 @@ "ast_hash": "1cd806b72716facac6dbf7ec3e0bbe12", "semantic_hash": "" }, + "D:\\Repositories\\server\\migrations\\versions\\d4e5f6a7b8c9_drop_dead_holding_columns.py": { + "mtime": 1790836959.2365656, + "ast_hash": "f74e397a4de0a6b5dbb3bef4a119becd", + "semantic_hash": "" + }, "D:\\Repositories\\server\\migrations\\versions\\e4f5a6b7c8d9_fix_fulltext_index_prometheus_memories.py": { "mtime": 1789266824.6476328, "ast_hash": "9ae7aa16f3e81e913d533d84a9c932b9", @@ -810,8 +810,8 @@ "semantic_hash": "" }, "D:\\Repositories\\server\\frontend\\mock-wallet.html": { - "mtime": 1790828329.3471212, - "ast_hash": "842c72edefd8f4c47baf0cf55f8a955e", + "mtime": 1790835791.9064455, + "ast_hash": "10a5e8765d73579086d5d3c82aeb1fa5", "semantic_hash": "" }, "D:\\Repositories\\server\\frontend\\pnpm-workspace.yaml": { diff --git a/main/app/orunmila/tools/wallet.py b/main/app/orunmila/tools/wallet.py index f61142ae..ab8ab703 100644 --- a/main/app/orunmila/tools/wallet.py +++ b/main/app/orunmila/tools/wallet.py @@ -145,9 +145,7 @@ async def list_wallet_earnings(wallet_id: int, status: Optional[str] = "A Recebe closeOwnSession(db, ownSession) -async def wallet_performance( - wallet_id: int, from_date: str, to_date: str, ticker: Optional[str] = None, **_ -) -> dict: +async def wallet_performance(wallet_id: int, from_date: str, to_date: str, ticker: Optional[str] = None, **_) -> dict: """Compute time-weighted return, volatility, and dividends for a wallet or ticker. Read-only: never mutates wallet state. diff --git a/main/app/wallet/summary.py b/main/app/wallet/summary.py index 32f196e5..764be7cb 100644 --- a/main/app/wallet/summary.py +++ b/main/app/wallet/summary.py @@ -162,4 +162,5 @@ def set_rating(cls, db: Session, userId: int, data: RatingUpsert) -> Holding: return holding + set_rating = SummaryManager.set_rating