Files
palladium/README.md
Robert Helewka e88449d15a Migrate Genesys CX Cloud TEI study to the pattern; retire Streamlit app
studies/202512_GenesysCX -> studies/202512_TEI_Genesys_CX_Cloud,
rebuilt as pattern Variant 4 (TEI composite reproduction):

- teicalc/ self-contained engine: Forrester's tables as the never-edited
  verbatim anchor (incl. the p.14 typo note and the $0 AI-token line),
  generic model/scenarios/staging carried over from the Amazon Connect
  study, ClientDrivers overlay (agents / weekly interactions / revenue,
  flat composite so no growth re-base) with ai_tokens_annual as a direct
  input for the token line the published study models at $0
- one deliverable notebook (business_case.ipynb): widget-pair sidebar
  drivers incl. the AI-token price, published-vs-overlay KPI columns,
  cash-flow/waterfall/scenario charts, verification gate, backstage JSON
  data appendix
- gate + tests reproduce the published totals within $2: NPV $10.8M /
  ROI 266% (engine $10,783,466 / 265.79%; payback 3.3 months, not
  headlined in the PDF); 29 study tests, headless nbconvert green,
  stage simulation leak-free, exports carry the appendix
- old Athena workflow (00_provision..04_export, config.py, seed_data.py,
  PALLADIUM_GENESYSCX_* keys, ATHENA_EXPECTED reconciliation) deleted;
  git history preserves it

With the last legacy study migrated, the retirement lands too:
- app/ (Streamlit UI) and core/notebook_helpers deleted; nothing else
  imported them
- streamlit stripped from pyproject extras, requirements.txt, Makefile;
  .env.example reduced to the Athena keys; 00_setup.ipynb and
  core/bootstrap.py repointed at the pattern studies
- root README reworked: self-contained studies + slim core/ Athena
  toolkit (tei_client, calculations, export, cli)

All suites green: Genesys 29, Amazon Connect 27, CTM 55, template 7,
root 58.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 16:38:51 -04:00

429 lines
17 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Palladium
**TEI (Total Economic Impact) Calculator** — The strategic artifact that protects the business case.
Palladium is a Jupyter-notebook toolkit for building Total Economic Impact analyses. Each study is a self-contained Mercury-served notebook deliverable (math in a study package, verification gate, LLM-readable exports); a small shared `core/` talks to [Athena](https://athena.nttdata.com) for client/opportunity context and server-side TEI tooling.
> *In Greek mythology, the Palladium was a sacred artifact of Athena that protected Troy. Whoever possessed it held strategic advantage. In our ecosystem, Palladium protects the deal — transforming discovery inputs into a financial case no CFO can ignore.*
## Architecture
```
┌──────────────────────────────────────────────────────────────────┐
│ Palladium │
│ │
│ studies/YYYYMM_TEI_Vendor_Product/ ← self-contained study │
│ studies/YYYYMM_Client_EngagementName/ (own venv + engine) │
│ ├─ <studylib>/ ← ALL math, verbatim anchors │
│ ├─ notebooks/ ← THE deliverable (Mercury-served) │
│ ├─ tests/ ← pinned acceptance numbers │
│ └─ exports/ ← .html/.md + JSON appendix (for LLMs, │
│ and the Athena repository roadmap) │
│ │
│ core/ ← shared Athena toolkit (studies do NOT import it) │
│ tei_client → ──────────────────────────► Athena API │
│ calculations · export · cli · bootstrap │
└──────────────────────────────────────────────────────────────────┘
```
### Components
| Component | Purpose |
|-----------|---------|
| **`studies/`** | One self-contained folder per engagement — own venv, engine package, Mercury notebook, tests, exports |
| **`template/`** | Copy-me study scaffold — start here for new studies |
| **`core/tei_client`** | Python API client for Athena's TEI endpoints |
| **`core/calculations`** | Financial logic — NPV, ROI, payback, risk adjustment, scenarios |
| **`core/export`** | Builds the structured JSON envelope consumed by the report pipeline |
| **`core/cli`** | `python -m palladium` command-line interface |
> **All studies follow the [Mercury Notebook Deliverable Pattern](docs/Mercury_Notebook_Pattern_V1-00.md)**:
> the notebook *is* the artifact — self-contained study package, Mercury-served,
> gate-verified, LLM-exportable. Start from [`template/MercuryNotebook/`](template/MercuryNotebook/).
> The Streamlit `app/` and `core/notebook_helpers` were retired when the last
> legacy study migrated (git history keeps them).
---
## Quick Start — Jupyter Lab first
Palladium is a **Jupyter Lab-first** environment. Everything starts from a
notebook; the CLI is a companion, not a prerequisite.
```bash
git clone https://github.com/nttdata/palladium.git
cd palladium
make setup # venv + deps + editable install (one time)
make lab # launches Jupyter Lab
```
Then open **`00_setup.ipynb`** at the repo root. It will:
1. Prompt for your Athena API key (hidden input) and save it to `.env`
2. Test the connection
3. Show what report templates and tools exist in the instance
Current target instance: **https://athena.ouranos.helu.ca** (Ouranos sandbox —
no production data, safe to experiment).
From any root-level notebook, the Athena connection is one import (pattern
studies are self-contained and never import `core`):
```python
from core.bootstrap import init
pal = init() # loads .env, builds client, tests it
pal.client.list_reports()
```
### Configuration
All credentials and IDs live in `<repo>/.env` (gitignored). `00_setup.ipynb`
writes it for you; to do it by hand:
```bash
# .env
ATHENA_BASE_URL=https://athena.ouranos.helu.ca
ATHENA_API_KEY=your-api-key-here
```
### Verify Connection
In a notebook: `init()` prints the connection status. From a shell:
```bash
python -m palladium test
```
---
## Usage
### Run a study end-to-end
Each new study is self-contained under the
[Mercury Notebook Deliverable Pattern](docs/Mercury_Notebook_Pattern_V1-00.md).
The reference TEI study is the February 2026 Forrester *Total Economic
Impact™ Of Amazon Connect* (pattern Variant 4 — composite reproduction):
```bash
cd studies/202602_TEI_Amazon_Connect
python -m venv .venv && source .venv/bin/activate && pip install -e ".[dev]"
mercury --working-dir notebooks/ # serve the deliverable (the stage)
python scripts/export_report.py # export .html/.md report sources
```
Its notebook reproduces the published totals within the PDF's rounding —
**NPV $78.7M • ROI 342% • Payback <6 months** — and the verification gate
asserts it on every headless run. See the study's README for details.
`studies/202512_TEI_Genesys_CX_Cloud/` follows the same shape (**NPV $10.8M
• ROI 266%**), with one signature input: the Genesys AI Experience token
line the published study models at $0, priced live from the client's quote.
`studies/202607_CTM_GenesysCX/` is the full multi-notebook reference
implementation.
### CLI
```bash
# Test connection
python -m palladium test
# List TEI tool instances
python -m palladium list
# List available report templates
python -m palladium reports
# Show financial summary for a tool
python -m palladium summary <public_id>
# Trigger server-side recalculation
python -m palladium calculate <public_id>
# Export for the report pipeline
python -m palladium export <public_id> -o export.json
```
### Tests
```bash
pytest tests/ -v
```
The root suite covers the API client (mocked HTTP), the financial math, and
the export envelope shape; the Amazon Connect verbatim anchor is asserted
against the published Forrester totals. Each study additionally carries its
own pinned suite (`cd studies/<slug> && pytest`).
---
## Adding a new study
Copy the template, not an existing study:
```bash
cp -r template/MercuryNotebook studies/YYYYMM_TEI_Vendor_Product
```
Then follow `template/MercuryNotebook/README.md`: rename `studylib/` to
your study package (underscores only — dashes break Python imports),
replace the toy model, re-pin the tests, rework the notebook.
`studies/202602_TEI_Amazon_Connect/` is the worked TEI example;
`studies/202607_CTM_GenesysCX/` is the full multi-notebook reference.
---
## TEI Methodology
Palladium implements the Forrester TEI™ framework.
### Benefit Categories
Benefits are quantified across categories, risk-adjusted, and discounted to present value:
| Category | Examples |
|----------|----------|
| **Cost Savings** | Legacy license elimination, reduced headcount, lower telecom |
| **Productivity** | Reduced handle time, faster training, automated QA |
| **Revenue** | Improved retention, better conversion, new channel revenue |
| **Risk Reduction** | Compliance automation, reduced legal exposure, audit readiness |
### Risk Adjustment
Each benefit carries a risk-adjustment factor (050%) reflecting implementation uncertainty.
A 20% risk adjustment on a $10M benefit yields a risk-adjusted value of $8M.
**Costs** are risk-adjusted **upward** by the same factor (higher risk → higher modelled cost).
### Financial Metrics
| Metric | Description |
|--------|-------------|
| **NPV** | Net Present Value — total risk-adjusted benefits minus costs, discounted |
| **ROI** | Return on Investment — `(benefits costs) / costs × 100` |
| **Payback** | Months until cumulative benefits exceed cumulative costs |
The initial investment (year 0) is **not** discounted. Year-N cashflows are
discounted at the end of the year: `PV = CF_n / (1 + r)^n`. This matches
the Forrester methodology used in the published studies.
### Scenario Analysis
Three scenarios model uncertainty in adoption and realization
(see `core.calculations.SCENARIOS`):
| Scenario | Adoption | Risk delta | Effect |
|----------|----------|------------|--------|
| Conservative | 80% | +10pp on benefits | Lower benefits, higher modelled cost |
| Moderate | 100% | 0 | Base case (= published study) |
| Aggressive | 115% | 5pp on benefits | Higher benefits, lower padding on cost |
---
## Project Structure
```
palladium/
├── 00_setup.ipynb # ← START HERE: credentials + connection
├── Makefile # make setup / lab / test
├── core/ # Shared, study-agnostic Python package
│ ├── bootstrap.py # one-import notebook setup (init, save_credentials)
│ ├── tei_client/ # Athena API client
│ │ ├── client.py # TEIClient with all /api/v1/tei/ methods
│ │ └── models.py # Optional dataclasses for typed access
│ ├── calculations/ # Pure-python financial math
│ │ ├── npv.py
│ │ ├── roi.py
│ │ ├── payback.py
│ │ └── scenarios.py
│ ├── export/
│ │ └── report_data.py # JSON envelope for the report pipeline
│ └── cli/
│ └── main.py # `python -m palladium ...`
├── palladium/ # CLI shim (just exposes `python -m palladium`)
│ └── __main__.py
├── template/
│ └── MercuryNotebook/ # copy-me pattern scaffold (runnable)
├── studies/ # One self-contained folder per engagement
│ ├── 202512_TEI_Genesys_CX_Cloud/ # CX Cloud TEI — pattern Variant 4
│ │ ├── README.md # NPV $10.8M · ROI 266% + the $0 AI-token line
│ │ ├── teicalc/ # self-contained engine (anchor/model/overlay)
│ │ ├── notebooks/business_case.ipynb
│ │ ├── tests/ · scripts/ · config.toml · pyproject.toml
│ │ └── docs/ # Forrester PDF + Genesys token-metering notes
│ ├── 202602_TEI_Amazon_Connect/ # Amazon Connect TEI — pattern Variant 4
│ │ ├── README.md # NPV $78.7M · ROI 342%, reproduced + gated
│ │ ├── teicalc/ # self-contained engine (anchor/model/overlay)
│ │ ├── notebooks/business_case.ipynb
│ │ ├── tests/ · scripts/ · config.toml · pyproject.toml
│ │ ├── exports/ # generated; .gitignored
│ │ └── docs/
│ │ └── 202602_TEI Report Amazon Connect.pdf
│ └── 202607_CTM_GenesysCX/ # CTM × Genesys study — pattern reference impl
├── tests/ # root tests for core/
│ ├── test_client.py
│ ├── test_calculations.py
│ └── test_export.py
├── Athena API.yaml # OpenAPI reference
├── .env.example
├── requirements.txt
├── pyproject.toml
└── README.md
```
---
## Athena Integration
Palladium connects to Athena's TEI module for data persistence and cross-tool reporting.
### API Endpoints Used
All endpoints are under `/api/v1/tei/` and require `Authorization: Api-Key {key}`.
| Endpoint | Purpose |
|----------|---------|
| `GET /api/v1/tei/reports/` | List available TEI report templates |
| `GET /api/v1/tei/reports/{public_id}/` | Get a report template |
| `GET /api/v1/tei/reports/{public_id}/fields/` | Get field definitions for a template |
| `POST /api/v1/tei/tools/` | Create a new TEI tool instance |
| `GET /api/v1/tei/tools/{public_id}/` | Get instance metadata |
| `PATCH /api/v1/tei/tools/{public_id}/` | Update name/status |
| `GET /api/v1/tei/tools/{public_id}/values/` | Get current field values |
| `PUT /api/v1/tei/tools/{public_id}/values/` | Bulk-update values |
| `PATCH /api/v1/tei/tools/{public_id}/values/{field_key}/` | Patch a single value |
| `POST /api/v1/tei/tools/{public_id}/calculate/` | Trigger calculation |
| `GET /api/v1/tei/tools/{public_id}/summary/` | Get financial summary |
| `GET /api/v1/tei/tools/{public_id}/versions/` | List version snapshots |
| `POST /api/v1/tei/tools/{public_id}/versions/` | Save a new version |
| `GET /api/v1/tei/tools/{public_id}/versions/{n}/` | Get a specific version |
| `GET /api/v1/tei/tools/{public_id}/export/` | Export for the report pipeline |
| `GET /api/v1/tei/summary/` | Aggregate NPV across all tools |
### Object model
| Athena object | Notes |
|---|---|
| **Opportunity** | Top-level sales record. Owns one or more **Proposals**. |
| **Proposal** | A specific bid/offer to a client. **A TEI tool is linked to a Proposal.** |
| **Engagement** | Optional — for active client engagements. A TEI tool may also link here. |
| **TEIReport** | Template (e.g. *Amazon Connect 2026*) — defines fields, discount rate, analysis horizon. |
| **TEITool** | Instance of a Report bound to a Proposal — holds values, summaries, versions. |
### Authentication
```
Authorization: Api-Key {your-api-key}
```
API keys are provisioned in Athena's admin interface per user/service account.
### Methodology conventions (Palladium ↔ Athena)
Two places where the Forrester methodology and the Athena TEI API differ, and
how Palladium bridges them:
| Topic | Athena behaviour | Palladium convention |
|---|---|---|
| **Cost risk adjustment** | Costs are never risk-adjusted server-side | Cost values are pushed pre-multiplied by `(1 + risk_adj)`; field-level adjustment stays 0 |
| **Year-0 "Initial" costs** | No year-0 concept; non-annual values are folded into Year 1 | Each cost gets a companion non-annual `<key>_initial` field. `TEIClient` folds them back into an `initial` key on read. Athena discounts these as Year 1 (Forrester doesn't discount Year 0) — expect ≈0.15% drift on cost PV |
---
## Report Pipeline Integration
Palladium's export produces structured JSON consumed by the LLM report generation pipeline:
```
Palladium Export (JSON)
Peitho — LLM generates HTML (following HTML_DOCUMENT_FORMAT.md)
html2docx converts to native Word
Professional TEI Report (.docx)
```
The export envelope (`core.export.build_report_data`) includes:
- All benefit categories with risk-adjusted values
- All cost categories with yearly breakdown (and Initial column)
- Financial summary (NPV, ROI, payback, yearly cashflow)
- Conservative / moderate / aggressive scenario analysis
- Metadata (study slug, proposal, engagement, generator stamp)
- The raw Athena `/export/` payload for reference
---
## Version Management
Athena keeps version history for TEI tools, driven through the API
(`core.tei_client`: `save_version` / `list_versions` / `get_version`):
1. **Save Version** — Snapshots current values + summary with a descriptive note
2. **View History** — All versions with headline metrics (NPV, ROI)
3. **Compare Versions** — Side-by-side diff of value changes between any two versions
4. **Restore Version** — Load a previous version's values as the current state
Version notes should capture:
- Assumptions made and their sources
- Which scenario the version represents
- What changed since the previous version
- Client confirmations or corrections
---
## Development
### Running Tests
```bash
pytest tests/ -v
```
Tests are designed to run without an Athena connection — HTTP is mocked
and the calculation suite uses the Amazon Connect seed data to verify the
Forrester numbers reproduce within rounding.
### Code Style
```bash
ruff check .
ruff format .
```
### Adding a New Benefit Category
1. Define the field in Athena's TEI Report admin (field name, type, category, defaults)
2. The field automatically appears in Palladium via the API — no client changes
3. Update notebook prose if category-specific commentary is needed
4. If the report template exposes a new structure, extend the envelope in
`core/export/report_data.py`
---
## Dependencies
| Package | Version | Purpose |
|---------|---------|---------|
| `requests` | ≥2.31 | HTTP client for Athena API |
| `python-dotenv` | ≥1.0 | Environment configuration |
| `jupyter` | ≥1.0 | Notebook environment |
| `pandas` | ≥2.0 | Data manipulation |
| `plotly` | ≥5.18 | Interactive visualizations |
| `numpy` | ≥1.26 | Financial calculations |
| `pytest` | ≥7.4 | Testing |
| `ruff` | ≥0.1 | Linting and formatting |
---
## Related Projects
| Project | Relationship |
|---------|-------------|
| **Athena** | Platform API — data persistence, cross-tool reporting |
| **Peitho** | Document generation — consumes Palladium's export JSON |
| **html2docx** | Converts LLM-generated HTML to native Word documents |