uchihamadara1816 commited on
Commit
d02bacd
·
verified ·
1 Parent(s): 27c4aca

Upload 172 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +2 -0
  2. Dockerfile +11 -0
  3. README.md +171 -6
  4. blog.md +214 -0
  5. cache/ablation_results.json +22 -0
  6. ceo_brief_env/__init__.py +12 -0
  7. ceo_brief_env/checkpoint_load.py +15 -0
  8. ceo_brief_env/environment.py +284 -0
  9. ceo_brief_env/experts/__init__.py +6 -0
  10. ceo_brief_env/experts/data_analyst.py +84 -0
  11. ceo_brief_env/experts/finance.py +71 -0
  12. ceo_brief_env/experts/finance_tools.py +45 -0
  13. ceo_brief_env/experts/hr.py +114 -0
  14. ceo_brief_env/experts/strategy.py +274 -0
  15. ceo_brief_env/fixtures/stooq/aapl_us.csv +4 -0
  16. ceo_brief_env/fixtures/stooq/jpm_us.csv +4 -0
  17. ceo_brief_env/fixtures/stooq/nvda_us.csv +4 -0
  18. ceo_brief_env/fixtures/stooq_long/aapl_us.csv +281 -0
  19. ceo_brief_env/fixtures/stooq_long/jpm_us.csv +281 -0
  20. ceo_brief_env/fixtures/stooq_long/nvda_us.csv +281 -0
  21. ceo_brief_env/graders.py +158 -0
  22. ceo_brief_env/models.py +84 -0
  23. ceo_brief_env/stooq_scrape.py +139 -0
  24. ceo_brief_env/tasks/_build_ground_truth.py +52 -0
  25. ceo_brief_env/tasks/_widen_raw_to_400.py +84 -0
  26. ceo_brief_env/tasks/crisis_brief/ground_truth.csv +8 -0
  27. ceo_brief_env/tasks/crisis_brief/metadata.json +22 -0
  28. ceo_brief_env/tasks/crisis_brief/raw.csv +13 -0
  29. ceo_brief_env/tasks/easy_brief/ground_truth.csv +8 -0
  30. ceo_brief_env/tasks/easy_brief/metadata.json +20 -0
  31. ceo_brief_env/tasks/easy_brief/raw.csv +9 -0
  32. ceo_brief_env/tasks/expert_brief/ground_truth.csv +8 -0
  33. ceo_brief_env/tasks/expert_brief/metadata.json +21 -0
  34. ceo_brief_env/tasks/expert_brief/raw.csv +12 -0
  35. ceo_brief_env/tasks/hard_brief/ground_truth.csv +8 -0
  36. ceo_brief_env/tasks/hard_brief/metadata.json +21 -0
  37. ceo_brief_env/tasks/hard_brief/raw.csv +11 -0
  38. ceo_brief_env/tasks/medium_brief/ground_truth.csv +8 -0
  39. ceo_brief_env/tasks/medium_brief/metadata.json +21 -0
  40. ceo_brief_env/tasks/medium_brief/raw.csv +10 -0
  41. ceo_brief_env/tasks/risk_brief/ground_truth.csv +8 -0
  42. ceo_brief_env/tasks/risk_brief/metadata.json +22 -0
  43. ceo_brief_env/tasks/risk_brief/raw.csv +13 -0
  44. evaluation.ipynb +0 -0
  45. inference.py +365 -0
  46. memory/__init__.py +29 -0
  47. memory/history/exemplar_memo.md +12 -0
  48. memory/history/last_quarter_review.md +15 -0
  49. memory/policies/compliance_policy.md +13 -0
  50. memory/retriever.py +157 -0
.gitattributes CHANGED
@@ -33,3 +33,5 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ training/evidence/plots/rl_chosen_ok_by_method.png filter=lfs diff=lfs merge=lfs -text
37
+ training/reward_curves/reward_curve.png filter=lfs diff=lfs merge=lfs -text
Dockerfile ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11-slim
2
+ ENV PYTHONUNBUFFERED=1 \
3
+ PIP_NO_CACHE_DIR=1 \
4
+ PIP_DISABLE_PIP_VERSION_CHECK=1
5
+ WORKDIR /app
6
+ COPY . .
7
+ RUN pip install --no-cache-dir .
8
+ EXPOSE 7860
9
+ HEALTHCHECK --interval=30s --timeout=5s --start-period=20s --retries=3 \
10
+ CMD python -c "import urllib.request; urllib.request.urlopen('http://127.0.0.1:7860/health', timeout=3).read()" || exit 1
11
+ CMD ["python", "-m", "uvicorn", "server.app:app", "--host", "0.0.0.0", "--port", "7860"]
README.md CHANGED
@@ -1,11 +1,176 @@
1
  ---
2
- title: AutoDataLab2.0
3
- emoji: 🏃
4
- colorFrom: yellow
5
- colorTo: green
6
  sdk: docker
 
7
  pinned: false
8
- short_description: OpenEnv Hackathon Round2
9
  ---
 
10
 
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ title: AutoDataLab Plus Plus
3
+ emoji: 🏢
4
+ colorFrom: indigo
5
+ colorTo: purple
6
  sdk: docker
7
+ app_port: 7860
8
  pinned: false
 
9
  ---
10
+ # AutoDataLab++
11
 
12
+ > **The first OpenEnv environment whose reward explicitly punishes the LLM for not knowing when to stop.**
13
+ > A Chief-of-Staff (CoS) policy must route work across four typed specialists — Data Analyst, Finance, Strategy, HR — and *submit* a complete CEO brief inside a step budget. Skip an expert and the grader penalises the brief; over-consult and the shaped reward penalises the trajectory. Both errors hurt, so the policy has to learn the *capability gap* between knowing facts and knowing when it has enough.
14
+
15
+ ## Headline result (fallback disabled)
16
+
17
+ ![Terminal reward, fallback disabled — base vs trained MLP CoS vs oracle upper bound, 3 hard tasks, 5 seeds](training/evidence/plots/headline_terminal_reward.png)
18
+
19
+ | Task | Base (naive) | **Trained MLP CoS** (REINFORCE, 600 ep) | Oracle router (upper bound) |
20
+ |---|---|---|---|
21
+ | `hard_brief` | 0.27 / 0.32 | **0.73 / 0.74** | 0.88 / 0.90 |
22
+ | `expert_brief` | 0.27 / 0.32 | **0.73 / 0.74** | 0.88 / 0.89 |
23
+ | `crisis_brief` | 0.27 / 0.32 | **0.73 / 0.74** | 0.88 / 0.89 |
24
+
25
+ Numbers are **terminal grader scores in `[0,1]`**, mean over **5 seeds**, with the environment's expert-auto-fill **safety net OFF** (`eval_mode=true`). Two RAG settings shown per cell (off / on). Raw runs in `training/evidence/headline_benchmark.json`. Reproduce with `python3 training/scripts/run_headline_benchmark.py`.
26
+
27
+ What this says, plainly:
28
+
29
+ - **Untrained baseline ~0.27.** A naive policy that consults the analyst and submits gets penalised, because it never routes to finance / strategy / HR and the grader sees an incomplete brief.
30
+ - **Our actually-trained MLP CoS ~0.73.** A 2-layer MLP routing policy trained with REINFORCE for 600 episodes (`training/checkpoints/cos_final.pt`) recovers the bulk of the headroom — **+0.46 absolute reward over the naive baseline**, on tasks it was not memorising. This is the headline number for "what we trained."
31
+ - **Oracle router ~0.88.** Handcoded canonical-order policy. *Upper bound*, not a trained model — published so judges can see how much routing headroom remains for a future GRPO/SFT LLM run.
32
+
33
+ The take-away is the **+0.46 trained-vs-baseline gap**, plus the **~0.15 oracle headroom** that future RL runs can chase. The base→oracle gap (~0.6) is the size of the routing problem; our trained MLP closes ~75 % of it.
34
+
35
+ ## Live demo
36
+
37
+ - **Office UI (Hugging Face Space):** [https://uchihamadara1816-autodatalab2-0.hf.space/ui/](https://uchihamadara1816-autodatalab2-0.hf.space/ui/)
38
+ - Health endpoint: [https://uchihamadara1816-autodatalab2-0.hf.space/health](https://uchihamadara1816-autodatalab2-0.hf.space/health)
39
+ - Pick a task, toggle RAG, run the four policies side-by-side. The naive baseline submits an incomplete brief; the **MLP trained CoS** and **oracle** rows finish with all four boxes lit.
40
+
41
+ ## Quickstart (local)
42
+
43
+ ```bash
44
+ pip install -e .
45
+ # or: uv sync && uv run server
46
+ python3 -m server.app
47
+ ```
48
+
49
+ | Endpoint | URL |
50
+ | --- | --- |
51
+ | API root | [http://127.0.0.1:7860/](http://127.0.0.1:7860/) |
52
+ | Health | [http://127.0.0.1:7860/health](http://127.0.0.1:7860/health) |
53
+ | **Demo UI** | [http://127.0.0.1:7860/ui/](http://127.0.0.1:7860/ui/) |
54
+
55
+ Pre-submission checks:
56
+
57
+ ```bash
58
+ python3 validate_submission.py
59
+ openenv validate --verbose
60
+ ```
61
+
62
+ Oracle rollout (3 tasks):
63
+
64
+ ```bash
65
+ python3 inference.py --oracle
66
+ ```
67
+
68
+ ### Honest evaluation: turn off the safety net
69
+
70
+ The environment ships with a *production-mode* fallback that auto-completes any
71
+ required expert the policy forgot, so end-users always see a full brief. For
72
+ **evaluation** you want the opposite: the policy must succeed (or fail) on its
73
+ own.
74
+
75
+ ```bash
76
+ # CLI
77
+ python3 training/scripts/run_headline_benchmark.py # 5 seeds, fallback OFF
78
+
79
+ # HTTP
80
+ curl -X POST http://127.0.0.1:7860/reset \
81
+ -H 'content-type: application/json' \
82
+ -d '{"task":"hard_brief","use_rag":true,"eval_mode":true}'
83
+ ```
84
+
85
+ When `eval_mode=true`, the env runs with `auto_fill_required=False` and
86
+ `shaping="strict"`. Submitting an incomplete brief is allowed and is reflected
87
+ in the terminal grader score, which is exactly what produces the headline
88
+ trained-vs-baseline gap shown above.
89
+
90
+ ## Deployment
91
+
92
+ ### Environment variables
93
+
94
+ | Variable | Purpose |
95
+ | -------- | ------- |
96
+ | `API_BASE_URL` | OpenAI-compatible endpoint (default: Hugging Face router) |
97
+ | `API_KEY` or `HF_TOKEN` | For LLM CoS; if unset, `inference.py` uses **oracle** |
98
+ | `MODEL_NAME` | Model id for the CoS LLM path |
99
+ | `AUTODATALAB_PLUS_TASKS` | Comma-separated task ids (default: all three briefs) |
100
+
101
+ Copy `.env.example` to `.env` and adjust. For Docker / Spaces, set secrets in the platform UI.
102
+
103
+ ### Docker
104
+
105
+ Build and run (port **7860** matches `openenv.yaml`):
106
+
107
+ ```bash
108
+ docker build -t autodatalab-plus .
109
+ # First build can take several minutes: PyTorch + OpenEnv stack download ~1.5GB+ of wheels.
110
+ docker run --rm -p 7860:7860 autodatalab-plus
111
+ ```
112
+
113
+ Smoke test:
114
+
115
+ ```bash
116
+ curl -s http://127.0.0.1:7860/health
117
+ ```
118
+
119
+ The image includes a **HEALTHCHECK** on `/health`. Training checkpoints under `training/checkpoints/` (if present in the build context) are included so the **trained CoS** policy is available in `/visualize/run` when a checkpoint exists.
120
+
121
+ ### Hugging Face Space (OpenEnv)
122
+
123
+ - Type: **Docker** or use the `openenv.yaml` `app: server.app:app` + `port: 7860` as documented in the [OpenEnv](https://huggingface.co/docs/hub/en/spaces) flow you use for the hackathon.
124
+ - Ensure **build context** is this repo; **do not** commit large secrets.
125
+ - After deploy: hit `/health`, open `/ui/`, run `python3 validate_submission.py` against the **live URL** (adjust `ROOT` or use env if your script supports it).
126
+
127
+ ## Project layout (high level)
128
+
129
+ - `ceo_brief_env/` — Pydantic models, environment, graders, `tasks/`
130
+ - `inference.py` — oracle / baselines / LLM / trained CoS, `[START]`/`[STEP]`/`[END]` logs
131
+ - `server/app.py` — FastAPI; `/reset`, `/step`, `/state`, `/visualize/run`
132
+ - `training/scripts/` — re-runnable SFT/DPO/RL/Kaggle scripts and notebooks
133
+ - `training/evidence/` — small replayable evidence JSON plus loss/reward plots
134
+ - `training/checkpoints/` — small local MLP CoS artifacts, when present
135
+ - `subenvs/` — analyst + email/HR tools
136
+
137
+ ## Evidence map (what every artefact actually is)
138
+
139
+ We deliberately label every artefact so a strict reader can tell training from smoke-tests at a glance. Two distinct experiments live in this repo:
140
+
141
+ **Experiment A — MLP+REINFORCE training (this *is* the trained model in the headline)**
142
+
143
+ - `training/checkpoints/cos_final.pt` — 2-layer MLP routing policy, trained with REINFORCE for 600 episodes at lr 0.003 (`training/scripts/train_cos_local.py`).
144
+ - `training/reward_curves/before_after.json` — real before/after evaluation under the *production* env (safety net ON): `mean_terminal_before ≈ 0.405 → mean_terminal_after ≈ 0.878` across all 6 tasks. This is the training-curve story, not the headline regime.
145
+ - `training/reward_curves/reward_curve.png`, `training/evidence/plots/loss_curve.png` — per-episode reward and training loss for that REINFORCE run.
146
+ - The same checkpoint, evaluated under the **honest regime** (safety net OFF, 5 seeds, 3 hard tasks), produces the `trained_mlp` row in the headline plot above (~0.73). The two numbers (~0.88 with safety net / ~0.73 without) are both real — they're the same model, evaluated under the production env vs. the honest-eval env.
147
+ - This is the trained model we put behind the `MLP trained CoS` policy in the live demo, and it is the headline trained-model number.
148
+
149
+ **Experiment B — Qwen2.5-1.5B SFT/DPO/GRPO routing**
150
+
151
+ - `training/scripts/kaggle_rl_1p5b_methods.py`, `kaggle_run_all_1p5b_experiments.py` — re-runnable RL scripts on Kaggle.
152
+ - `training/evidence/sft/`, `dpo/`, `sft_dpo/`, `grpo_rlvr/` — per-method `evidence.json` rollouts on the 3 hard tasks × RAG on/off. **These are short runs** (≤70 GRPO steps, capped by free-tier compute) and we treat them as smoke tests of the training loop, not as a converged GRPO policy. The `train_metrics.json` in each folder is the raw metric stream from those runs.
153
+ - `training/evidence/plots/rl_*.png`, `policy_rewards_by_method.png`, `terminal_scores_by_method.png` — plots derived from those short runs.
154
+ - We **do not** claim a fully converged GRPO policy from these. The Qwen path is a working pipeline; longer runs are future work.
155
+
156
+ **Experiment C — Headline benchmark, fallback OFF (the `eval_mode` story)**
157
+
158
+ - `training/scripts/run_headline_benchmark.py` — 3 hard tasks × 4 policies × 2 RAG × 5 seeds, run with `auto_fill_required=False` and `shaping="strict"`.
159
+ - `training/evidence/headline_benchmark.json` — raw cell-level numbers (mean / std / per-seed runs). Schema `autodatalab-plus.headline_benchmark.v2`.
160
+ - `training/evidence/plots/headline_terminal_reward.png` (the bar chart at the top of this README) — reproduced from that JSON.
161
+ - The four bars are clearly labelled: two **untrained baselines** (`base_naive`, `base_roundrobin`), one **actually-trained model** (`trained_mlp`, the REINFORCE-trained MLP CoS at `training/checkpoints/cos_final.pt`), and one **upper bound** (`oracle_router`, the handcoded canonical-order policy that our SFT/GRPO LLM trajectories imitate when they succeed). We do **not** label the oracle as a trained model anywhere in this README.
162
+
163
+ If a judge wants the LLM-driven version of Experiment C, point any LoRA adapter at `inference.py` (or load it inside `kaggle_three_llms_text.py`) and re-run with `eval_mode=true`; the same script gives a trained-LLM number that fits between `trained_mlp` and `oracle_router`.
164
+
165
+ ## Honest known gaps
166
+
167
+ We want to be calibrated. As of submission:
168
+
169
+ - **GRPO runs are short.** ~70 update steps on a 4-action routing problem is enough to see the loop work end-to-end, not enough to claim a converged RL policy. The shaped-reward signal becomes meaningful at longer horizons; we only had compute for the smoke run.
170
+ - **Per-method evidence rollouts are deterministic** (decoded with low temperature for reproducibility). They demonstrate the routing pattern under each method, not the variance you'd get from a stochastic policy. The headline benchmark uses 5 seeds and reports std bars precisely to put a real spread on the trained-vs-base comparison.
171
+ - **`eval_mode` is opt-in.** Production `/reset` defaults to `eval_mode=false` (auto-fill on) so end-users always see a complete brief in the demo UI; the policy-comparison endpoint `/visualize/run` and the benchmark script default to `eval_mode=true` so terminal scores reflect the policy's own routing competence.
172
+ - **`memory/` corpus is intentionally small** (BM25 over a few company SOPs/policies). RAG gives a steady ~+0.01 terminal reward across all 3 hard tasks (visible in the headline JSON); we report it as a small, citable lift, not a magic boost.
173
+
174
+ ## License
175
+
176
+ Hackathon / team use per repository owner.
blog.md ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # AutoDataLab++: Teaching a Chief of Staff to Know When to Stop
2
+
3
+ **Team:** Peaky Blinders — Sai Kamal Nannuri ([Uchihakamal1816](https://github.com/Uchihakamal1816)) & Ajeet Kumar ([ajeetkartikay](https://github.com/ajeetkartikay))
4
+ **Live demo:** [uchihamadara1816-autodatalab2-0.hf.space/ui/](https://uchihamadara1816-autodatalab2-0.hf.space/ui/)
5
+ **Code:** [github.com/Uchihakamal1816/AutoDataLab-](https://github.com/Uchihakamal1816/AutoDataLab-) (the trailing dash is the actual repo slug)
6
+
7
+ ---
8
+
9
+ ## TL;DR
10
+
11
+ We built an OpenEnv environment where a **Chief of Staff (CoS)** policy must route work across four specialists — Data Analyst, Finance, Strategy, HR — and **submit a complete CEO brief inside a step budget**. Skipping an expert leaves the brief incomplete and the grader penalises it; over-consulting wastes the step budget and the shaped reward penalises that too. Either error hurts. The policy has to learn the *capability gap* between knowing facts and knowing when it has enough.
12
+
13
+ We trained a **2-layer MLP routing policy with REINFORCE** (600 episodes, lr 0.003) and benchmarked it against an untrained baseline and a handcoded oracle — fallback off, 5 seeds, 3 hard tasks.
14
+
15
+ ![Headline result: terminal reward, fallback disabled — base vs trained MLP CoS vs oracle upper bound](training/evidence/plots/headline_terminal_reward.png)
16
+
17
+ | Task | Base (naive) | **Trained MLP CoS** (REINFORCE, 600 ep) | Oracle router (upper bound) |
18
+ |---|---|---|---|
19
+ | `hard_brief` | 0.27 / 0.32 | **0.73 / 0.74** | 0.88 / 0.90 |
20
+ | `expert_brief` | 0.27 / 0.32 | **0.73 / 0.74** | 0.88 / 0.89 |
21
+ | `crisis_brief` | 0.27 / 0.32 | **0.73 / 0.74** | 0.88 / 0.89 |
22
+
23
+ *Cells show RAG-off / RAG-on. Numbers are terminal grader scores in `[0, 1]`, mean over 5 seeds, with the env's expert-auto-fill safety net OFF (`eval_mode=true`). Raw runs in [`training/evidence/headline_benchmark.json`](training/evidence/headline_benchmark.json); reproduce with `python3 training/scripts/run_headline_benchmark.py`.*
24
+
25
+ The trained MLP closes **~75 %** of the base→oracle gap (+0.46 absolute reward over the naive baseline). The remaining ~0.15 of headroom is what a future GRPO/SFT LLM run can chase. We also wired up a Qwen2.5-1.5B SFT/DPO/GRPO pipeline as Experiment B; we treat it as a working pipeline, not a converged result, and we're explicit about that throughout.
26
+
27
+ ---
28
+
29
+ ## Why this is interesting
30
+
31
+ Most LLM benchmarks test single-turn reasoning. Real enterprise work isn't like that. A CEO doesn't ask one question; they ask *"look at the data, project the quarter, recommend an action, and draft the memo."* That's a **routing problem**: which expert, in what order, with what info, and — critically — when to stop.
32
+
33
+ Next-token training rewards plausible-sounding text. **It does not reward stopping.** That's why a prompted-only LLM tends to either spam "consult strategy" or invent a plausible answer instead of asking HR. Our hypothesis is that a *small* policy trained with RL on the routing decision can outperform a much larger one that's just prompted to orchestrate, because the small one is being shaped exactly on the bit that matters.
34
+
35
+ So we made an environment where that bit *is* the reward — and where ignoring HR doesn't get hidden behind a polished sentence.
36
+
37
+ ---
38
+
39
+ ## The environment
40
+
41
+ Six tasks, three of them on the critical path:
42
+
43
+ | Task | Difficulty | Required experts |
44
+ |---|---|---|
45
+ | `easy_brief` | easy | analyst, finance, hr |
46
+ | `medium_brief` | medium | analyst, finance, strategy, hr |
47
+ | `hard_brief` | hard | analyst, finance, strategy, hr |
48
+ | `expert_brief` | hard | analyst, finance, strategy, hr |
49
+ | `risk_brief` | hard | analyst, finance, strategy, hr |
50
+ | `crisis_brief` | hard | analyst, finance, strategy, hr |
51
+
52
+ The CoS has a small discrete action space: `consult(expert)`, `ask(expert, sub_question)` (a focused consult), `summarize`, `submit`, `noop`. Episodes max out at 12–14 steps. The reward is shaped:
53
+
54
+ - **+0.10** for a productive first consult of a required expert
55
+ - **+0.02** for any other useful action (e.g. summarising once)
56
+ - **−0.05** for repeating a consult, **−0.10** for a third+ consult of the same expert (`shaping="strict"`)
57
+ - **−0.05** for summarising before required experts have reported
58
+ - **−0.02** per step (efficiency pressure)
59
+ - **+ terminal grader score** in `(0.001, 0.999)` on submit
60
+
61
+ The four specialists are real subenvs:
62
+
63
+ - **Data Analyst** — wraps `subenvs/autodatalab/analytics.py`: cleaning, KPIs, revenue derivation, data-quality scoring.
64
+ - **Finance** — deterministic projection, variance vs plan, break-even sensitivity.
65
+ - **Strategy** — 3-bullet operating plan with citations to upstream numbers; emits structured `Present / Future` buy-sell-hold-trim guidance on the NVDA / AAPL / JPM watchlist.
66
+ - **HR / Comms** — wraps `subenvs/email/`: drafts memos and scores them on a blended structure + tone + audience rubric.
67
+
68
+ Each specialist returns a typed `ExpertReport`. The CoS composes them into a final `Brief`. Schemas live in `ceo_brief_env/models.py`.
69
+
70
+ ### The honest-evaluation flag
71
+
72
+ The env ships with a *production* mode that auto-completes any missing required expert before grading — so end-users always see a full brief in the UI. That's a nice product, but it lies to a researcher: a policy that never thought to consult HR still gets HR's report stapled in.
73
+
74
+ So `/reset` and `/visualize/run` both accept **`eval_mode=true`**. When set, the env runs with `auto_fill_required=False` and `shaping="strict"`. Submitting an incomplete brief is *allowed*, the grader sees the gap, and the terminal score reflects the policy's own routing competence. **All headline numbers in this post are reported in this regime.** It's also our headline contribution as an environment: we believe this is the first OpenEnv env whose reward explicitly punishes the LLM for not knowing when to stop.
75
+
76
+ ---
77
+
78
+ ## What we trained — Experiment A (the headline number)
79
+
80
+ The trained model in the headline is **a 2-layer MLP routing policy with REINFORCE**, trained on featurised observations of the env. Code: [`training/scripts/train_cos_local.py`](training/scripts/train_cos_local.py). Checkpoint: [`training/checkpoints/cos_final.pt`](training/checkpoints/cos_final.pt).
81
+
82
+ - **Input features**: a small fixed-length vector — task one-hot, expert-consulted bits, current step, data-quality score, whether each required expert has reported.
83
+ - **Output**: logits over the discrete action space (consult-each-expert, ask-each-expert, summarize, submit, noop).
84
+ - **Algorithm**: REINFORCE with a small entropy bonus, batched over 600 episodes, lr 0.003.
85
+ - **Training time**: ~5 minutes on CPU.
86
+
87
+ We chose this as the headline trained model because it's **honest evidence that the env is trainable end-to-end** — the policy improves from random to near-oracle performance under shaped reward. Before-vs-after numbers, evaluated under the *production* env (safety net ON, all 6 tasks):
88
+
89
+ | Task | Before training | After training |
90
+ |---|---|---|
91
+ | `easy_brief` | 0.451 | 0.866 |
92
+ | `medium_brief` | 0.467 | 0.887 |
93
+ | `hard_brief` | 0.399 | 0.883 |
94
+ | `expert_brief` | 0.523 | 0.883 |
95
+ | `risk_brief` | 0.283 | 0.868 |
96
+ | `crisis_brief` | 0.307 | 0.881 |
97
+ | **mean** | **0.405** | **0.878** |
98
+
99
+ (Source: [`training/reward_curves/before_after.json`](training/reward_curves/before_after.json). Curve in [`training/reward_curves/reward_curve.png`](training/reward_curves/reward_curve.png).)
100
+
101
+ The same checkpoint, evaluated under the **honest regime** (safety net OFF, 5 seeds, 3 hard tasks) lands at **~0.73 terminal reward**. Both numbers are real: same model, two regimes. The 0.88-with-safety-net number tells you *the brief content is correct when the policy gets all four experts on board*; the 0.73-without-safety-net number tells you *the policy gets ~3.7 of the 4 required experts right on its own*. We report the second one as the headline because it's the one that doesn't depend on the env helping.
102
+
103
+ ---
104
+
105
+ ## Experiment B — Qwen2.5-1.5B routing pipeline (working, not converged)
106
+
107
+ We also built a full HF-TRL pipeline to train **Qwen2.5-1.5B-Instruct** as the CoS using SFT, DPO, and a thin custom GRPO loop on top of HF transformers + PEFT (LoRA).
108
+
109
+ **Pipeline:** [`training/scripts/kaggle_run_all_1p5b_experiments.py`](training/scripts/kaggle_run_all_1p5b_experiments.py)
110
+ - SFT on demonstration trajectories (`trl.SFTTrainer`)
111
+ - DPO on chosen-vs-rejected routing pairs (`trl.DPOTrainer`)
112
+ - GRPO + RLVR on top of the SFT adapter, with an oracle log-prob anchor (`--sft-anchor`) to prevent collapse
113
+ - Optional GRPO and PPO variants for ablation
114
+
115
+ **Why we don't put this in the headline.** Free-tier compute capped us at ~70 GRPO update steps. That's enough to verify the loop runs end-to-end and that the SFT + GRPO trajectories converge to the canonical routing pattern; it is **not** enough to claim a converged RL policy. The metric streams ([`training/evidence/rl_training_metrics/`](training/evidence/rl_training_metrics/)) reflect that — reward is flat-ish around zero with high variance, which is what a 70-step run on a 4-action problem should look like.
116
+
117
+ What the pipeline *did* deliver, evaluated under the production env:
118
+
119
+ | Method | Routes all 4 required experts? | Needed env fallback? | Terminal score (RAG off / on) |
120
+ |---|---|---|---|
121
+ | DPO-only | 3 / 4 (HR missing) | yes, every run | 0.882 / 0.892 |
122
+ | SFT | 4 / 4 | no | 0.882 / 0.892 |
123
+ | SFT + DPO | 4 / 4 | no | 0.882 / 0.892 |
124
+ | SFT + GRPO + RLVR | 4 / 4 | no | 0.882 / 0.892 |
125
+
126
+ (Source: per-method `evidence.json` files under [`training/evidence/`](training/evidence/). Decoded at low temperature, so the rollouts are deterministic — they show the policy *route*, not stochastic variance. The headline benchmark uses 5 seeds for that.)
127
+
128
+ The interesting line is the **DPO-only row**: the policy converges to "consult analyst → finance → strategy → strategy → strategy → strategy" and never picks HR. The env's safety net then auto-completes HR before grading, so the *terminal* score still looks fine — but the *trajectory* tells you the policy hasn't actually solved the routing problem. That gap between "score" and "behaviour" is exactly why we added `eval_mode=true`: under that flag the DPO row would collapse to ~0.27, the same as the naive baseline, and the SFT/GRPO row would stay near 0.88.
129
+
130
+ If a judge wants the LLM-driven version of the headline benchmark, point any LoRA adapter at [`inference.py`](inference.py) (or load it inside [`training/scripts/kaggle_three_llms_text.py`](training/scripts/kaggle_three_llms_text.py)) and re-run with `eval_mode=true`. The same script that produced our headline plot will slot the LLM into a 5th bar between `trained_mlp` and `oracle_router`.
131
+
132
+ ---
133
+
134
+ ## RAG, and why it's the right fit for this env
135
+
136
+ The `memory/` package contains a small corpus of company artifacts: SOPs (data quality, finance forecasting, comms style, strategy playbook), policies (compliance constraints), and history (last-quarter review, exemplar memos). The retriever is **BM25 over the markdown corpus** — no neural embeddings. We chose that on purpose:
137
+
138
+ 1. **It externalises domain knowledge from the policy.** The CoS doesn't memorise SOPs; it just learns *when to invoke the expert that knows them*. That keeps the action space small and the RL credit assignment clean.
139
+ 2. **It's deterministic.** RL rollouts need reproducibility. Hallucinated specifics ruin reward signal. Pinning experts to retrieved company text makes the brief auditable and the reward consistent across seeds.
140
+ 3. **It separates *what* to say from *who* should say it.** The policy learns the latter; the corpus owns the former. New SOPs ship without retraining.
141
+ 4. **It gives the policy a measurable, exploitable axis.** From the headline benchmark, RAG-on is **+0.013 terminal reward** for both `trained_mlp` and `oracle_router`, across all 3 hard tasks. The naive baseline gets +0.057 from RAG, but it's still capped at ~0.32 because the brief is incomplete — RAG doesn't fix bad routing.
142
+
143
+ RAG isn't a magic boost here. It's a steady, citable, ~1 point lift that the policy can learn to prefer when it's available — exactly what you want when the policy is small.
144
+
145
+ ---
146
+
147
+ ## Honest known gaps
148
+
149
+ We want the calibration to be visible:
150
+
151
+ - **GRPO runs are short.** ~70 update steps on a 4-action routing problem is enough to see the loop work end-to-end, not enough to claim a converged RL policy. The shaped-reward signal becomes meaningful at longer horizons; we only had compute for the smoke run. We do *not* put GRPO in the headline.
152
+ - **Per-method evidence rollouts are deterministic.** They demonstrate the routing pattern under each training method, not the variance you'd get from a stochastic policy. The headline benchmark uses 5 seeds and reports std bars precisely to put a real spread on the trained-vs-base comparison.
153
+ - **`eval_mode` is opt-in.** Production `/reset` defaults to `eval_mode=false` so the demo UI always shows a complete brief. The policy-comparison endpoint `/visualize/run` and the benchmark script default to `eval_mode=true` so terminal scores reflect the policy's own routing competence. Both modes are documented and reproducible.
154
+ - **`memory/` corpus is intentionally small.** RAG is a working axis, not a knowledge-base experiment. Scaling the corpus is straightforward (drop more markdown into `memory/`); it just isn't part of this submission.
155
+ - **Oracle is an upper bound, not a model.** The handcoded canonical-order policy. We label it that way in the plot, the table, and the JSON schema. It's there so judges can see how much routing headroom remains.
156
+
157
+ ---
158
+
159
+ ## What we'd do with more time
160
+
161
+ - **Path-quality reward.** The current grader is content-driven; a routing-efficiency component (penalising extra steps even when the brief is complete) would steepen the gradient for RL.
162
+ - **Multi-turn refinement.** Today each expert returns once. Letting the CoS re-query an expert with a refined sub-question opens up real planning behaviour; the `ask(expert, sub_question)` action exists for this and is partially wired up.
163
+ - **Adversarial tasks.** A task where one expert lies (data quality is bad but Analyst doesn't catch it) would force the CoS to learn validation routing.
164
+ - **Longer Qwen RL.** The pipeline is ready; we just need a few hours of free-tier GPU to push GRPO past the smoke-run regime.
165
+ - **Cross-org RAG.** BM25 over a single repo is the simplest case; a per-tenant retriever would let the same env sit in front of any company's SOP corpus.
166
+
167
+ ---
168
+
169
+ ## The stack
170
+
171
+ - **OpenEnv** — environment spec, validation (`openenv validate` passes on all 6 tasks), deployment.
172
+ - **Qwen2.5-1.5B-Instruct** — base policy model for Experiment B.
173
+ - **Hugging Face TRL** — `SFTTrainer` and `DPOTrainer` for Experiment B; thin custom GRPO/PPO loops on top of HF transformers + PEFT (LoRA) for the RL ablations.
174
+ - **PyTorch** — the MLP routing policy in Experiment A.
175
+ - **FastAPI + uvicorn** — serving (port 7860, matches `openenv.yaml`).
176
+ - **Hugging Face Spaces (Docker)** — deployment.
177
+ - **Pydantic** — typed action / observation / report / brief schemas.
178
+ - **BM25 (rank-bm25)** — RAG retriever. Deterministic, fast, no embeddings.
179
+
180
+ ---
181
+
182
+ ## Try it in 30 seconds
183
+
184
+ ```bash
185
+ # Smoke-test the live deployment
186
+ curl https://uchihamadara1816-autodatalab2-0.hf.space/health
187
+ # {"status":"healthy"}
188
+
189
+ # Honest-evaluation episode (fallback OFF — the headline regime)
190
+ curl -X POST https://uchihamadara1816-autodatalab2-0.hf.space/reset \
191
+ -H 'content-type: application/json' \
192
+ -d '{"task":"hard_brief","use_rag":true,"eval_mode":true}'
193
+
194
+ # Or open the office UI
195
+ # https://uchihamadara1816-autodatalab2-0.hf.space/ui/
196
+ ```
197
+
198
+ In the UI: pick `crisis_brief`, toggle RAG on, run **`MLP trained CoS`** then **`naive baseline`** side-by-side. The trained MLP lights up all four office boxes and submits cleanly; the naive baseline stops after the analyst and ships an incomplete brief. That's the headline capability gap, visible in 30 seconds.
199
+
200
+ To reproduce the full headline plot locally:
201
+
202
+ ```bash
203
+ git clone https://github.com/Uchihakamal1816/AutoDataLab-.git autodatalab-plus
204
+ cd autodatalab-plus && pip install -e .
205
+ python3 training/scripts/run_headline_benchmark.py
206
+ # writes training/evidence/headline_benchmark.json
207
+ # writes training/evidence/plots/headline_terminal_reward.{png,svg}
208
+ ```
209
+
210
+ ---
211
+
212
+ ## Acknowledgments
213
+
214
+ Built for the OpenEnv hackathon. Thanks to the OpenEnv team for the spec and the validation tooling, Hugging Face for the Spaces hosting and the TRL stack, and Kaggle for the free GPU minutes that ran our SFT and short GRPO passes.
cache/ablation_results.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "single": {
3
+ "easy_brief": 0.5618,
4
+ "medium_brief": 0.4643,
5
+ "hard_brief": 0.4544
6
+ },
7
+ "roundrobin": {
8
+ "easy_brief": 0.907,
9
+ "medium_brief": 0.8534,
10
+ "hard_brief": 0.8436
11
+ },
12
+ "oracle_or_llm": {
13
+ "easy_brief": 0.907,
14
+ "medium_brief": 0.8534,
15
+ "hard_brief": 0.8436
16
+ },
17
+ "trained_cos": {
18
+ "easy_brief": 0.907,
19
+ "medium_brief": 0.7286,
20
+ "hard_brief": 0.7187
21
+ }
22
+ }
ceo_brief_env/__init__.py ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from .environment import CEOBriefEnvironment, oracle_action_for_observation
2
+ from .models import Brief, CoSAction, CoSObservation, CoSState, ExpertReport
3
+
4
+ __all__ = [
5
+ "Brief",
6
+ "CEOBriefEnvironment",
7
+ "CoSAction",
8
+ "CoSObservation",
9
+ "CoSState",
10
+ "ExpertReport",
11
+ "oracle_action_for_observation",
12
+ ]
ceo_brief_env/checkpoint_load.py ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Load trusted local PyTorch state-dict checkpoints (CoS policy weights)."""
2
+ from __future__ import annotations
3
+
4
+ from pathlib import Path
5
+ from typing import Any
6
+
7
+
8
+ def load_state_dict(ckpt_path: Path, map_location: str | Any = "cpu") -> Any:
9
+ import torch
10
+
11
+ p = Path(ckpt_path)
12
+ try:
13
+ return torch.load(p, map_location=map_location, weights_only=True)
14
+ except TypeError:
15
+ return torch.load(p, map_location=map_location)
ceo_brief_env/environment.py ADDED
@@ -0,0 +1,284 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from pathlib import Path
5
+ from typing import Any, Dict
6
+ from uuid import uuid4
7
+
8
+ import pandas as pd
9
+
10
+ from .experts import DataAnalystExpert, FinanceExpert, HRExpert, StrategyExpert
11
+ from .graders import grade_episode, load_metric_ground_truth
12
+ from .models import Brief, CoSAction, CoSObservation, CoSState, ExpertReport, RewardBreakdown
13
+
14
+ TASK_ROOT = Path(__file__).resolve().parent / 'tasks'
15
+
16
+ # Per-task order for “single” baselines, oracle, and any policy that should cover required experts.
17
+ REQUIRED_EXPERTS_BY_TASK: dict[str, list[str]] = {
18
+ 'easy_brief': ['analyst', 'finance', 'hr'],
19
+ 'medium_brief': ['analyst', 'finance', 'strategy', 'hr'],
20
+ 'hard_brief': ['analyst', 'finance', 'strategy', 'hr'],
21
+ 'expert_brief': ['analyst', 'finance', 'strategy', 'hr'],
22
+ 'risk_brief': ['analyst', 'finance', 'strategy', 'hr'],
23
+ 'crisis_brief': ['analyst', 'finance', 'strategy', 'hr'],
24
+ }
25
+
26
+
27
+ def required_experts_for_task(task_name: str) -> list[str]:
28
+ return list(REQUIRED_EXPERTS_BY_TASK.get(task_name, ['analyst', 'finance', 'hr']))
29
+
30
+
31
+ class CEOBriefEnvironment:
32
+ def __init__(self, shaping: str = "default", auto_fill_required: bool = True) -> None:
33
+ """Multi-agent CEO-brief env.
34
+
35
+ ``shaping`` controls the dense per-step reward. The terminal grader is
36
+ unchanged either way; that is what hackathon scoring uses.
37
+
38
+ - ``"default"``: legacy per-step rewards. Stable; matches existing
39
+ trained checkpoints and submitted runs.
40
+ - ``"strict"``: anti-degenerate shaping for RL training. Adds a
41
+ repetition penalty, an over-consult penalty, an early-finish bonus
42
+ when all required experts are covered, and a stronger penalty for
43
+ summarizing before required experts have reported. Use for new
44
+ GRPO/REINFORCE runs to discourage "summarize-spam -> submit" lazy
45
+ policies.
46
+
47
+ ``auto_fill_required`` keeps the production/demo environment robust by
48
+ filling any missing required experts before composing or grading. Turn
49
+ it off only for policy-evidence runs where we want to observe what the
50
+ LLM actually routed by itself.
51
+ """
52
+ self.analyst = DataAnalystExpert()
53
+ self.finance = FinanceExpert()
54
+ self.hr = HRExpert()
55
+ self.strategy = StrategyExpert()
56
+ self.use_rag = False
57
+ self.shaping = shaping if shaping in {"default", "strict"} else "default"
58
+ self.auto_fill_required = auto_fill_required
59
+ self.reset()
60
+
61
+ def reset(self, task: str = 'easy_brief', episode_id: str | None = None, use_rag: bool = False) -> CoSObservation:
62
+ self.use_rag = use_rag
63
+ self.episode_id = episode_id or str(uuid4())
64
+ self.task_name = task if (TASK_ROOT / task).exists() else 'easy_brief'
65
+ task_dir = TASK_ROOT / self.task_name
66
+ self.raw_df = pd.read_csv(task_dir / 'raw.csv')
67
+ self.gt_metrics = load_metric_ground_truth(str(task_dir / 'ground_truth.csv')) if (task_dir / 'ground_truth.csv').exists() else {}
68
+ with open(task_dir / 'metadata.json', encoding='utf-8') as f:
69
+ self.meta = json.load(f)
70
+ self.step_count = 0
71
+ self.done = False
72
+ self.cumulative_reward = 0.0
73
+ self.expert_reports: Dict[str, ExpertReport] = {}
74
+ self.current_brief: Brief | None = None
75
+ self.history: list[str] = []
76
+ self.last_reward = 0.0
77
+ self.last_terminal = None
78
+ self.last_data_quality = 0.0
79
+ self.last_issues = ['No experts consulted yet.']
80
+ self._consult_counts: Dict[str, int] = {}
81
+ self._last_action_key: str | None = None
82
+ return self._observe(initial=True)
83
+
84
+ def state(self) -> CoSState:
85
+ return CoSState(
86
+ episode_id=self.episode_id,
87
+ task_name=self.task_name,
88
+ step_count=self.step_count,
89
+ done=self.done,
90
+ rag_enabled=self.use_rag,
91
+ consulted_experts=list(self.expert_reports.keys()),
92
+ expert_reports=self.expert_reports,
93
+ current_brief=self.current_brief,
94
+ cumulative_reward=self.cumulative_reward,
95
+ )
96
+
97
+ def _observe(self, initial: bool = False) -> CoSObservation:
98
+ return CoSObservation(
99
+ done=self.done,
100
+ reward=0.0 if initial else self.last_reward,
101
+ instruction=self.meta['instruction'],
102
+ history=list(self.history),
103
+ issues=list(self.last_issues),
104
+ data_quality_score=self.last_data_quality,
105
+ task_name=self.task_name,
106
+ task_difficulty=self.meta['difficulty'],
107
+ max_steps=int(self.meta.get('max_steps', 12)),
108
+ step_count=self.step_count,
109
+ rag_enabled=self.use_rag,
110
+ consulted_experts=list(self.expert_reports.keys()),
111
+ expert_reports=self.expert_reports,
112
+ current_brief=self.current_brief,
113
+ reward_breakdown=RewardBreakdown(
114
+ immediate=self.last_reward,
115
+ cumulative=self.cumulative_reward,
116
+ terminal_grader=self.last_terminal,
117
+ ),
118
+ terminal_grader_score=self.last_terminal,
119
+ )
120
+
121
+ def _compose_brief(self) -> Brief:
122
+ metrics: Dict[str, Any] = {}
123
+ recommendations: list[str] = []
124
+ summary_parts: list[str] = []
125
+ for expert_id in ('analyst', 'finance'):
126
+ report = self.expert_reports.get(expert_id)
127
+ if report:
128
+ metrics.update(report.metrics)
129
+ summary_parts.append(report.summary)
130
+ if 'strategy' in self.expert_reports:
131
+ recommendations = list(self.expert_reports['strategy'].bullet_points)
132
+ summary_parts.append(self.expert_reports['strategy'].summary)
133
+ hr_memo = self.expert_reports['hr'].memo if 'hr' in self.expert_reports and self.expert_reports['hr'].memo else ''
134
+ summary = ' '.join(summary_parts) if summary_parts else 'No brief drafted yet.'
135
+ self.current_brief = Brief(
136
+ summary=summary,
137
+ metrics=metrics,
138
+ recommendations=recommendations,
139
+ hr_memo=hr_memo,
140
+ consulted_experts=list(self.expert_reports.keys()),
141
+ )
142
+ return self.current_brief
143
+
144
+ def _run_expert(self, expert_id: str, focused: bool = False) -> ExpertReport:
145
+ question = self.meta['instruction']
146
+ if expert_id == 'analyst':
147
+ report = self.analyst.run(
148
+ self.task_name, question, self.raw_df, focused=focused, use_rag=self.use_rag
149
+ )
150
+ self.last_data_quality = float(report.metrics.get('data_quality_score', 0.0))
151
+ self.last_issues = report.issues or ['analyst:no material issues']
152
+ return report
153
+ if expert_id == 'finance':
154
+ analyst = self.expert_reports.get('analyst') or self._run_expert('analyst')
155
+ return self.finance.run(
156
+ self.task_name,
157
+ question,
158
+ self.raw_df,
159
+ analyst.metrics,
160
+ self.meta,
161
+ focused=focused,
162
+ use_rag=self.use_rag,
163
+ )
164
+ if expert_id == 'strategy':
165
+ analyst = self.expert_reports.get('analyst') or self._run_expert('analyst')
166
+ finance = self.expert_reports.get('finance') or self._run_expert('finance')
167
+ return self.strategy.run(
168
+ self.task_name, self.meta, analyst, finance, focused=focused, use_rag=self.use_rag
169
+ )
170
+ if expert_id == 'hr':
171
+ analyst = self.expert_reports.get('analyst') or self._run_expert('analyst')
172
+ finance = self.expert_reports.get('finance') or self._run_expert('finance')
173
+ strategy = self.expert_reports.get('strategy')
174
+ return self.hr.run(
175
+ self.task_name, self.meta, analyst, finance, strategy, focused=focused, use_rag=self.use_rag
176
+ )
177
+ raise ValueError(f'Unknown expert {expert_id!r}')
178
+
179
+ def _ensure_required_experts(self) -> list[str]:
180
+ """Run any task-required experts that the policy never consulted.
181
+
182
+ This guarantees the strategist (and any other required role) always
183
+ contributes to the brief, so the UI / grader always has their report.
184
+ Returns the list of expert ids that were auto-filled.
185
+ """
186
+ if not self.auto_fill_required:
187
+ return []
188
+ auto: list[str] = []
189
+ for expert_id in required_experts_for_task(self.task_name):
190
+ if expert_id in self.expert_reports:
191
+ continue
192
+ try:
193
+ self.expert_reports[expert_id] = self._run_expert(expert_id)
194
+ auto.append(expert_id)
195
+ except Exception:
196
+ continue
197
+ return auto
198
+
199
+ def step(self, action: CoSAction) -> CoSObservation:
200
+ if self.done:
201
+ return self._observe()
202
+ self.step_count += 1
203
+ immediate = -0.02
204
+ details = action.model_dump(exclude_none=True)
205
+ action_key = json.dumps(details, sort_keys=True)
206
+ self.history.append(action_key)
207
+ strict = self.shaping == 'strict'
208
+ if strict and self._last_action_key is not None and action_key == self._last_action_key:
209
+ immediate -= 0.05
210
+ self._last_action_key = action_key
211
+ required = list(self.meta.get('required_experts', []))
212
+ if action.action_type in {'consult', 'ask'}:
213
+ if not action.expert_id:
214
+ immediate -= 0.03
215
+ self.last_issues = ['action_missing_expert']
216
+ else:
217
+ prior = action.expert_id in self.expert_reports
218
+ report = self._run_expert(action.expert_id, focused=action.action_type == 'ask')
219
+ self.expert_reports[action.expert_id] = report
220
+ immediate += 0.10 if not prior and action.expert_id in required else 0.02
221
+ if prior:
222
+ immediate -= 0.05
223
+ if strict:
224
+ self._consult_counts[action.expert_id] = self._consult_counts.get(action.expert_id, 0) + 1
225
+ if self._consult_counts[action.expert_id] > 2:
226
+ immediate -= 0.10
227
+ self.last_issues = report.issues or [f'{action.expert_id}:ok']
228
+ elif action.action_type == 'summarize':
229
+ brief_already_exists = self.current_brief is not None
230
+ missing_required = [e for e in required if e not in self.expert_reports]
231
+ self._ensure_required_experts()
232
+ self._compose_brief()
233
+ immediate += 0.04 if len(self.expert_reports) >= 2 else -0.02
234
+ if strict and missing_required:
235
+ immediate -= 0.05 * len(missing_required)
236
+ if strict and brief_already_exists:
237
+ immediate -= 0.08
238
+ self.last_issues = ['brief_composed']
239
+ elif action.action_type == 'submit':
240
+ auto_filled = self._ensure_required_experts()
241
+ if self.current_brief is None or auto_filled:
242
+ self._compose_brief()
243
+ self.done = True
244
+ self.last_terminal = grade_episode(
245
+ self.gt_metrics, self.meta, self.current_brief, self.expert_reports, use_rag=self.use_rag
246
+ )
247
+ immediate += self.last_terminal
248
+ if strict and not auto_filled:
249
+ max_steps = int(self.meta.get('max_steps', 12))
250
+ steps_saved = max(0, max_steps - self.step_count)
251
+ if steps_saved > 0 and all(e in self.expert_reports for e in required):
252
+ immediate += min(0.10, 0.01 * steps_saved)
253
+ self.last_issues = ['submitted'] + (
254
+ [f'auto_consulted:{",".join(auto_filled)}'] if auto_filled else []
255
+ )
256
+ else:
257
+ self.last_issues = ['noop']
258
+ immediate -= 0.01
259
+
260
+ if not self.done and self.step_count >= int(self.meta.get('max_steps', 12)):
261
+ auto_filled = self._ensure_required_experts()
262
+ if self.current_brief is None or auto_filled:
263
+ self._compose_brief()
264
+ self.done = True
265
+ self.last_terminal = grade_episode(
266
+ self.gt_metrics, self.meta, self.current_brief, self.expert_reports, use_rag=self.use_rag
267
+ )
268
+ immediate += self.last_terminal
269
+ self.last_issues = ['forced_termination:max_steps'] + (
270
+ [f'auto_consulted:{",".join(auto_filled)}'] if auto_filled else []
271
+ )
272
+
273
+ self.last_reward = round(immediate, 4)
274
+ self.cumulative_reward = round(self.cumulative_reward + self.last_reward, 4)
275
+ return self._observe()
276
+
277
+
278
+ def oracle_action_for_observation(obs: CoSObservation) -> CoSAction:
279
+ for expert in required_experts_for_task(obs.task_name):
280
+ if expert not in obs.consulted_experts:
281
+ return CoSAction(action_type='consult', expert_id=expert)
282
+ if obs.current_brief is None:
283
+ return CoSAction(action_type='summarize')
284
+ return CoSAction(action_type='submit')
ceo_brief_env/experts/__init__.py ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ from .data_analyst import DataAnalystExpert
2
+ from .finance import FinanceExpert
3
+ from .hr import HRExpert
4
+ from .strategy import StrategyExpert
5
+
6
+ __all__ = ["DataAnalystExpert", "FinanceExpert", "HRExpert", "StrategyExpert"]
ceo_brief_env/experts/data_analyst.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import pandas as pd
4
+
5
+ from subenvs.autodatalab.analytics import (
6
+ clean_orders,
7
+ compute_kpis,
8
+ compute_revenue_share,
9
+ data_quality_score,
10
+ derive_revenue,
11
+ validate_schema,
12
+ )
13
+
14
+ from ..models import ExpertReport
15
+
16
+ _ANALYST_QUERY = (
17
+ "data quality cleaning duplicates imputation category median "
18
+ "KPIs total revenue top category data_quality_score"
19
+ )
20
+
21
+
22
+ class DataAnalystExpert:
23
+ expert_id = "analyst"
24
+
25
+ def run(
26
+ self,
27
+ task_name: str,
28
+ question: str,
29
+ raw_df: pd.DataFrame,
30
+ focused: bool = False,
31
+ use_rag: bool = False,
32
+ ) -> ExpertReport:
33
+ cleaned = clean_orders(raw_df)
34
+ enriched = derive_revenue(cleaned.df)
35
+ kpis = compute_kpis(cleaned.df)
36
+ share = compute_revenue_share(cleaned.df)
37
+ schema = validate_schema(enriched)
38
+ top_row = share.iloc[0]
39
+ summary = (
40
+ f"Cleaned {len(raw_df)} raw rows into {len(cleaned.df)} trusted rows. "
41
+ f"Top category is {top_row['Category']} and total revenue is {kpis['total_revenue']:.2f}."
42
+ )
43
+ bullets = [
44
+ f"Removed {cleaned.duplicates_removed} duplicate rows and imputed {cleaned.imputed_prices} missing prices.",
45
+ f"Data quality score is {data_quality_score(cleaned.df):.2f} with {schema['invalid_date_rows']} invalid date rows.",
46
+ f"{top_row['Category']} leads revenue at {float(top_row['Revenue']):.2f}.",
47
+ ]
48
+ metrics = {
49
+ "duplicates_removed": cleaned.duplicates_removed,
50
+ "imputed_prices": cleaned.imputed_prices,
51
+ "data_quality_score": data_quality_score(cleaned.df),
52
+ "total_revenue": kpis["total_revenue"],
53
+ "avg_order_value": kpis["avg_order_value"],
54
+ "top_category": str(top_row["Category"]),
55
+ "top_category_revenue": round(float(top_row["Revenue"]), 2),
56
+ }
57
+ issues = [f"risk:{name}" for name in schema["risk_flags"]]
58
+ citations = share["Category"].astype(str).head(3).tolist()
59
+
60
+ memory_citations: list[str] = []
61
+ memory_snippets: list[str] = []
62
+ if use_rag:
63
+ from memory import get_retriever
64
+
65
+ hits = get_retriever().query(_ANALYST_QUERY, k=2)
66
+ memory_citations = [h.as_citation() for h in hits]
67
+ memory_snippets = [h.snippet for h in hits]
68
+ if hits:
69
+ summary = summary + f" Grounded in SOP {hits[0].source.split('#')[0]}."
70
+ bullets.append(
71
+ f"Grounded against SOP: {hits[0].source.split('#')[0]} (score {hits[0].score:.2f})."
72
+ )
73
+
74
+ return ExpertReport(
75
+ expert_id="analyst",
76
+ title="Data Analyst Report",
77
+ summary=summary,
78
+ metrics=metrics,
79
+ bullet_points=bullets,
80
+ issues=issues,
81
+ citations=citations,
82
+ memory_citations=memory_citations,
83
+ memory_snippets=memory_snippets,
84
+ )
ceo_brief_env/experts/finance.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import pandas as pd
4
+
5
+ from subenvs.autodatalab.analytics import clean_orders, monthly_revenue
6
+
7
+ from ..models import ExpertReport
8
+ from .finance_tools import break_even, compute_variance, project_next_quarter
9
+
10
+ _FINANCE_QUERY = (
11
+ "finance forecasting next quarter projection confidence band "
12
+ "variance plan_value favorable unfavorable break-even unit_margin fixed_cost"
13
+ )
14
+
15
+
16
+ class FinanceExpert:
17
+ expert_id = "finance"
18
+
19
+ def run(
20
+ self,
21
+ task_name: str,
22
+ question: str,
23
+ raw_df: pd.DataFrame,
24
+ analyst_metrics: dict,
25
+ task_meta: dict,
26
+ focused: bool = False,
27
+ use_rag: bool = False,
28
+ ) -> ExpertReport:
29
+ cleaned = clean_orders(raw_df).df
30
+ monthly = monthly_revenue(cleaned)
31
+ projection = project_next_quarter(monthly)
32
+ variance = compute_variance(float(analyst_metrics.get("total_revenue", 0.0)), float(task_meta.get("plan_value", 1.0)))
33
+ be = break_even(float(task_meta.get("fixed_cost", 10000.0)), float(task_meta.get("unit_margin", 500.0)))
34
+ metrics = {
35
+ **projection,
36
+ **variance,
37
+ **be,
38
+ }
39
+ bullets = [
40
+ f"Next-quarter revenue projection is {metrics['projection_next_quarter']:.2f} with +/- {metrics['confidence_band']:.2f} band.",
41
+ f"Variance versus plan is {metrics['variance_abs']:.2f} ({metrics['variance_pct']:.2f}%).",
42
+ f"Break-even sits at {metrics['break_even_units']:.2f} units.",
43
+ ]
44
+ memory_citations: list[str] = []
45
+ memory_snippets: list[str] = []
46
+ summary = (
47
+ f"Finance projects next quarter at {metrics['projection_next_quarter']:.2f} and "
48
+ f"marks performance as {metrics['variance_flag']} plan."
49
+ )
50
+ if use_rag:
51
+ from memory import get_retriever
52
+
53
+ hits = get_retriever().query(_FINANCE_QUERY, k=2)
54
+ memory_citations = [h.as_citation() for h in hits]
55
+ memory_snippets = [h.snippet for h in hits]
56
+ if hits:
57
+ summary = summary + f" Following SOP {hits[0].source.split('#')[0]}."
58
+ bullets.append(
59
+ f"SOP alignment: {hits[0].source.split('#')[0]} (score {hits[0].score:.2f})."
60
+ )
61
+
62
+ return ExpertReport(
63
+ expert_id="finance",
64
+ title="Finance Forecast",
65
+ summary=summary,
66
+ metrics=metrics,
67
+ bullet_points=bullets,
68
+ citations=list(monthly['Month'].astype(str).tail(3)),
69
+ memory_citations=memory_citations,
70
+ memory_snippets=memory_snippets,
71
+ )
ceo_brief_env/experts/finance_tools.py ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import numpy as np
4
+ import pandas as pd
5
+
6
+
7
+ def project_next_quarter(revenue_by_month: pd.DataFrame) -> dict[str, float]:
8
+ if revenue_by_month.empty:
9
+ return {"projection_next_quarter": 0.0, "confidence_band": 0.0}
10
+ y = revenue_by_month["Revenue"].astype(float).to_numpy()
11
+ x = np.arange(1, len(y) + 1, dtype=float)
12
+ if len(y) == 1:
13
+ next_values = np.array([y[-1], y[-1], y[-1]])
14
+ residual = 0.0
15
+ else:
16
+ slope, intercept = np.polyfit(x, y, 1)
17
+ future_x = np.arange(len(y) + 1, len(y) + 4, dtype=float)
18
+ next_values = slope * future_x + intercept
19
+ predicted = slope * x + intercept
20
+ residual = float(np.std(y - predicted))
21
+ return {
22
+ "projection_next_quarter": round(float(next_values.sum()), 2),
23
+ "confidence_band": round(residual * 3, 2),
24
+ }
25
+
26
+
27
+ def compute_variance(actual: float, plan: float) -> dict[str, float | str]:
28
+ variance_abs = round(float(actual) - float(plan), 2)
29
+ variance_pct = round((variance_abs / float(plan)) * 100, 2) if plan else 0.0
30
+ flag = "ahead" if variance_abs >= 0 else "behind"
31
+ return {
32
+ "variance_abs": variance_abs,
33
+ "variance_pct": variance_pct,
34
+ "variance_flag": flag,
35
+ }
36
+
37
+
38
+ def break_even(fixed_cost: float, unit_margin: float) -> dict[str, float]:
39
+ if unit_margin <= 0:
40
+ return {"break_even_units": 0.0, "break_even_revenue": 0.0}
41
+ units = float(fixed_cost) / float(unit_margin)
42
+ return {
43
+ "break_even_units": round(units, 2),
44
+ "break_even_revenue": round(units * float(unit_margin), 2),
45
+ }
ceo_brief_env/experts/hr.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ from ..models import ExpertReport
4
+ from subenvs.email.hr_tools import build_hr_memo, score_memo
5
+ from subenvs.email.graders import grade_response
6
+
7
+ # Maps CoS brief tasks to the Round 1 email-env task IDs so the right
8
+ # task-specific rubric fires inside grade_response.
9
+ _BRIEF_TO_EMAIL_TASK = {
10
+ "easy_brief": "task_1",
11
+ "medium_brief": "task_2",
12
+ "hard_brief": "task_3",
13
+ "expert_brief": "task_3",
14
+ }
15
+
16
+ _HR_QUERY = (
17
+ "memo style guide audience tone bullet highlights "
18
+ "call to action professional direct exemplar"
19
+ )
20
+
21
+
22
+ def _clamp(score: float) -> float:
23
+ """Match ceo_brief_env.graders._clamp so every emitted score is in (0.001, 0.999)."""
24
+ return max(0.001, min(0.999, round(float(score), 4)))
25
+
26
+
27
+ class HRExpert:
28
+ expert_id = "hr"
29
+
30
+ def run(
31
+ self,
32
+ task_name: str,
33
+ task_meta: dict,
34
+ analyst_report: ExpertReport | None,
35
+ finance_report: ExpertReport | None,
36
+ strategy_report: ExpertReport | None = None,
37
+ focused: bool = False,
38
+ use_rag: bool = False,
39
+ ) -> ExpertReport:
40
+ # --- 1. Build the memo from upstream reports -----------------------
41
+ highlights: list[str] = []
42
+ if analyst_report:
43
+ highlights.extend(analyst_report.bullet_points[:2])
44
+ if finance_report:
45
+ highlights.extend(finance_report.bullet_points[:2])
46
+ if strategy_report:
47
+ highlights.extend(strategy_report.bullet_points[:2])
48
+
49
+ memory_citations: list[str] = []
50
+ memory_snippets: list[str] = []
51
+ if use_rag:
52
+ from memory import get_retriever
53
+
54
+ hits = get_retriever().query(_HR_QUERY, k=2)
55
+ memory_citations = [h.as_citation() for h in hits]
56
+ memory_snippets = [h.snippet for h in hits]
57
+ if hits:
58
+ highlights.insert(
59
+ 0,
60
+ f"Memo follows {hits[0].source.split('#')[0]} (style SOP retrieved from company memory).",
61
+ )
62
+
63
+ audience = str(task_meta.get("memo_audience", "team"))
64
+ title = str(task_meta.get("title", task_name))
65
+ memo = build_hr_memo(audience, title, highlights)
66
+
67
+ # --- 2. Three-part scoring ----------------------------------------
68
+ structure_score = score_memo(memo, task_meta.get("hr_required_terms", []))
69
+
70
+ email_task_id = _BRIEF_TO_EMAIL_TASK.get(task_name, "task_1")
71
+ tone_score = grade_response(
72
+ email=task_meta.get("instruction", ""),
73
+ response=memo,
74
+ task_id=email_task_id,
75
+ )
76
+
77
+ audience_hit = 1.0 if audience.lower() in memo.lower() else 0.0
78
+
79
+ blended = 0.45 * structure_score + 0.45 * tone_score + 0.10 * audience_hit
80
+ score = _clamp(blended)
81
+
82
+ # --- 3. Return a typed ExpertReport -------------------------------
83
+ issues: list[str] = []
84
+ if structure_score < 0.4:
85
+ issues.append("hr:weak_structure_or_missing_required_terms")
86
+ if tone_score < 0.4:
87
+ issues.append("hr:weak_professional_tone")
88
+ if audience_hit == 0.0:
89
+ issues.append(f"hr:audience_not_referenced:{audience}")
90
+
91
+ return ExpertReport(
92
+ expert_id="hr",
93
+ title="HR / Communications Memo",
94
+ summary=(
95
+ "Drafted the internal memo and scored it on structure, "
96
+ "professional tone, and audience relevance."
97
+ ),
98
+ metrics={
99
+ "memo_structure_score": _clamp(structure_score),
100
+ "memo_tone_score": _clamp(tone_score),
101
+ "audience_reference": audience_hit,
102
+ "memo_score": score,
103
+ },
104
+ bullet_points=[
105
+ f"Memo addressed to {audience}.",
106
+ f"Structure score {structure_score:.3f}, tone score {tone_score:.3f}.",
107
+ "Blended score uses 45% structure, 45% tone, 10% audience bonus.",
108
+ ],
109
+ issues=issues,
110
+ memo=memo,
111
+ score=score,
112
+ memory_citations=memory_citations,
113
+ memory_snippets=memory_snippets,
114
+ )
ceo_brief_env/experts/strategy.py ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ from ..models import ExpertReport
4
+
5
+ _STRATEGY_QUERY = (
6
+ "strategy playbook portfolio buy sell hold trim NVDA AAPL JPM "
7
+ "projection variance break-even margin diversification"
8
+ )
9
+
10
+ # External watchlist for “portfolio” recommendations (narrative layer on top of internal P&L).
11
+ WATCHLIST: tuple[tuple[str, str], ...] = (
12
+ ("NVDA", "NVIDIA"),
13
+ ("AAPL", "Apple"),
14
+ ("JPM", "JPMorgan Chase"),
15
+ )
16
+
17
+
18
+ def _stance(
19
+ key: str,
20
+ variance_flag: str,
21
+ projection: float,
22
+ plan_value: float,
23
+ top_category_lower: str,
24
+ ) -> str:
25
+ """
26
+ Return one of: buy more, add, hold, reduce (sell/trim) — deterministic, CoS-graded via brief text.
27
+ Tech names tilt on Electronics-heavy internal mix; JPM is treated as a defensive/financial anchor.
28
+ """
29
+ stress = variance_flag == "behind" or (plan_value > 0 and projection < 0.95 * plan_value)
30
+ electronic_tilt = "electronic" in top_category_lower or "phone" in top_category_lower or "tablet" in top_category_lower
31
+
32
+ if key == "NVDA":
33
+ if stress:
34
+ return "reduce (trim high-beta tech beta — lock in Q4 if variance stays behind plan)"
35
+ if electronic_tilt:
36
+ return "buy more (reinforce tech / AI exposure; aligns with strong Electronics sell-through vs plan)"
37
+ return "add (modest size-up while projection holds vs plan_value)"
38
+
39
+ if key == "AAPL":
40
+ if stress:
41
+ return "hold (keep core quality; avoid size-up while variance is behind plan)"
42
+ if electronic_tilt:
43
+ return "add (broaden megacap tech anchor alongside internal Electronics strength)"
44
+ return "buy more (diversifier vs pure growth; use break-even and cash discipline)"
45
+
46
+ if key == "JPM":
47
+ if stress:
48
+ return "add (increase defensives / quality financials; reduce portfolio beta vs NVDA + AAPL)"
49
+ return "hold (bank anchor; rotate only on clearer variance reversion to plan)"
50
+ return "hold"
51
+
52
+
53
+ def _static_horizons(
54
+ key: str,
55
+ variance_flag: str,
56
+ projection: float,
57
+ plan_value: float,
58
+ top_category_lower: str,
59
+ ) -> tuple[str, str, str, str]:
60
+ """
61
+ Fixed policy text: *present* = what the desk would do in the **current** reporting window;
62
+ *future* = staged intent for the **next 1-2 quarters** (not a forecast of prices).
63
+ Also returns present/future one-word stance tokens for metrics (buy|sell|hold|trim|none).
64
+ """
65
+ stress = variance_flag == "behind" or (plan_value > 0 and projection < 0.95 * plan_value)
66
+ electronic = (
67
+ "electronic" in top_category_lower
68
+ or "phone" in top_category_lower
69
+ or "tablet" in top_category_lower
70
+ )
71
+ if key == "NVDA":
72
+ if stress:
73
+ return (
74
+ "Present: **trim / do not add** (reduce high-beta now while internal variance is behind plan).",
75
+ "Future: re-open **buy** scales only if next-quarter **projection** clears plan and **variance** flips ahead.",
76
+ "trim",
77
+ "buy",
78
+ )
79
+ if electronic:
80
+ return (
81
+ "Present: **hold** to **buy small** only within risk limits; no forced trade today.",
82
+ "Future: **add / buy** on a staged plan over the next 1-2 quarters while Electronics strength persists.",
83
+ "hold",
84
+ "buy",
85
+ )
86
+ return (
87
+ "Present: **hold**; wait for a cleaner internal read vs plan.",
88
+ "Future: **add** modestly next quarter if the **projection** path holds.",
89
+ "hold",
90
+ "add",
91
+ )
92
+ if key == "AAPL":
93
+ if stress:
94
+ return (
95
+ "Present: **hold**; **no new buy** until variance to plan improves.",
96
+ "Future: **buy** or **add** in the *next* quarter if forecast confidence widens and execution stabilizes.",
97
+ "hold",
98
+ "buy",
99
+ )
100
+ if electronic:
101
+ return (
102
+ "Present: **hold** to **add** a sliver of core quality if account policy allows (optional today).",
103
+ "Future: **buy / add** as a megacap anchor over the next two quarters (static ladder, not market timing).",
104
+ "hold",
105
+ "add",
106
+ )
107
+ return (
108
+ "Present: **hold**; keep dry powder for updates vs plan_value.",
109
+ "Future: **buy** more defensively in the *next* quarter (quality tilt).",
110
+ "hold",
111
+ "buy",
112
+ )
113
+ if key == "JPM":
114
+ if stress:
115
+ return (
116
+ "Present: **buy / add** defensives to lower portfolio beta (execute now, static sleeve shift).",
117
+ "Future: **hold** the defensive sleeve; re-check after **break-even** and plan variance improve.",
118
+ "buy",
119
+ "hold",
120
+ )
121
+ return (
122
+ "Present: **hold** the bank anchor; no need to day-trade the sleeve.",
123
+ "Future: only **sell** down if the operating plan is consistently ahead and you rotate into growth; else **hold**.",
124
+ "hold",
125
+ "sell" if (not stress and plan_value and projection > plan_value * 1.02) else "hold",
126
+ )
127
+ return (
128
+ "Present: **hold**.",
129
+ "Future: **hold**; revisit vs plan next cycle.",
130
+ "hold",
131
+ "hold",
132
+ )
133
+
134
+
135
+ def _one_line(
136
+ sym: str,
137
+ display: str,
138
+ stance: str,
139
+ num_token: str,
140
+ cat_phrase: str,
141
+ present: str,
142
+ future: str,
143
+ ) -> str:
144
+ # Keep one finance keyword for rubric: projection / variance / break-even
145
+ return (
146
+ f"{sym} ({display}): {stance} — tie to internal numbers including {num_token} {cat_phrase} "
147
+ f"and the latest projection/variance read vs plan. {present} {future}"
148
+ )
149
+
150
+
151
+ class StrategyExpert:
152
+ expert_id = "strategy"
153
+
154
+ def run(
155
+ self,
156
+ task_name: str,
157
+ task_meta: dict,
158
+ analyst_report: ExpertReport,
159
+ finance_report: ExpertReport,
160
+ focused: bool = False,
161
+ use_rag: bool = False,
162
+ ) -> ExpertReport:
163
+ top_category = str(analyst_report.metrics.get("top_category", "the best category"))
164
+ top_cat_lower = top_category.lower()
165
+ fin = finance_report.metrics
166
+ projection = float(fin.get("projection_next_quarter", 0.0) or 0.0)
167
+ var_pct = float(fin.get("variance_pct", 0.0) or 0.0)
168
+ be_units = fin.get("break_even_units", 0.0)
169
+ vflag = str(fin.get("variance_flag", "behind"))
170
+ plan_value = float(task_meta.get("plan_value", 0.0) or 0.0)
171
+
172
+ # These keys exist on analyst+finance and flow into `brief.metrics` (used by strategy grader for evidence #).
173
+ tr = analyst_report.metrics.get("total_revenue", 0.0)
174
+ tr_s = str(tr)
175
+ proj_s = str(fin.get("projection_next_quarter", projection))
176
+ vps = str(fin.get("variance_pct", var_pct))
177
+ be_s = str(be_units)
178
+
179
+ cats = [str(c) for c in (analyst_report.citations or []) if c]
180
+ if top_category and top_category not in cats:
181
+ cats.insert(0, top_category)
182
+ cat_a = cats[0] if cats else top_category
183
+ cat_b = cats[1] if len(cats) > 1 else (cats[0] if cats else "operations")
184
+
185
+ st_nvda = _stance("NVDA", vflag, projection, plan_value, top_cat_lower)
186
+ st_aapl = _stance("AAPL", vflag, projection, plan_value, top_cat_lower)
187
+ st_jpm = _stance("JPM", vflag, projection, plan_value, top_cat_lower)
188
+ pnv, fnv, nv_pr, nv_fu = _static_horizons("NVDA", vflag, projection, plan_value, top_cat_lower)
189
+ paa, faa, aa_pr, aa_fu = _static_horizons("AAPL", vflag, projection, plan_value, top_cat_lower)
190
+ pjp, fjp, jp_pr, jp_fu = _static_horizons("JPM", vflag, projection, plan_value, top_cat_lower)
191
+
192
+ # Each line embeds a distinct evidence token that appears in `brief.metrics` after analyst+finance merge.
193
+ line_nvda = _one_line(
194
+ "NVDA", "NVIDIA", st_nvda, tr_s, f"while top internal category {cat_a!r} is in focus", pnv, fnv
195
+ )
196
+ line_aapl = _one_line("AAPL", "Apple", st_aapl, proj_s, f"cross-check against {cat_b!r} demand mix", paa, faa)
197
+ line_jpm = _one_line("JPM", "JPMorgan", st_jpm, vps, f"and break-even path ~{be_s} units in our operating model", pjp, fjp)
198
+
199
+ # Third line: explicit break-even token for grader’s projection|variance|break-even check.
200
+ if "break-even" not in line_jpm.lower() and be_s != "0":
201
+ line_jpm = line_jpm + f" (break-even reference {be_s})."
202
+
203
+ bullets = [line_nvda, line_aapl, line_jpm]
204
+
205
+ memory_citations: list[str] = []
206
+ memory_snippets: list[str] = []
207
+ summary = (
208
+ f"Portfolio call on {', '.join(s[0] for s in WATCHLIST)}: map internal "
209
+ f"{top_category!r} to actions vs plan, with static **Present** (this cycle) "
210
+ f"and **Future** (next 1-2Q) buy/sell/hold/trim guidance per line."
211
+ )
212
+ if use_rag:
213
+ from memory import get_retriever
214
+
215
+ hits = get_retriever().query(_STRATEGY_QUERY, k=2)
216
+ memory_citations = [h.as_citation() for h in hits]
217
+ memory_snippets = [h.snippet for h in hits]
218
+ if hits:
219
+ summary = summary + f" Structure follows {hits[0].source.split('#')[0]}."
220
+
221
+ # Advanced RAG: lightweight Stooq daily CSV "scrape" (HTTP + fixture fallback).
222
+ from ..stooq_scrape import DEFAULT_WATCHLIST, scrape_watchlist
223
+
224
+ stq = scrape_watchlist(DEFAULT_WATCHLIST)
225
+ for _sym, cite, snip in stq:
226
+ memory_citations.append(cite)
227
+ memory_snippets.append(snip)
228
+ ext = " | ".join(s for _, __, s in stq)
229
+ summary = summary + f" External tape (Stooq, scraped in RAG mode): {ext}"
230
+ else:
231
+ # Non-RAG: no HTTP scrape — still attach multi-hundred-row local “tape” CSVs for grounding text.
232
+ from ..stooq_scrape import DEFAULT_WATCHLIST, scrape_watchlist_from_long_csv
233
+
234
+ stq = scrape_watchlist_from_long_csv(DEFAULT_WATCHLIST, last_n=5)
235
+ n0 = stq[0][3] if stq else 0
236
+ for _sym, cite, snip, _n in stq:
237
+ memory_citations.append(cite)
238
+ memory_snippets.append(snip)
239
+ ext = " | ".join(s[2] for s in stq)
240
+ summary = (
241
+ summary
242
+ + f" External tape (bundled long CSV, ~{n0} trading days per symbol, no network): {ext}"
243
+ )
244
+
245
+ def _action_token(stance: str) -> str:
246
+ head = stance.split()[0].lower() if stance else "hold"
247
+ if head in ("reduce", "hold", "add"):
248
+ return head
249
+ if head == "buy":
250
+ return "buy_more"
251
+ return head
252
+
253
+ return ExpertReport(
254
+ expert_id="strategy",
255
+ title="Strategy — public equities (watchlist)",
256
+ summary=summary,
257
+ metrics={
258
+ "recommendation_count": len(bullets),
259
+ "nvda": _action_token(st_nvda),
260
+ "aapl": _action_token(st_aapl),
261
+ "jpm": _action_token(st_jpm),
262
+ "nvda_present": nv_pr,
263
+ "nvda_future": nv_fu,
264
+ "aapl_present": aa_pr,
265
+ "aapl_future": aa_fu,
266
+ "jpm_present": jp_pr,
267
+ "jpm_future": jp_fu,
268
+ "watchlist": "NVDA,AAPL,JPM",
269
+ },
270
+ bullet_points=bullets,
271
+ citations=list(analyst_report.citations[:3]) or [top_category, cat_a, cat_b],
272
+ memory_citations=memory_citations,
273
+ memory_snippets=memory_snippets,
274
+ )
ceo_brief_env/fixtures/stooq/aapl_us.csv ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Date,Open,High,Low,Close,Volume
2
+ 2024-10-28,220.0,224.0,218.0,222.1,40000000
3
+ 2024-10-29,222.0,226.0,221.0,224.5,38000000
4
+ 2024-10-30,224.0,228.0,223.0,225.0,36000000
ceo_brief_env/fixtures/stooq/jpm_us.csv ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Date,Open,High,Low,Close,Volume
2
+ 2024-10-28,210.0,213.0,208.0,211.0,8000000
3
+ 2024-10-29,211.0,215.0,210.0,213.4,7500000
4
+ 2024-10-30,213.0,216.0,212.0,214.2,7200000
ceo_brief_env/fixtures/stooq/nvda_us.csv ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ Date,Open,High,Low,Close,Volume
2
+ 2024-10-28,130.0,132.5,128.0,131.2,45000000
3
+ 2024-10-29,131.0,135.0,130.0,133.8,48000000
4
+ 2024-10-30,134.0,136.0,132.0,135.1,42000000
ceo_brief_env/fixtures/stooq_long/aapl_us.csv ADDED
@@ -0,0 +1,281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Date,Open,High,Low,Close,Volume
2
+ 2022-06-01,150.0000,153.0614,149.0632,151.6332,40551601
3
+ 2022-06-02,151.6332,153.4470,150.4806,151.0050,23116470
4
+ 2022-06-03,151.0050,151.4769,148.7328,149.3193,28859720
5
+ 2022-06-06,149.3193,149.9026,145.8916,146.4382,43323520
6
+ 2022-06-07,146.4382,146.5626,143.9913,144.3422,42037244
7
+ 2022-06-08,144.3422,145.6126,142.3213,143.7062,35893004
8
+ 2022-06-09,143.7062,144.9616,139.5929,140.8703,35011039
9
+ 2022-06-10,140.8703,142.7739,139.3237,142.2634,56022729
10
+ 2022-06-13,142.2634,146.3343,141.8659,144.6782,42172092
11
+ 2022-06-14,144.6782,148.0800,144.0006,146.6694,22650088
12
+ 2022-06-15,146.6694,148.0570,145.4279,147.8713,16333835
13
+ 2022-06-16,147.8713,148.7226,147.5242,147.7365,39049284
14
+ 2022-06-17,147.7365,148.6139,146.1476,147.9587,57571368
15
+ 2022-06-20,147.9587,151.6875,147.9127,151.2431,34077358
16
+ 2022-06-21,151.2431,152.5230,147.9049,148.3731,22162397
17
+ 2022-06-22,148.3731,149.0914,145.5985,146.8948,38129914
18
+ 2022-06-23,146.8948,148.0888,145.4880,145.5672,26041890
19
+ 2022-06-24,145.5672,148.5606,145.3902,147.2319,19190460
20
+ 2022-06-27,147.2319,148.6599,147.2034,147.4980,36965252
21
+ 2022-06-28,147.4980,147.6486,145.6590,145.9587,29720348
22
+ 2022-06-29,145.9587,146.1553,144.8364,145.9227,58180230
23
+ 2022-06-30,145.9227,147.6848,144.7871,147.5644,46425650
24
+ 2022-07-01,147.5644,148.2457,142.8168,143.9439,61606791
25
+ 2022-07-04,143.9439,148.4399,142.9268,147.4323,62006500
26
+ 2022-07-05,147.4323,148.3331,145.2850,145.3923,53180621
27
+ 2022-07-06,145.3923,147.1653,145.0485,146.7944,41138742
28
+ 2022-07-07,146.7944,149.2158,146.2247,148.9729,40612341
29
+ 2022-07-08,148.9729,150.5540,146.0292,147.3108,61859297
30
+ 2022-07-11,147.3108,149.8476,146.8062,148.6325,40226129
31
+ 2022-07-12,148.6325,149.4859,148.1869,148.2981,56784517
32
+ 2022-07-13,148.2981,149.1137,144.1771,145.8044,40621804
33
+ 2022-07-14,145.8044,149.3362,144.9875,148.8708,34204067
34
+ 2022-07-15,148.8708,149.5308,146.9185,147.7077,56404746
35
+ 2022-07-18,147.7077,151.7883,146.5243,151.6162,41384367
36
+ 2022-07-19,151.6162,151.6903,150.4895,151.1458,31216002
37
+ 2022-07-20,151.1458,152.2222,149.6456,150.3077,30197143
38
+ 2022-07-21,150.3077,152.0704,148.0356,148.7349,62697979
39
+ 2022-07-22,148.7349,149.9199,145.3486,146.3221,50074664
40
+ 2022-07-25,146.3221,148.1913,145.2905,146.6534,18238939
41
+ 2022-07-26,146.6534,149.3839,146.2217,148.2928,51071273
42
+ 2022-07-27,148.2928,151.6566,148.0287,151.1539,29878387
43
+ 2022-07-28,151.1539,152.9081,151.0229,152.0975,37583425
44
+ 2022-07-29,152.0975,153.7670,151.4517,152.7065,53693519
45
+ 2022-08-01,152.7065,154.8454,152.0717,154.3667,60415621
46
+ 2022-08-02,154.3667,155.1956,151.7603,152.3160,43996373
47
+ 2022-08-03,152.3160,155.1567,151.9681,154.9271,19061040
48
+ 2022-08-04,154.9271,155.8952,151.1959,152.0881,61384083
49
+ 2022-08-05,152.0881,153.0471,151.8897,151.9379,26819323
50
+ 2022-08-08,151.9379,152.3824,149.2065,150.6309,36015787
51
+ 2022-08-09,150.6309,151.5964,147.6761,147.9533,24932317
52
+ 2022-08-10,147.9533,149.1763,146.6099,149.0226,37062747
53
+ 2022-08-11,149.0226,150.2280,144.1232,145.8055,51448952
54
+ 2022-08-12,145.8055,150.3378,145.3305,148.6623,39341972
55
+ 2022-08-15,148.6623,151.5042,146.9376,150.7860,36316767
56
+ 2022-08-16,150.7860,150.9581,146.4359,147.1901,16908063
57
+ 2022-08-17,147.1901,150.0374,145.5422,148.2680,63361666
58
+ 2022-08-18,148.2680,148.5887,146.3941,146.5182,60678872
59
+ 2022-08-19,146.5182,146.6456,141.9117,143.0571,61491371
60
+ 2022-08-22,143.0571,143.6392,142.9967,143.5306,55336787
61
+ 2022-08-23,143.5306,145.7196,141.8356,145.1789,29499185
62
+ 2022-08-24,145.1789,146.8622,142.5965,142.6918,33415837
63
+ 2022-08-25,142.6918,143.7873,139.6609,140.4849,28098960
64
+ 2022-08-26,140.4849,141.8285,138.8273,141.6468,53606023
65
+ 2022-08-29,141.6468,142.6598,139.2177,139.6728,43591329
66
+ 2022-08-30,139.6728,140.0251,137.6988,138.5144,19437891
67
+ 2022-08-31,138.5144,143.6863,138.1364,142.3407,44740851
68
+ 2022-09-01,142.3407,142.6256,139.4717,140.1161,50368913
69
+ 2022-09-02,140.1161,141.6904,136.7132,137.1267,23883653
70
+ 2022-09-05,137.1267,138.7331,136.4428,137.2424,41767984
71
+ 2022-09-06,137.2424,141.8819,136.6708,140.9899,25084158
72
+ 2022-09-07,140.9899,142.4328,139.9880,141.3622,25292440
73
+ 2022-09-08,141.3622,143.0000,136.7804,137.9206,56549399
74
+ 2022-09-09,137.9206,141.3430,137.6117,140.6247,62249603
75
+ 2022-09-12,140.6247,143.9042,139.5618,143.7906,40018841
76
+ 2022-09-13,143.7906,144.7720,139.2849,140.3807,37434662
77
+ 2022-09-14,140.3807,141.8738,137.6514,138.7696,29374531
78
+ 2022-09-15,138.7696,142.5623,138.1234,141.0231,43526395
79
+ 2022-09-16,141.0231,141.2473,136.7909,138.2010,61832825
80
+ 2022-09-19,138.2010,141.8212,137.0369,141.5683,34835447
81
+ 2022-09-20,141.5683,143.0864,139.4827,139.6427,19899141
82
+ 2022-09-21,139.6427,139.8875,138.0773,138.7379,46295064
83
+ 2022-09-22,138.7379,140.5963,137.9340,139.0592,22950518
84
+ 2022-09-23,139.0592,139.6654,137.9584,139.6264,23627897
85
+ 2022-09-26,139.6264,140.4765,138.0684,139.7416,22127554
86
+ 2022-09-27,139.7416,140.2926,137.4767,138.3396,34547060
87
+ 2022-09-28,138.3396,143.6562,136.7728,142.0769,48139682
88
+ 2022-09-29,142.0769,145.4728,141.7326,144.5175,23988391
89
+ 2022-09-30,144.5175,145.8481,141.2125,142.3560,17645555
90
+ 2022-10-03,142.3560,142.4829,140.1131,141.0005,32394415
91
+ 2022-10-04,141.0005,141.7078,140.3177,141.0816,37788029
92
+ 2022-10-05,141.0816,143.5555,139.7986,143.4373,44089705
93
+ 2022-10-06,143.4373,146.1430,142.9412,145.8696,59548311
94
+ 2022-10-07,145.8696,150.1263,145.2110,149.6357,32166577
95
+ 2022-10-10,149.6357,151.3380,147.6023,148.4964,36419715
96
+ 2022-10-11,148.4964,153.0525,146.8255,151.8950,47181775
97
+ 2022-10-12,151.8950,152.0384,150.7532,151.6573,41037869
98
+ 2022-10-13,151.6573,154.3835,150.9917,152.8299,42379740
99
+ 2022-10-14,152.8299,157.4605,151.3190,155.6863,28648380
100
+ 2022-10-17,155.6863,159.8747,155.0975,158.5930,42558530
101
+ 2022-10-18,158.5930,162.8619,158.1285,161.2986,39446059
102
+ 2022-10-19,161.2986,163.2745,159.8202,162.9390,53912955
103
+ 2022-10-20,162.9390,165.7712,162.3205,163.8920,29399026
104
+ 2022-10-21,163.8920,169.4780,163.8793,168.2351,36799955
105
+ 2022-10-24,168.2351,169.9060,164.9097,166.8574,22559495
106
+ 2022-10-25,166.8574,170.4136,166.6272,168.6820,37220744
107
+ 2022-10-26,168.6820,169.3992,163.6109,164.7627,50015989
108
+ 2022-10-27,164.7627,166.0650,161.9548,163.0381,33504603
109
+ 2022-10-28,163.0381,164.9036,161.4943,163.3323,36083122
110
+ 2022-10-31,163.3323,166.9905,162.4053,166.1144,26884459
111
+ 2022-11-01,166.1144,166.4681,164.4281,166.3540,33759598
112
+ 2022-11-02,166.3540,168.0635,164.0036,165.3645,37841852
113
+ 2022-11-03,165.3645,170.0003,163.6566,168.7904,28620900
114
+ 2022-11-04,168.7904,173.5442,167.9788,171.5928,52491586
115
+ 2022-11-07,171.5928,177.4088,170.0348,176.1594,21304671
116
+ 2022-11-08,176.1594,177.9010,171.2243,172.8210,23405715
117
+ 2022-11-09,172.8210,176.0650,171.0556,175.7622,60639633
118
+ 2022-11-10,175.7622,176.9523,174.1573,176.3209,57627183
119
+ 2022-11-11,176.3209,177.3192,172.0211,173.3712,52578145
120
+ 2022-11-14,173.3712,175.0428,167.9039,169.1718,55506239
121
+ 2022-11-15,169.1718,170.0118,164.8528,166.0996,59087464
122
+ 2022-11-16,166.0996,167.9726,164.5363,165.5902,59956679
123
+ 2022-11-17,165.5902,170.1847,165.1824,170.0223,31119361
124
+ 2022-11-18,170.0223,172.0425,168.8116,170.5827,32562829
125
+ 2022-11-21,170.5827,171.4699,165.9147,167.9132,25292506
126
+ 2022-11-22,167.9132,169.0001,164.9456,165.2998,54162806
127
+ 2022-11-23,165.2998,165.5045,164.3623,165.3514,49610913
128
+ 2022-11-24,165.3514,166.7788,163.4866,166.3270,21204170
129
+ 2022-11-25,166.3270,166.8136,160.6813,162.4023,41236986
130
+ 2022-11-28,162.4023,164.7246,161.7036,163.9993,37099895
131
+ 2022-11-29,163.9993,165.1690,160.9217,161.5277,61627825
132
+ 2022-11-30,161.5277,164.5285,159.7175,164.1563,21913335
133
+ 2022-12-01,164.1563,169.0072,162.5169,168.1067,41259288
134
+ 2022-12-02,168.1067,168.8293,166.5666,167.7023,41456754
135
+ 2022-12-05,167.7023,168.6673,163.6443,164.5951,56312267
136
+ 2022-12-06,164.5951,164.9769,161.7618,161.9279,34765115
137
+ 2022-12-07,161.9279,162.6246,161.2947,161.4628,60351536
138
+ 2022-12-08,161.4628,162.7852,157.4684,157.8839,39307532
139
+ 2022-12-09,157.8839,158.8417,157.0807,157.2742,26398357
140
+ 2022-12-12,157.2742,158.6024,154.0704,154.1138,48288576
141
+ 2022-12-13,154.1138,154.3120,150.9453,152.4740,51802247
142
+ 2022-12-14,152.4740,152.9385,148.4520,149.7980,30815538
143
+ 2022-12-15,149.7980,152.9901,148.8072,151.9651,30082768
144
+ 2022-12-16,151.9651,154.0332,151.8021,152.4305,39214558
145
+ 2022-12-19,152.4305,152.6015,151.9140,152.5755,25603644
146
+ 2022-12-20,152.5755,155.4452,151.4205,154.1834,35741884
147
+ 2022-12-21,154.1834,158.4177,152.8941,156.8650,18562426
148
+ 2022-12-22,156.8650,158.4173,154.1391,154.5203,44784454
149
+ 2022-12-23,154.5203,158.7765,153.6953,158.1909,33874261
150
+ 2022-12-26,158.1909,159.5171,157.7942,158.8448,61676357
151
+ 2022-12-27,158.8448,160.6424,157.2460,158.0613,22794627
152
+ 2022-12-28,158.0613,158.8446,154.0200,155.8668,37029864
153
+ 2022-12-29,155.8668,156.5515,152.1522,152.9085,43839108
154
+ 2022-12-30,152.9085,153.4613,150.0348,150.2470,31723429
155
+ 2023-01-02,150.2470,151.9073,150.0122,150.4768,22020956
156
+ 2023-01-03,150.4768,151.1848,146.1678,147.7686,63386705
157
+ 2023-01-04,147.7686,149.3873,147.2179,147.7778,33690213
158
+ 2023-01-05,147.7778,148.6890,145.5279,145.9164,56872653
159
+ 2023-01-06,145.9164,149.5629,144.7856,148.3077,32013903
160
+ 2023-01-09,148.3077,149.4503,146.4922,147.1435,44120255
161
+ 2023-01-10,147.1435,148.1802,143.4742,144.9628,47038088
162
+ 2023-01-11,144.9628,145.4797,143.0683,143.6195,32144223
163
+ 2023-01-12,143.6195,146.4374,142.5767,146.2717,26090165
164
+ 2023-01-13,146.2717,148.0524,145.5106,146.7912,25916784
165
+ 2023-01-16,146.7912,148.3105,145.8002,147.7372,51160231
166
+ 2023-01-17,147.7372,148.6910,145.5677,146.5816,40478412
167
+ 2023-01-18,146.5816,146.9642,143.7413,145.2270,24041128
168
+ 2023-01-19,145.2270,145.2272,141.0273,142.6215,27644199
169
+ 2023-01-20,142.6215,144.9270,141.5365,144.3558,43897042
170
+ 2023-01-23,144.3558,145.0180,141.4161,142.9636,48578854
171
+ 2023-01-24,142.9636,144.4040,139.7050,140.4072,16160311
172
+ 2023-01-25,140.4072,142.3254,139.3981,140.9088,29079710
173
+ 2023-01-26,140.9088,141.7393,140.7650,141.5966,18896294
174
+ 2023-01-27,141.5966,143.0342,140.9088,142.1154,46020088
175
+ 2023-01-30,142.1154,143.8130,139.8781,140.1731,35763875
176
+ 2023-01-31,140.1731,141.5010,138.5103,141.3207,19454086
177
+ 2023-02-01,141.3207,143.3532,140.5007,143.2395,59089857
178
+ 2023-02-02,143.2395,144.7575,141.6480,144.3791,24487809
179
+ 2023-02-03,144.3791,145.2654,141.0388,142.1378,34185329
180
+ 2023-02-06,142.1378,143.5469,141.7807,142.6275,36967477
181
+ 2023-02-07,142.6275,144.1770,139.6226,140.7197,22468977
182
+ 2023-02-08,140.7197,141.1762,139.3685,140.5382,63891500
183
+ 2023-02-09,140.5382,141.6623,138.6237,139.1115,36777340
184
+ 2023-02-10,139.1115,140.2410,138.2406,139.4196,42239771
185
+ 2023-02-13,139.4196,141.4074,137.9228,140.0077,26644522
186
+ 2023-02-14,140.0077,141.8013,138.4348,140.4361,35038013
187
+ 2023-02-15,140.4361,141.6201,137.2364,138.7804,24542043
188
+ 2023-02-16,138.7804,139.9166,137.2607,137.4724,29076086
189
+ 2023-02-17,137.4724,137.9714,135.7770,136.6441,37826103
190
+ 2023-02-20,136.6441,137.8303,133.6829,134.5077,52832008
191
+ 2023-02-21,134.5077,135.9924,131.0542,131.7410,49383270
192
+ 2023-02-22,131.7410,133.7500,130.2145,132.2229,41407365
193
+ 2023-02-23,132.2229,132.2315,131.5787,131.7150,24508352
194
+ 2023-02-24,131.7150,134.3708,131.5056,133.8885,48515940
195
+ 2023-02-27,133.8885,134.1262,130.6624,131.3146,61579399
196
+ 2023-02-28,131.3146,132.1462,129.4757,130.3199,16704423
197
+ 2023-03-01,130.3199,130.5609,128.6511,129.0302,30446269
198
+ 2023-03-02,129.0302,129.7247,127.9010,128.6080,24186687
199
+ 2023-03-03,128.6080,128.6449,125.2151,126.4900,41351451
200
+ 2023-03-06,126.4900,127.1243,124.7468,124.7673,57510976
201
+ 2023-03-07,124.7673,127.9902,124.2014,127.2919,19367493
202
+ 2023-03-08,127.2919,129.9797,126.5960,129.7326,59116507
203
+ 2023-03-09,129.7326,132.8077,129.2628,132.6947,50921025
204
+ 2023-03-10,132.6947,135.1480,131.7717,134.6063,37811377
205
+ 2023-03-13,134.6063,139.0367,133.1152,137.5597,50343278
206
+ 2023-03-14,137.5597,140.0697,137.3062,138.8865,46647009
207
+ 2023-03-15,138.8865,139.7698,138.4016,139.0210,30616019
208
+ 2023-03-16,139.0210,140.4934,137.0606,138.7211,37600461
209
+ 2023-03-17,138.7211,140.6040,138.1897,139.2467,63904563
210
+ 2023-03-20,139.2467,139.8619,138.6762,139.6637,45892599
211
+ 2023-03-21,139.6637,143.8524,139.0000,143.2696,37968751
212
+ 2023-03-22,143.2696,143.2799,139.3070,140.6730,19906742
213
+ 2023-03-23,140.6730,144.0949,139.2280,142.6671,16501972
214
+ 2023-03-24,142.6671,142.9714,142.4706,142.9437,29117645
215
+ 2023-03-27,142.9437,143.5775,142.6406,142.8772,37542918
216
+ 2023-03-28,142.8772,145.0555,141.6908,144.4807,31027008
217
+ 2023-03-29,144.4807,148.1383,143.6584,146.9116,32187951
218
+ 2023-03-30,146.9116,147.3035,145.5146,145.5431,40577332
219
+ 2023-03-31,145.5431,148.2819,144.6893,147.5319,61103835
220
+ 2023-04-03,147.5319,148.2751,144.5336,146.0747,52634786
221
+ 2023-04-04,146.0747,146.7849,142.7085,143.6763,28735915
222
+ 2023-04-05,143.6763,147.4556,143.6094,146.0349,44362706
223
+ 2023-04-06,146.0349,146.9070,142.3872,142.4001,46293742
224
+ 2023-04-07,142.4001,142.4878,138.3520,139.5344,18746277
225
+ 2023-04-10,139.5344,139.6012,137.7011,138.6622,27155763
226
+ 2023-04-11,138.6622,139.8434,137.3353,138.2472,50522230
227
+ 2023-04-12,138.2472,141.1127,137.7835,140.7977,24828501
228
+ 2023-04-13,140.7977,144.2846,140.4378,143.2484,27139664
229
+ 2023-04-14,143.2484,144.0432,140.0562,140.4710,35547093
230
+ 2023-04-17,140.4710,142.0960,139.5788,140.9138,38581607
231
+ 2023-04-18,140.9138,142.1146,139.1607,139.4430,26649410
232
+ 2023-04-19,139.4430,141.1119,137.9747,138.2508,55547535
233
+ 2023-04-20,138.2508,142.8210,136.6856,141.2508,49948656
234
+ 2023-04-21,141.2508,141.5880,137.5066,138.7865,50452607
235
+ 2023-04-24,138.7865,139.6707,137.3383,139.1869,32406891
236
+ 2023-04-25,139.1869,141.3401,138.4521,139.8045,47992099
237
+ 2023-04-26,139.8045,141.0832,137.6149,139.0651,17261688
238
+ 2023-04-27,139.0651,140.6903,137.1073,138.7606,41182408
239
+ 2023-04-28,138.7606,139.0076,134.6397,136.1457,46879299
240
+ 2023-05-01,136.1457,137.7118,133.6466,133.7489,31610983
241
+ 2023-05-02,133.7489,135.4959,132.8496,135.4748,41255116
242
+ 2023-05-03,135.4748,137.9852,134.6214,137.3000,39211755
243
+ 2023-05-04,137.3000,138.4522,134.8214,135.4000,48234431
244
+ 2023-05-05,135.4000,137.3661,134.1352,136.1354,29860333
245
+ 2023-05-08,136.1354,140.0433,135.0874,138.7268,30166737
246
+ 2023-05-09,138.7268,140.3499,134.7882,135.9078,21143153
247
+ 2023-05-10,135.9078,140.2104,135.5300,139.1656,30905890
248
+ 2023-05-11,139.1656,143.4398,138.6643,142.9997,45233969
249
+ 2023-05-12,142.9997,143.3075,141.4119,142.5113,21881872
250
+ 2023-05-15,142.5113,143.5008,137.7018,138.9492,58596133
251
+ 2023-05-16,138.9492,139.1475,135.7163,136.0713,22354681
252
+ 2023-05-17,136.0713,136.6504,132.6879,133.1196,50790544
253
+ 2023-05-18,133.1196,134.0172,129.1524,130.7168,21989903
254
+ 2023-05-19,130.7168,131.5026,126.9655,128.2068,31027042
255
+ 2023-05-22,128.2068,129.3728,126.1629,126.6792,35036773
256
+ 2023-05-23,126.6792,127.6917,126.0449,127.0633,43089801
257
+ 2023-05-24,127.0633,131.8342,126.4674,130.2904,19247247
258
+ 2023-05-25,130.2904,132.3496,129.5528,131.5643,59721419
259
+ 2023-05-26,131.5643,132.8025,127.8454,129.0915,57321755
260
+ 2023-05-29,129.0915,132.4151,128.4796,131.4945,39711549
261
+ 2023-05-30,131.4945,131.5959,129.1600,129.7038,51989991
262
+ 2023-05-31,129.7038,132.7931,129.4506,131.9624,18181473
263
+ 2023-06-01,131.9624,133.5361,131.6584,131.9087,26932135
264
+ 2023-06-02,131.9087,132.9228,128.3772,129.2774,39127430
265
+ 2023-06-05,129.2774,130.0173,124.9391,126.2356,42304905
266
+ 2023-06-06,126.2356,129.8914,124.7713,128.7644,17322086
267
+ 2023-06-07,128.7644,131.8121,127.4767,131.0285,48283550
268
+ 2023-06-08,131.0285,135.8626,129.6838,134.2628,26692862
269
+ 2023-06-09,134.2628,135.4602,132.7162,134.5304,46241067
270
+ 2023-06-12,134.5304,135.9920,133.8481,134.9338,52545464
271
+ 2023-06-13,134.9338,136.0484,130.3476,131.5739,43731435
272
+ 2023-06-14,131.5739,133.6187,130.2123,132.1579,37540238
273
+ 2023-06-15,132.1579,136.2544,131.0292,135.8573,24346444
274
+ 2023-06-16,135.8573,138.3284,135.4662,137.6395,36946771
275
+ 2023-06-19,137.6395,138.9008,133.6924,134.7936,57883516
276
+ 2023-06-20,134.7936,137.9968,134.5681,137.0318,42430153
277
+ 2023-06-21,137.0318,138.4179,134.5249,135.3774,49176819
278
+ 2023-06-22,135.3774,137.8429,134.3712,136.6948,28571688
279
+ 2023-06-23,136.6948,137.2033,133.7525,134.7591,40173582
280
+ 2023-06-26,134.7591,135.4331,131.7575,132.8981,47833938
281
+ 2023-06-27,132.8981,134.4429,132.1697,132.6250,39713466
ceo_brief_env/fixtures/stooq_long/jpm_us.csv ADDED
@@ -0,0 +1,281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Date,Open,High,Low,Close,Volume
2
+ 2022-06-01,120.0000,124.2809,118.7149,122.8821,4002086
3
+ 2022-06-02,122.8821,124.2947,122.1005,123.6658,4450908
4
+ 2022-06-03,123.6658,124.3256,121.5094,121.8326,7568316
5
+ 2022-06-06,121.8326,121.9580,117.9332,118.9467,7243984
6
+ 2022-06-07,118.9467,120.2550,118.4343,119.2048,3752523
7
+ 2022-06-08,119.2048,122.0288,118.2636,121.1722,9161517
8
+ 2022-06-09,121.1722,124.9185,120.0674,124.3770,6739364
9
+ 2022-06-10,124.3770,126.0296,123.9078,125.0385,4023066
10
+ 2022-06-13,125.0385,126.1316,124.1523,125.0542,7495534
11
+ 2022-06-14,125.0542,126.4611,124.7863,126.1855,6304758
12
+ 2022-06-15,126.1855,128.7889,126.0124,128.4873,4146600
13
+ 2022-06-16,128.4873,128.9121,124.6773,125.5402,11078366
14
+ 2022-06-17,125.5402,126.0971,124.1714,124.6028,6125959
15
+ 2022-06-20,124.6028,127.4570,124.2164,126.6228,4228421
16
+ 2022-06-21,126.6228,129.8096,125.3638,128.7174,5485053
17
+ 2022-06-22,128.7174,130.6454,127.8019,129.2207,12276477
18
+ 2022-06-23,129.2207,130.7326,127.0504,127.1357,7195743
19
+ 2022-06-24,127.1357,128.3708,123.0912,124.1147,12547862
20
+ 2022-06-27,124.1147,127.7451,123.3126,126.3070,12686888
21
+ 2022-06-28,126.3070,128.6958,124.8301,128.1634,6819191
22
+ 2022-06-29,128.1634,128.2801,125.5664,126.2724,5087791
23
+ 2022-06-30,126.2724,130.8390,125.9452,129.3636,4193633
24
+ 2022-07-01,129.3636,130.0204,128.5196,129.7562,11003290
25
+ 2022-07-04,129.7562,130.4129,126.8662,128.2526,7469048
26
+ 2022-07-05,128.2526,129.6260,126.1325,127.3763,11793743
27
+ 2022-07-06,127.3763,129.4728,126.3170,128.8348,11166268
28
+ 2022-07-07,128.8348,130.3526,128.3784,129.9807,7132317
29
+ 2022-07-08,129.9807,132.9299,129.1229,132.0472,11134792
30
+ 2022-07-11,132.0472,133.0474,128.9882,129.5050,8569810
31
+ 2022-07-12,129.5050,132.3944,128.0262,132.0010,3954323
32
+ 2022-07-13,132.0010,133.4952,131.6286,132.6329,8584142
33
+ 2022-07-14,132.6329,133.3485,131.4827,132.6261,3237843
34
+ 2022-07-15,132.6261,133.8763,131.7370,131.9616,11526951
35
+ 2022-07-18,131.9616,133.0402,129.8162,130.0865,7513510
36
+ 2022-07-19,130.0865,130.2142,128.6584,129.7477,7809679
37
+ 2022-07-20,129.7477,132.0911,128.8822,131.2420,8250816
38
+ 2022-07-21,131.2420,132.6575,129.8976,130.0324,11615514
39
+ 2022-07-22,130.0324,133.5252,128.8200,132.7323,9664320
40
+ 2022-07-25,132.7323,134.1384,132.2232,133.6706,6554049
41
+ 2022-07-26,133.6706,135.2100,131.9271,132.4696,6920482
42
+ 2022-07-27,132.4696,133.7675,131.3462,132.1035,8516022
43
+ 2022-07-28,132.1035,132.5443,130.4501,130.5897,5285683
44
+ 2022-07-29,130.5897,131.9253,128.3726,129.1514,4259735
45
+ 2022-08-01,129.1514,129.3388,128.2131,129.0899,7444486
46
+ 2022-08-02,129.0899,132.1447,127.7719,131.7349,5576984
47
+ 2022-08-03,131.7349,136.3317,131.6674,135.3021,10948887
48
+ 2022-08-04,135.3021,135.8902,133.6607,133.8962,11239370
49
+ 2022-08-05,133.8962,135.0824,130.5671,131.1901,9722647
50
+ 2022-08-08,131.1901,131.3133,128.5210,129.9481,9485616
51
+ 2022-08-09,129.9481,131.4703,126.4689,127.8680,4952982
52
+ 2022-08-10,127.8680,128.8055,124.5924,124.8008,10226144
53
+ 2022-08-11,124.8008,125.8627,123.9289,124.7821,10598787
54
+ 2022-08-12,124.7821,128.0158,123.8965,127.0963,6337847
55
+ 2022-08-15,127.0963,127.2374,123.5386,124.8222,5178459
56
+ 2022-08-16,124.8222,125.2966,123.5977,124.5236,8320125
57
+ 2022-08-17,124.5236,127.7449,123.9828,127.0799,9451693
58
+ 2022-08-18,127.0799,130.3511,126.6044,128.9194,11710175
59
+ 2022-08-19,128.9194,133.9631,128.7195,132.4022,6849072
60
+ 2022-08-22,132.4022,135.8650,132.3395,134.5235,6992622
61
+ 2022-08-23,134.5235,137.5639,133.6597,136.3235,5221318
62
+ 2022-08-24,136.3235,136.4193,135.3400,135.8546,7302739
63
+ 2022-08-25,135.8546,139.3623,135.1791,138.3837,5560958
64
+ 2022-08-26,138.3837,139.4975,136.5028,137.2364,4861988
65
+ 2022-08-29,137.2364,140.7480,135.6431,139.7824,8349295
66
+ 2022-08-30,139.7824,141.6269,138.7621,140.9039,12020811
67
+ 2022-08-31,140.9039,145.8572,140.1764,144.7094,3801734
68
+ 2022-09-01,144.7094,148.2287,144.0453,147.5357,3748289
69
+ 2022-09-02,147.5357,148.2271,142.4285,144.1142,10309527
70
+ 2022-09-05,144.1142,147.0957,143.6423,145.9252,4819077
71
+ 2022-09-06,145.9252,147.0478,144.8954,146.9357,8139003
72
+ 2022-09-07,146.9357,147.7018,146.8165,147.4870,7743032
73
+ 2022-09-08,147.4870,148.6223,144.3994,144.9378,9158184
74
+ 2022-09-09,144.9378,148.1476,144.0132,147.0773,5094285
75
+ 2022-09-12,147.0773,148.8033,145.6358,146.1067,5929550
76
+ 2022-09-13,146.1067,147.2322,144.7203,146.2738,6034334
77
+ 2022-09-14,146.2738,150.1214,144.8865,150.0813,8669397
78
+ 2022-09-15,150.0813,153.7794,148.8401,153.4974,12293243
79
+ 2022-09-16,153.4974,155.2959,151.8011,155.0868,12508518
80
+ 2022-09-19,155.0868,156.6263,151.9755,152.1203,3980409
81
+ 2022-09-20,152.1203,156.0667,150.3731,154.7300,9266517
82
+ 2022-09-21,154.7300,155.5642,153.6663,155.0580,12727597
83
+ 2022-09-22,155.0580,158.1401,154.6906,156.4959,10255680
84
+ 2022-09-23,156.4959,158.7879,154.9556,158.6530,4890282
85
+ 2022-09-26,158.6530,158.7696,155.2696,156.5143,4566056
86
+ 2022-09-27,156.5143,160.6951,154.9939,160.6951,10488007
87
+ 2022-09-28,160.6951,162.6350,159.1563,161.5263,9309078
88
+ 2022-09-29,161.5263,163.0709,158.0075,158.6813,8804160
89
+ 2022-09-30,158.6813,160.7491,157.8923,159.0239,11392829
90
+ 2022-10-03,159.0239,159.6463,154.4846,155.7378,9074700
91
+ 2022-10-04,155.7378,159.1104,154.2349,158.7144,10837955
92
+ 2022-10-05,158.7144,158.9807,154.8572,155.9488,12565978
93
+ 2022-10-06,155.9488,157.9296,155.0003,157.1227,10971684
94
+ 2022-10-07,157.1227,158.5588,156.0041,157.5440,12148113
95
+ 2022-10-10,157.5440,161.9027,157.0408,160.2886,8961424
96
+ 2022-10-11,160.2886,164.6808,158.4578,163.2738,11986026
97
+ 2022-10-12,163.2738,164.2695,159.6082,160.2963,5169308
98
+ 2022-10-13,160.2963,162.4385,158.8185,160.5436,4151672
99
+ 2022-10-14,160.5436,161.2557,156.9529,158.6379,7611174
100
+ 2022-10-17,158.6379,159.6853,155.5503,156.0132,3568049
101
+ 2022-10-18,156.0132,158.8804,154.5605,157.0134,10267560
102
+ 2022-10-19,157.0134,158.0718,153.1785,154.3583,10487620
103
+ 2022-10-20,154.3583,154.4570,152.4377,154.1538,5749175
104
+ 2022-10-21,154.1538,157.2039,152.7124,156.3330,6442193
105
+ 2022-10-24,156.3330,157.1360,152.3084,153.1908,10808646
106
+ 2022-10-25,153.1908,154.4159,151.9499,152.6391,10233544
107
+ 2022-10-26,152.6391,154.2511,148.5301,150.2326,3427613
108
+ 2022-10-27,150.2326,154.7431,148.9833,153.3117,4216650
109
+ 2022-10-28,153.3117,156.8730,152.1595,155.4337,12451105
110
+ 2022-10-31,155.4337,160.5604,153.7084,159.3488,4580365
111
+ 2022-11-01,159.3488,160.3620,156.8941,157.8844,12347274
112
+ 2022-11-02,157.8844,160.4461,156.7073,159.2587,12277537
113
+ 2022-11-03,159.2587,160.6718,157.5144,158.6571,7063328
114
+ 2022-11-04,158.6571,158.9496,157.5208,157.5414,6425652
115
+ 2022-11-07,157.5414,157.6949,155.2001,156.1095,6568579
116
+ 2022-11-08,156.1095,161.3657,154.8636,159.8684,11331092
117
+ 2022-11-09,159.8684,160.0914,157.0415,158.1989,5383764
118
+ 2022-11-10,158.1989,163.3319,156.5167,162.5031,5559174
119
+ 2022-11-11,162.5031,163.7258,157.9237,159.2478,5657863
120
+ 2022-11-14,159.2478,164.9935,157.9345,163.0890,12620870
121
+ 2022-11-15,163.0890,167.8077,161.6596,167.5099,10361298
122
+ 2022-11-16,167.5099,170.5118,166.4178,169.8198,8845446
123
+ 2022-11-17,169.8198,173.3313,169.0552,173.2243,6222772
124
+ 2022-11-18,173.2243,176.4074,173.0961,176.1609,4308118
125
+ 2022-11-21,176.1609,177.0808,171.0447,172.8402,6609315
126
+ 2022-11-22,172.8402,174.2298,168.7693,169.4458,8683254
127
+ 2022-11-23,169.4458,172.8643,167.9547,171.9238,9147793
128
+ 2022-11-24,171.9238,176.9916,170.0645,175.3871,10364424
129
+ 2022-11-25,175.3871,176.4491,172.0168,173.6258,10732745
130
+ 2022-11-28,173.6258,177.7866,171.9078,176.0060,8394012
131
+ 2022-11-29,176.0060,177.6741,174.9976,177.5807,10176995
132
+ 2022-11-30,177.5807,183.5891,176.6446,181.7390,5404289
133
+ 2022-12-01,181.7390,187.1903,181.3212,185.7254,3561854
134
+ 2022-12-02,185.7254,191.0383,185.4814,189.7253,12703238
135
+ 2022-12-05,189.7253,192.6250,187.8894,190.8872,5656723
136
+ 2022-12-06,190.8872,191.7955,189.4843,191.4000,7372043
137
+ 2022-12-07,191.4000,194.8994,190.9279,194.6290,6915516
138
+ 2022-12-08,194.6290,195.5785,187.5874,189.7795,11510901
139
+ 2022-12-09,189.7795,191.6736,186.3412,186.8459,5500504
140
+ 2022-12-12,186.8459,189.1539,186.3946,188.4887,4022045
141
+ 2022-12-13,188.4887,188.9240,183.5121,185.5424,3602831
142
+ 2022-12-14,185.5424,186.6898,183.9387,186.2156,3228953
143
+ 2022-12-15,186.2156,187.8640,185.1683,185.2259,7148769
144
+ 2022-12-16,185.2259,186.3021,182.4089,183.7954,3967302
145
+ 2022-12-19,183.7954,188.2436,182.0926,187.6356,4476017
146
+ 2022-12-20,187.6356,188.0717,183.6927,183.8778,5579311
147
+ 2022-12-21,183.8778,184.0686,178.7943,180.6408,8273098
148
+ 2022-12-22,180.6408,181.9819,178.8839,180.8787,3640717
149
+ 2022-12-23,180.8787,182.3247,176.7766,176.7915,8054607
150
+ 2022-12-26,176.7915,180.0439,176.7900,178.2270,7058755
151
+ 2022-12-27,178.2270,179.4678,176.6575,176.7275,10438646
152
+ 2022-12-28,176.7275,182.4666,175.3147,181.2731,11217222
153
+ 2022-12-29,181.2731,186.6653,180.2132,184.8478,4041284
154
+ 2022-12-30,184.8478,189.9130,183.2930,188.0095,6220570
155
+ 2023-01-02,188.0095,194.4669,187.3047,193.0242,10746678
156
+ 2023-01-03,193.0242,193.5818,188.4223,190.4916,3729913
157
+ 2023-01-04,190.4916,195.4367,189.1840,194.5106,9833389
158
+ 2023-01-05,194.5106,199.4775,194.2937,198.9526,8116695
159
+ 2023-01-06,198.9526,199.9652,196.0821,196.3418,4064015
160
+ 2023-01-09,196.3418,197.4612,195.7137,197.3386,6926543
161
+ 2023-01-10,197.3386,199.2463,191.3059,193.3983,3508276
162
+ 2023-01-11,193.3983,197.2490,191.7052,196.8335,3782379
163
+ 2023-01-12,196.8335,201.9243,196.2216,199.6898,4784633
164
+ 2023-01-13,199.6898,201.7502,196.4446,198.3011,4704496
165
+ 2023-01-16,198.3011,204.6209,196.0235,202.8219,12537898
166
+ 2023-01-17,202.8219,204.5928,199.3959,199.4544,5040959
167
+ 2023-01-18,199.4544,200.6992,198.9320,200.1391,6634504
168
+ 2023-01-19,200.1391,202.3435,198.6140,200.0090,8538489
169
+ 2023-01-20,200.0090,203.0914,198.0809,202.6333,10522656
170
+ 2023-01-23,202.6333,207.4270,201.3158,206.3126,3918231
171
+ 2023-01-24,206.3126,207.9062,203.8179,206.1681,11802870
172
+ 2023-01-25,206.1681,208.0393,202.6176,204.7206,12428558
173
+ 2023-01-26,204.7206,207.8051,202.5746,206.9865,3356134
174
+ 2023-01-27,206.9865,209.1811,204.7939,208.0376,9163038
175
+ 2023-01-30,208.0376,208.4508,204.9598,205.0485,10421504
176
+ 2023-01-31,205.0485,209.3681,204.4982,208.4342,8552006
177
+ 2023-02-01,208.4342,209.7515,204.5361,205.3829,6263340
178
+ 2023-02-02,205.3829,208.3914,204.5660,207.7713,8613593
179
+ 2023-02-03,207.7713,213.3322,207.0072,212.9485,5817322
180
+ 2023-02-06,212.9485,214.1947,209.1011,211.1799,4939991
181
+ 2023-02-07,211.1799,215.0544,209.7304,213.9453,8025563
182
+ 2023-02-08,213.9453,215.8977,212.3637,215.4337,7060133
183
+ 2023-02-09,215.4337,220.5662,214.3791,219.0005,12675816
184
+ 2023-02-10,219.0005,219.0367,215.2850,215.6037,9822228
185
+ 2023-02-13,215.6037,217.5064,211.0396,211.2635,6054504
186
+ 2023-02-14,211.2635,213.0026,210.1661,212.9494,12793620
187
+ 2023-02-15,212.9494,216.8491,210.6280,215.8409,8664424
188
+ 2023-02-16,215.8409,220.6278,214.8524,219.7212,9925061
189
+ 2023-02-17,219.7212,224.9434,219.3249,223.0892,7245303
190
+ 2023-02-20,223.0892,223.7089,220.9659,221.2747,10383140
191
+ 2023-02-21,221.2747,222.2141,217.3536,217.4025,9965697
192
+ 2023-02-22,217.4025,219.3782,214.9237,219.1728,12751937
193
+ 2023-02-23,219.1728,224.5564,217.3224,222.4059,3411422
194
+ 2023-02-24,222.4059,223.0380,220.0079,220.0650,9328101
195
+ 2023-02-27,220.0650,222.4213,218.0890,221.4589,5449045
196
+ 2023-02-28,221.4589,221.7647,218.5993,219.2181,11367526
197
+ 2023-03-01,219.2181,221.3707,216.9352,219.4309,9597356
198
+ 2023-03-02,219.4309,221.9779,217.9358,218.1454,7165900
199
+ 2023-03-03,218.1454,224.7494,217.2197,222.9244,11140838
200
+ 2023-03-06,222.9244,228.2700,222.2115,226.3055,9728032
201
+ 2023-03-07,226.3055,230.8174,224.9126,228.5140,12121244
202
+ 2023-03-08,228.5140,232.1048,226.9279,231.5228,5084609
203
+ 2023-03-09,231.5228,234.2228,228.7502,233.3110,6485378
204
+ 2023-03-10,233.3110,239.6246,232.2656,237.2448,8854476
205
+ 2023-03-13,237.2448,238.3134,233.0059,234.2404,10030876
206
+ 2023-03-14,234.2404,235.1465,232.4162,234.6934,8154120
207
+ 2023-03-15,234.6934,236.6168,232.2523,235.3583,9481077
208
+ 2023-03-16,235.3583,239.1575,234.2236,237.7274,7299903
209
+ 2023-03-17,237.7274,241.6003,237.5292,240.3373,5319086
210
+ 2023-03-20,240.3373,240.4789,233.9970,235.0101,6826810
211
+ 2023-03-21,235.0101,235.5774,234.1631,234.8198,7492339
212
+ 2023-03-22,234.8198,235.5550,231.1920,232.5639,10530852
213
+ 2023-03-23,232.5639,232.6019,226.2755,227.4984,11784461
214
+ 2023-03-24,227.4984,230.4352,224.8428,229.4306,9716599
215
+ 2023-03-27,229.4306,236.0940,229.3236,233.7317,5071039
216
+ 2023-03-28,233.7317,238.8013,231.2066,237.6856,3883633
217
+ 2023-03-29,237.6856,245.3728,236.5122,243.5589,11164148
218
+ 2023-03-30,243.5589,245.7301,243.0203,244.3826,10725761
219
+ 2023-03-31,244.3826,245.2627,239.9133,240.1672,3351627
220
+ 2023-04-03,240.1672,240.2950,236.6047,237.9445,6530639
221
+ 2023-04-04,237.9445,239.2691,231.4259,232.2240,5422641
222
+ 2023-04-05,232.2240,234.0091,232.0722,233.0788,12137360
223
+ 2023-04-06,233.0788,239.9350,231.2347,239.2549,8816291
224
+ 2023-04-07,239.2549,240.8002,235.6728,236.4257,5842183
225
+ 2023-04-10,236.4257,236.5536,235.5446,236.1966,12644125
226
+ 2023-04-11,236.1966,240.8874,233.3716,239.9330,6357119
227
+ 2023-04-12,239.9330,245.7064,237.3587,244.7592,7539856
228
+ 2023-04-13,244.7592,250.3608,243.6008,249.9502,6508234
229
+ 2023-04-14,249.9502,256.6957,249.5435,254.0572,7136646
230
+ 2023-04-17,254.0572,254.2579,249.6394,250.0298,3908345
231
+ 2023-04-18,250.0298,251.3222,245.0882,247.7778,9458268
232
+ 2023-04-19,247.7778,252.5722,246.8212,251.5742,7155279
233
+ 2023-04-20,251.5742,251.6345,247.5670,248.3879,12113022
234
+ 2023-04-21,248.3879,249.8902,242.1745,242.8504,10520843
235
+ 2023-04-24,242.8504,244.3374,235.2054,237.2696,7638689
236
+ 2023-04-25,237.2696,239.8005,233.0888,233.1424,12095987
237
+ 2023-04-26,233.1424,239.9420,230.7209,237.4236,6749117
238
+ 2023-04-27,237.4236,240.7173,235.7570,239.3671,6846539
239
+ 2023-04-28,239.3671,245.1273,237.7551,244.2251,3854434
240
+ 2023-05-01,244.2251,246.8190,237.8559,238.8783,6795398
241
+ 2023-05-02,238.8783,247.5126,238.4327,245.3853,8412506
242
+ 2023-05-03,245.3853,247.3145,244.5825,245.5333,5846625
243
+ 2023-05-04,245.5333,253.4887,243.9103,251.6885,9840282
244
+ 2023-05-05,251.6885,255.9782,249.3238,255.4298,7834270
245
+ 2023-05-08,255.4298,256.3997,248.0959,251.0811,11312519
246
+ 2023-05-09,251.0811,258.3679,249.1639,256.8252,7004001
247
+ 2023-05-10,256.8252,262.0800,255.7233,260.4060,12583052
248
+ 2023-05-11,260.4060,260.9360,257.8615,260.8097,4120744
249
+ 2023-05-12,260.8097,262.2276,257.5036,258.1593,7513412
250
+ 2023-05-15,258.1593,259.8016,255.7068,257.7236,9780284
251
+ 2023-05-16,257.7236,258.4569,251.6161,251.9687,6395641
252
+ 2023-05-17,251.9687,254.5443,251.7286,251.7713,10978173
253
+ 2023-05-18,251.7713,254.0090,245.0351,247.5555,12666689
254
+ 2023-05-19,247.5555,249.0845,246.7016,248.9191,7382929
255
+ 2023-05-22,248.9191,254.5195,246.3010,251.5951,3805841
256
+ 2023-05-23,251.5951,253.5623,246.4069,247.0210,8801940
257
+ 2023-05-24,247.0210,249.1306,245.9860,247.5120,11938742
258
+ 2023-05-25,247.5120,248.5840,244.6981,245.1738,5981868
259
+ 2023-05-26,245.1738,247.0549,240.7116,240.7709,5529867
260
+ 2023-05-29,240.7709,247.5672,239.7895,245.0617,10253024
261
+ 2023-05-30,245.0617,251.4015,243.2353,249.4553,10436621
262
+ 2023-05-31,249.4553,250.4461,246.6829,247.4441,5416825
263
+ 2023-06-01,247.4441,249.5945,246.8775,247.9897,4019178
264
+ 2023-06-02,247.9897,248.6239,241.6604,242.1140,9162525
265
+ 2023-06-05,242.1140,248.0577,240.2431,246.4770,7243465
266
+ 2023-06-06,246.4770,248.6870,239.0704,241.2877,4617720
267
+ 2023-06-07,241.2877,243.2641,237.2003,239.2261,4774051
268
+ 2023-06-08,239.2261,240.3330,236.5938,238.1536,11073328
269
+ 2023-06-09,238.1536,239.2282,231.4565,234.0478,4903638
270
+ 2023-06-12,234.0478,236.2554,228.6634,230.3883,7769161
271
+ 2023-06-13,230.3883,230.5605,228.4559,230.2267,5738777
272
+ 2023-06-14,230.2267,232.7928,228.4887,229.8565,6989437
273
+ 2023-06-15,229.8565,230.6419,226.7111,228.4049,10077229
274
+ 2023-06-16,228.4049,228.4169,223.0283,224.0905,4788911
275
+ 2023-06-19,224.0905,226.0346,222.7344,225.5989,7755982
276
+ 2023-06-20,225.5989,232.4850,224.8894,231.5953,6440311
277
+ 2023-06-21,231.5953,234.5721,230.9235,233.8974,10027660
278
+ 2023-06-22,233.8974,234.8155,231.5217,234.6144,4417179
279
+ 2023-06-23,234.6144,236.1519,231.1599,232.4335,10551176
280
+ 2023-06-26,232.4335,234.2596,227.9579,228.4488,4316188
281
+ 2023-06-27,228.4488,233.3523,228.1529,231.1993,3519610
ceo_brief_env/fixtures/stooq_long/nvda_us.csv ADDED
@@ -0,0 +1,281 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Date,Open,High,Low,Close,Volume
2
+ 2022-06-01,48.0000,48.3224,47.4191,47.9509,47939004
3
+ 2022-06-02,47.9509,48.3813,47.8446,48.0427,50714518
4
+ 2022-06-03,48.0427,48.9065,47.9884,48.4455,38204075
5
+ 2022-06-06,48.4455,48.9162,47.0722,47.4672,22512820
6
+ 2022-06-07,47.4672,49.3158,47.0947,48.7514,56933762
7
+ 2022-06-08,48.7514,48.7602,47.6356,47.9396,23573066
8
+ 2022-06-09,47.9396,48.0788,47.2073,47.2244,47836067
9
+ 2022-06-10,47.2244,47.7018,46.8527,47.1464,58417502
10
+ 2022-06-13,47.1464,47.5919,46.8876,47.2165,36689773
11
+ 2022-06-14,47.2165,49.1126,46.7405,48.5327,62468577
12
+ 2022-06-15,48.5327,48.6665,47.9634,48.1304,24213409
13
+ 2022-06-16,48.1304,49.1167,47.6414,48.8818,43190811
14
+ 2022-06-17,48.8818,50.6517,48.8815,50.1418,32583044
15
+ 2022-06-20,50.1418,51.5967,49.5520,51.3074,43845463
16
+ 2022-06-21,51.3074,51.6949,49.7541,50.2233,36186535
17
+ 2022-06-22,50.2233,50.4237,48.6305,49.1997,65482431
18
+ 2022-06-23,49.1997,49.3451,48.2188,48.2773,23593604
19
+ 2022-06-24,48.2773,49.2145,47.9533,49.1097,46845492
20
+ 2022-06-27,49.1097,49.5411,48.3023,48.3783,58622907
21
+ 2022-06-28,48.3783,48.6226,47.3463,47.4676,36187698
22
+ 2022-06-29,47.4676,49.1933,47.2944,48.7236,73091906
23
+ 2022-06-30,48.7236,48.9541,47.5570,48.0496,58510139
24
+ 2022-07-01,48.0496,48.6200,46.9833,47.1039,35496653
25
+ 2022-07-04,47.1039,48.0442,46.9364,47.8553,24403913
26
+ 2022-07-05,47.8553,48.1899,46.7507,46.8875,56077030
27
+ 2022-07-06,46.8875,47.1425,46.1022,46.6390,49023471
28
+ 2022-07-07,46.6390,47.3809,46.5367,46.8933,29248119
29
+ 2022-07-08,46.8933,48.4495,46.7529,47.9787,31388039
30
+ 2022-07-11,47.9787,49.2086,47.8655,48.6595,77008151
31
+ 2022-07-12,48.6595,50.0782,48.4134,49.7181,26230380
32
+ 2022-07-13,49.7181,50.2925,48.4382,48.5771,62274767
33
+ 2022-07-14,48.5771,49.0573,47.6806,48.0243,37606120
34
+ 2022-07-15,48.0243,48.4395,47.2312,47.2702,33703780
35
+ 2022-07-18,47.2702,47.9756,46.9218,47.4899,36813163
36
+ 2022-07-19,47.4899,48.7306,47.4804,48.6116,36151635
37
+ 2022-07-20,48.6116,48.6469,48.4420,48.5446,42127122
38
+ 2022-07-21,48.5446,48.8802,48.3337,48.8031,73456413
39
+ 2022-07-22,48.8031,50.5143,48.3983,50.1192,55066416
40
+ 2022-07-25,50.1192,50.1403,49.2284,49.2390,74612747
41
+ 2022-07-26,49.2390,50.4131,49.2264,49.8373,58171071
42
+ 2022-07-27,49.8373,50.3023,49.6466,49.8651,79961457
43
+ 2022-07-28,49.8651,50.1919,48.3857,48.8174,74011752
44
+ 2022-07-29,48.8174,49.9221,48.3527,49.5041,74900154
45
+ 2022-08-01,49.5041,49.9111,48.6578,49.1896,72266075
46
+ 2022-08-02,49.1896,49.6562,48.5392,49.0474,54368449
47
+ 2022-08-03,49.0474,49.6727,48.7044,49.4458,56532014
48
+ 2022-08-04,49.4458,49.8252,47.8427,48.4198,72787509
49
+ 2022-08-05,48.4198,49.3069,47.9927,49.0781,54857172
50
+ 2022-08-08,49.0781,49.5718,48.9477,48.9970,65012610
51
+ 2022-08-09,48.9970,49.3505,47.5733,47.8494,33813298
52
+ 2022-08-10,47.8494,48.7131,47.4966,48.4242,75227856
53
+ 2022-08-11,48.4242,48.4308,47.6972,47.8702,60688218
54
+ 2022-08-12,47.8702,47.9676,46.6745,47.1874,59599400
55
+ 2022-08-15,47.1874,47.6923,46.9281,47.1129,59953943
56
+ 2022-08-16,47.1129,47.3565,45.9817,46.4308,74853271
57
+ 2022-08-17,46.4308,47.6550,46.1059,47.4362,38989210
58
+ 2022-08-18,47.4362,47.7188,46.1246,46.5927,70923218
59
+ 2022-08-19,46.5927,47.7220,46.4379,47.1841,30147734
60
+ 2022-08-22,47.1841,47.3399,47.0104,47.1315,44839088
61
+ 2022-08-23,47.1315,47.7979,46.9531,47.5163,70347104
62
+ 2022-08-24,47.5163,49.0665,47.4737,48.8015,21889146
63
+ 2022-08-25,48.8015,49.8638,48.3865,49.8390,54234917
64
+ 2022-08-26,49.8390,50.3124,49.3980,49.4093,28152869
65
+ 2022-08-29,49.4093,49.4240,48.8737,49.3652,34244540
66
+ 2022-08-30,49.3652,49.3930,48.1334,48.4996,46788846
67
+ 2022-08-31,48.4996,49.2909,48.0297,48.9064,77507639
68
+ 2022-09-01,48.9064,49.5763,48.6276,49.4580,30721165
69
+ 2022-09-02,49.4580,49.7382,47.8363,48.2498,30745928
70
+ 2022-09-05,48.2498,48.4499,47.3405,47.7400,51225376
71
+ 2022-09-06,47.7400,48.5377,47.5146,48.1012,67515934
72
+ 2022-09-07,48.1012,49.2605,47.5629,49.2090,63342630
73
+ 2022-09-08,49.2090,49.4768,47.9549,48.3176,74597921
74
+ 2022-09-09,48.3176,48.6474,47.5673,48.0746,67806034
75
+ 2022-09-12,48.0746,49.5528,47.6988,49.2786,32293661
76
+ 2022-09-13,49.2786,50.4225,48.8992,49.9322,63059717
77
+ 2022-09-14,49.9322,50.4714,48.6689,49.2483,78641511
78
+ 2022-09-15,49.2483,49.8876,49.0590,49.4187,74599383
79
+ 2022-09-16,49.4187,50.6356,49.3696,50.4247,46454071
80
+ 2022-09-19,50.4247,51.1015,50.1297,50.6347,21704621
81
+ 2022-09-20,50.6347,51.5799,50.1487,51.5403,30373778
82
+ 2022-09-21,51.5403,52.0276,51.0807,51.1669,28920533
83
+ 2022-09-22,51.1669,51.7338,50.6512,51.2885,61362292
84
+ 2022-09-23,51.2885,52.8879,50.7043,52.5771,25161410
85
+ 2022-09-26,52.5771,52.9094,51.6990,51.8797,63730592
86
+ 2022-09-27,51.8797,52.6677,51.3544,52.3393,53598265
87
+ 2022-09-28,52.3393,52.5787,51.3691,51.8955,74031502
88
+ 2022-09-29,51.8955,52.4253,50.5762,51.1708,51453556
89
+ 2022-09-30,51.1708,51.5696,50.8418,51.4455,50190446
90
+ 2022-10-03,51.4455,51.8269,50.8471,51.8096,50961066
91
+ 2022-10-04,51.8096,52.3077,51.2657,51.6144,49462426
92
+ 2022-10-05,51.6144,52.2555,51.2807,52.2142,44826445
93
+ 2022-10-06,52.2142,54.1503,52.0456,53.5569,48389689
94
+ 2022-10-07,53.5569,53.8356,52.0637,52.5783,74033328
95
+ 2022-10-10,52.5783,52.7920,52.4575,52.5918,57073692
96
+ 2022-10-11,52.5918,53.9398,52.1000,53.8561,21367156
97
+ 2022-10-12,53.8561,54.0030,52.6263,53.0637,39324934
98
+ 2022-10-13,53.0637,53.4584,52.6701,52.7365,63853625
99
+ 2022-10-14,52.7365,53.0596,51.6057,51.7613,31863730
100
+ 2022-10-17,51.7613,52.1943,51.5279,51.9222,44804120
101
+ 2022-10-18,51.9222,52.1807,51.7949,52.0808,57878899
102
+ 2022-10-19,52.0808,52.8751,51.5488,52.5412,56702668
103
+ 2022-10-20,52.5412,53.7631,52.0741,53.6135,68630494
104
+ 2022-10-21,53.6135,55.0460,53.4108,54.8381,75366018
105
+ 2022-10-24,54.8381,55.4951,53.5250,54.1012,28035933
106
+ 2022-10-25,54.1012,54.5729,53.2685,53.4349,25820952
107
+ 2022-10-26,53.4349,54.7313,52.9284,54.4558,27560196
108
+ 2022-10-27,54.4558,54.9036,54.2453,54.2569,32056043
109
+ 2022-10-28,54.2569,55.4627,53.6264,54.8627,26924614
110
+ 2022-10-31,54.8627,55.4616,54.5317,54.9615,61140957
111
+ 2022-11-01,54.9615,55.0081,54.0691,54.1381,22246152
112
+ 2022-11-02,54.1381,54.7034,53.7686,54.3675,28793289
113
+ 2022-11-03,54.3675,54.5006,53.0003,53.5401,79418082
114
+ 2022-11-04,53.5401,54.8944,53.5003,54.8318,77089696
115
+ 2022-11-07,54.8318,55.3349,54.5888,54.8038,48017592
116
+ 2022-11-08,54.8038,55.2139,54.4086,54.9304,20794760
117
+ 2022-11-09,54.9304,56.1613,54.8109,55.5981,47237058
118
+ 2022-11-10,55.5981,56.6609,55.4679,56.3867,29904599
119
+ 2022-11-11,56.3867,56.5193,55.7823,56.5088,68102369
120
+ 2022-11-14,56.5088,57.7974,56.0820,57.2066,44270594
121
+ 2022-11-15,57.2066,57.9429,56.5320,57.5944,68289284
122
+ 2022-11-16,57.5944,58.2242,56.4342,56.9429,66679278
123
+ 2022-11-17,56.9429,58.2601,56.3302,57.9779,72790490
124
+ 2022-11-18,57.9779,59.2035,57.4455,58.6634,44344730
125
+ 2022-11-21,58.6634,59.4939,58.4228,59.4436,48130423
126
+ 2022-11-22,59.4436,59.6973,57.5464,57.9909,57441216
127
+ 2022-11-23,57.9909,58.6483,56.7969,57.2545,40268936
128
+ 2022-11-24,57.2545,58.2204,56.8883,57.8252,43375644
129
+ 2022-11-25,57.8252,59.9021,57.3386,59.4439,65704382
130
+ 2022-11-28,59.4439,61.0624,59.0050,61.0456,64327692
131
+ 2022-11-29,61.0456,61.3398,60.3133,60.3498,31726765
132
+ 2022-11-30,60.3498,60.4211,59.8619,60.0427,74338595
133
+ 2022-12-01,60.0427,60.6595,59.3458,60.2920,54078710
134
+ 2022-12-02,60.2920,62.4390,59.7063,61.9646,24571759
135
+ 2022-12-05,61.9646,62.9462,61.9310,62.3778,75809229
136
+ 2022-12-06,62.3778,62.7310,61.2226,61.3471,49731254
137
+ 2022-12-07,61.3471,61.8440,60.6513,61.8006,45242232
138
+ 2022-12-08,61.8006,62.4256,61.5295,61.9810,37145024
139
+ 2022-12-09,61.9810,63.0045,61.7701,62.5835,62996106
140
+ 2022-12-12,62.5835,62.5940,61.8185,62.0008,22566440
141
+ 2022-12-13,62.0008,62.5623,60.6801,60.9654,73852526
142
+ 2022-12-14,60.9654,61.8966,60.2420,61.8593,76667440
143
+ 2022-12-15,61.8593,62.5315,60.2417,60.5538,48656506
144
+ 2022-12-16,60.5538,62.3450,60.1735,62.1632,76236257
145
+ 2022-12-19,62.1632,63.3443,61.4331,62.9903,69001762
146
+ 2022-12-20,62.9903,63.5183,62.5184,63.4307,47341321
147
+ 2022-12-21,63.4307,63.4704,62.1334,62.5296,27459554
148
+ 2022-12-22,62.5296,63.0308,62.0928,62.4341,35727764
149
+ 2022-12-23,62.4341,63.1160,61.8512,62.7998,51845975
150
+ 2022-12-26,62.7998,65.2883,62.2465,64.5504,34304661
151
+ 2022-12-27,64.5504,65.2419,62.7302,63.3262,57498585
152
+ 2022-12-28,63.3262,63.5325,62.4311,62.9485,53893424
153
+ 2022-12-29,62.9485,63.8301,62.3795,63.3488,31388926
154
+ 2022-12-30,63.3488,64.0936,61.9131,62.6010,72726584
155
+ 2023-01-02,62.6010,62.6466,60.9682,61.1670,45511578
156
+ 2023-01-03,61.1670,61.7345,60.7695,61.6587,24349570
157
+ 2023-01-04,61.6587,62.1590,60.0006,60.3997,57866325
158
+ 2023-01-05,60.3997,60.7465,59.9325,60.0843,40622031
159
+ 2023-01-06,60.0843,61.5674,60.0307,60.9541,27187311
160
+ 2023-01-09,60.9541,62.5087,60.3918,62.0444,32789879
161
+ 2023-01-10,62.0444,62.2365,61.2872,61.8887,42136999
162
+ 2023-01-11,61.8887,63.2273,61.6470,62.4855,52916808
163
+ 2023-01-12,62.4855,64.0948,62.1649,63.3943,42155630
164
+ 2023-01-13,63.3943,64.0601,62.0769,62.1354,24981285
165
+ 2023-01-16,62.1354,62.8034,61.6244,62.4401,37932240
166
+ 2023-01-17,62.4401,63.5034,62.2803,63.4455,59725896
167
+ 2023-01-18,63.4455,63.6768,61.5935,62.1341,61638850
168
+ 2023-01-19,62.1341,62.2407,61.2483,61.5124,63558537
169
+ 2023-01-20,61.5124,61.5991,60.6485,61.1691,54156473
170
+ 2023-01-23,61.1691,63.3241,60.4987,62.6178,46279562
171
+ 2023-01-24,62.6178,63.9505,62.3791,63.7175,43975501
172
+ 2023-01-25,63.7175,65.9818,63.5276,65.2809,41701652
173
+ 2023-01-26,65.2809,65.5655,64.6056,64.9137,43254792
174
+ 2023-01-27,64.9137,65.3529,63.3498,63.9616,52433687
175
+ 2023-01-30,63.9616,65.6382,63.8261,65.1979,65536841
176
+ 2023-01-31,65.1979,66.8368,65.1805,66.6119,50938477
177
+ 2023-02-01,66.6119,67.3230,65.8394,66.8676,59072247
178
+ 2023-02-02,66.8676,68.0988,66.4289,68.0465,67283772
179
+ 2023-02-03,68.0465,68.1131,66.0589,66.6484,73944311
180
+ 2023-02-06,66.6484,67.1556,65.1687,65.2814,64747492
181
+ 2023-02-07,65.2814,66.0889,65.1087,65.8948,65921181
182
+ 2023-02-08,65.8948,66.6752,65.5830,66.0690,40268815
183
+ 2023-02-09,66.0690,68.3549,65.6776,67.8078,52240390
184
+ 2023-02-10,67.8078,69.2873,67.0633,68.7035,44636331
185
+ 2023-02-13,68.7035,70.5545,67.9998,69.9945,68354435
186
+ 2023-02-14,69.9945,72.0986,69.1900,71.3379,58416401
187
+ 2023-02-15,71.3379,72.1446,70.6511,71.5351,45296655
188
+ 2023-02-16,71.5351,71.6606,70.7062,71.3408,79460622
189
+ 2023-02-17,71.3408,71.4843,70.8031,70.9771,45496710
190
+ 2023-02-20,70.9771,71.8031,70.2513,70.3012,38506676
191
+ 2023-02-21,70.3012,70.8479,68.3293,68.9715,30765972
192
+ 2023-02-22,68.9715,69.3512,67.0022,67.4751,74557695
193
+ 2023-02-23,67.4751,67.5631,65.7723,65.9183,33041860
194
+ 2023-02-24,65.9183,66.4857,64.6282,65.0928,33437559
195
+ 2023-02-27,65.0928,65.3123,63.9710,64.1037,65450232
196
+ 2023-02-28,64.1037,64.5254,62.9369,63.5602,48769467
197
+ 2023-03-01,63.5602,64.2370,62.1591,62.8486,40524498
198
+ 2023-03-02,62.8486,63.8253,62.4846,63.1006,33260314
199
+ 2023-03-03,63.1006,63.8181,61.0960,61.6893,43098593
200
+ 2023-03-06,61.6893,62.2550,61.4861,61.8720,79414739
201
+ 2023-03-07,61.8720,62.6597,61.8640,62.4815,48358760
202
+ 2023-03-08,62.4815,63.0789,61.6179,62.1499,56364393
203
+ 2023-03-09,62.1499,62.2669,60.8782,61.1143,35565400
204
+ 2023-03-10,61.1143,62.7884,60.6471,62.4019,79587131
205
+ 2023-03-13,62.4019,62.8022,61.6117,61.7233,66222663
206
+ 2023-03-14,61.7233,62.3317,59.5736,60.1847,69325303
207
+ 2023-03-15,60.1847,60.3796,58.4362,58.9430,25830017
208
+ 2023-03-16,58.9430,59.3009,58.2672,58.9693,55198007
209
+ 2023-03-17,58.9693,60.3938,58.4107,60.1745,45018230
210
+ 2023-03-20,60.1745,61.6612,59.5779,61.5939,32504498
211
+ 2023-03-21,61.5939,62.2179,61.4775,61.8279,69920547
212
+ 2023-03-22,61.8279,62.0585,61.2467,61.3027,38342082
213
+ 2023-03-23,61.3027,61.8288,61.0236,61.2881,61225660
214
+ 2023-03-24,61.2881,61.5781,59.7664,60.0995,78014498
215
+ 2023-03-27,60.0995,61.7205,60.0905,61.2399,42627605
216
+ 2023-03-28,61.2399,62.1901,60.8254,62.0134,47485269
217
+ 2023-03-29,62.0134,62.7513,59.9171,60.4975,32403806
218
+ 2023-03-30,60.4975,61.1728,60.2245,60.9604,52386055
219
+ 2023-03-31,60.9604,61.2072,60.1156,60.3998,60001328
220
+ 2023-04-03,60.3998,60.5448,59.1867,59.7108,39763881
221
+ 2023-04-04,59.7108,61.6221,59.1922,61.2087,39899507
222
+ 2023-04-05,61.2087,62.4300,61.1053,62.3610,25663785
223
+ 2023-04-06,62.3610,63.5777,62.2264,63.0418,44136741
224
+ 2023-04-07,63.0418,64.7192,62.9737,64.2621,33594978
225
+ 2023-04-10,64.2621,64.3578,62.8821,63.1906,24360950
226
+ 2023-04-11,63.1906,65.0256,62.8027,64.6941,58834852
227
+ 2023-04-12,64.6941,66.3535,64.3944,65.7061,39884630
228
+ 2023-04-13,65.7061,65.7183,65.1838,65.4987,61992841
229
+ 2023-04-14,65.4987,67.9075,64.9798,67.2700,56516241
230
+ 2023-04-17,67.2700,67.5372,65.3847,65.6544,59043339
231
+ 2023-04-18,65.6544,65.9519,63.9893,64.3828,67313257
232
+ 2023-04-19,64.3828,66.0703,64.2605,65.5890,65990762
233
+ 2023-04-20,65.5890,67.5297,65.3115,67.0883,50024936
234
+ 2023-04-21,67.0883,67.6627,65.1346,65.9152,50962181
235
+ 2023-04-24,65.9152,67.4359,65.7592,66.7665,76693427
236
+ 2023-04-25,66.7665,67.4763,66.6998,67.3164,34675961
237
+ 2023-04-26,67.3164,68.2565,67.0505,67.6903,75743602
238
+ 2023-04-27,67.6903,68.0664,67.1937,67.2939,78414699
239
+ 2023-04-28,67.2939,68.0239,65.6642,66.0952,53643678
240
+ 2023-05-01,66.0952,66.6164,65.3739,66.4057,79527871
241
+ 2023-05-02,66.4057,68.1109,66.3080,67.6228,69479116
242
+ 2023-05-03,67.6228,68.3507,66.7730,66.9665,54415063
243
+ 2023-05-04,66.9665,68.3928,66.5263,68.2409,24576281
244
+ 2023-05-05,68.2409,68.3883,65.8613,66.6507,76366678
245
+ 2023-05-08,66.6507,67.5586,66.1138,67.3101,64260744
246
+ 2023-05-09,67.3101,67.7882,66.3427,66.9888,20980949
247
+ 2023-05-10,66.9888,67.3651,65.9092,66.0225,43182666
248
+ 2023-05-11,66.0225,66.5031,65.6107,66.3648,35819491
249
+ 2023-05-12,66.3648,66.9695,65.8538,66.7037,22271791
250
+ 2023-05-15,66.7037,67.5253,65.9358,67.4082,56005598
251
+ 2023-05-16,67.4082,67.7410,66.8973,67.4019,61358523
252
+ 2023-05-17,67.4019,69.0420,67.0089,68.4247,79676891
253
+ 2023-05-18,68.4247,70.4697,68.0889,69.7540,46037392
254
+ 2023-05-19,69.7540,70.8640,69.3137,70.1025,51500069
255
+ 2023-05-22,70.1025,70.8632,69.6866,69.9559,23280846
256
+ 2023-05-23,69.9559,71.6630,69.3414,70.8972,55851297
257
+ 2023-05-24,70.8972,72.2131,70.3923,71.9500,24187987
258
+ 2023-05-25,71.9500,72.3359,70.1998,70.6258,43803458
259
+ 2023-05-26,70.6258,71.2147,68.6186,69.0547,34348857
260
+ 2023-05-29,69.0547,69.3824,68.2556,68.4493,24106379
261
+ 2023-05-30,68.4493,70.8564,67.9025,70.0441,71989491
262
+ 2023-05-31,70.0441,70.7209,69.6715,69.8574,64797363
263
+ 2023-06-01,69.8574,70.9706,69.7748,70.2095,67541445
264
+ 2023-06-02,70.2095,70.6624,68.1285,68.9149,20034594
265
+ 2023-06-05,68.9149,69.1624,67.8177,68.0830,23758054
266
+ 2023-06-06,68.0830,70.2921,67.7584,69.6109,41389863
267
+ 2023-06-07,69.6109,70.0693,69.5849,70.0308,73910730
268
+ 2023-06-08,70.0308,70.4496,68.6446,69.4226,78636742
269
+ 2023-06-09,69.4226,69.5981,69.1766,69.4261,75358941
270
+ 2023-06-12,69.4261,71.1568,68.7280,70.9903,41249240
271
+ 2023-06-13,70.9903,71.1397,70.2409,70.9933,79724244
272
+ 2023-06-14,70.9933,71.5320,69.8177,69.9785,72810169
273
+ 2023-06-15,69.9785,70.0676,67.8187,68.4145,38779274
274
+ 2023-06-16,68.4145,70.6988,67.8290,69.9686,28092788
275
+ 2023-06-19,69.9686,71.5970,69.5949,70.8002,24739373
276
+ 2023-06-20,70.8002,71.0612,69.2722,69.8679,31787909
277
+ 2023-06-21,69.8679,70.0653,68.2429,68.7915,67429400
278
+ 2023-06-22,68.7915,69.3380,67.7036,68.4299,55394024
279
+ 2023-06-23,68.4299,68.6770,66.7985,67.5497,60022008
280
+ 2023-06-26,67.5497,68.0684,66.7799,66.8520,78981678
281
+ 2023-06-27,66.8520,67.2759,66.3158,66.7409,22720502
ceo_brief_env/graders.py ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ from typing import Dict, Iterable, List
4
+
5
+ import pandas as pd
6
+
7
+ from .models import Brief, ExpertReport
8
+
9
+ _SCORE_MIN = 0.001
10
+ _SCORE_MAX = 0.999
11
+
12
+
13
+ # RAG+ mode: Stooq watchlist citations (see ``ceo_brief_env.stooq_scrape``).
14
+ STOOQ_CITATION_PREFIX = "stooq:"
15
+ STOOQ_CITATION_SUFFIXES = frozenset({"nvda.us", "aapl.us", "jpm.us"})
16
+
17
+
18
+ def _citation_grounds(retriever_sources: set[str], c: str) -> bool:
19
+ if not isinstance(c, str) or not c:
20
+ return False
21
+ if c.startswith("memory:") and c[len("memory:") :] in retriever_sources:
22
+ return True
23
+ if c.startswith(STOOQ_CITATION_PREFIX):
24
+ rest = c[len(STOOQ_CITATION_PREFIX) :]
25
+ return rest in STOOQ_CITATION_SUFFIXES
26
+ return False
27
+
28
+
29
+ def grounding_score(reports: Dict[str, ExpertReport]) -> float:
30
+ """Fraction of specialists with a resolvable ``memory:`` or ``stooq:`` citation (RAG on only)."""
31
+ if not reports:
32
+ return 0.0
33
+ try:
34
+ from memory import get_retriever
35
+ except Exception:
36
+ known_sources: set[str] = set()
37
+ else:
38
+ known_sources = set(get_retriever().sources())
39
+ grounded = 0
40
+ for report in reports.values():
41
+ cites = getattr(report, "memory_citations", []) or []
42
+ if any(_citation_grounds(known_sources, c) for c in cites):
43
+ grounded += 1
44
+ return grounded / max(len(reports), 1)
45
+
46
+
47
+ def _clamp(score: float) -> float:
48
+ return max(_SCORE_MIN, min(_SCORE_MAX, round(float(score), 4)))
49
+
50
+
51
+ def load_metric_ground_truth(path: str) -> Dict[str, str]:
52
+ df = pd.read_csv(path)
53
+ return {str(row["metric"]): str(row["value"]) for _, row in df.iterrows()}
54
+
55
+
56
+ def _try_float(value: object) -> float | None:
57
+ try:
58
+ return float(value)
59
+ except (TypeError, ValueError):
60
+ return None
61
+
62
+
63
+ def metric_match_score(expected: Dict[str, str], actual: Dict[str, object]) -> float:
64
+ if not expected:
65
+ return 1.0
66
+ matched = 0.0
67
+ for key, expected_value in expected.items():
68
+ actual_value = actual.get(key)
69
+ ev = _try_float(expected_value)
70
+ av = _try_float(actual_value)
71
+ if ev is not None and av is not None:
72
+ tolerance = max(0.5, abs(ev) * 0.02)
73
+ if abs(ev - av) <= tolerance:
74
+ matched += 1.0
75
+ elif str(actual_value) == str(expected_value):
76
+ matched += 1.0
77
+ return matched / max(len(expected), 1)
78
+
79
+
80
+ def strategy_rubric_score(recommendations: List[str], evidence_numbers: Iterable[str], categories: Iterable[str]) -> float:
81
+ if not recommendations:
82
+ return 0.001
83
+ score = 0.0
84
+ if len(recommendations) == 3:
85
+ score += 0.25
86
+ lowered = [r.lower() for r in recommendations]
87
+ nums = [str(n) for n in evidence_numbers]
88
+ if nums and all(any(n in rec for n in nums) for rec in lowered[: min(3, len(lowered))]):
89
+ score += 0.25
90
+ cat_hits = 0
91
+ for cat in set(str(c).lower() for c in categories if c):
92
+ if any(cat in rec for rec in lowered):
93
+ cat_hits += 1
94
+ if cat_hits >= 2:
95
+ score += 0.25
96
+ if any("projection" in rec or "variance" in rec or "break-even" in rec for rec in lowered):
97
+ score += 0.25
98
+ return _clamp(score)
99
+
100
+
101
+ def grade_episode(
102
+ expected_metrics: Dict[str, str],
103
+ task_meta: Dict[str, object],
104
+ brief: Brief,
105
+ reports: Dict[str, ExpertReport],
106
+ use_rag: bool = False,
107
+ ) -> float:
108
+ required_experts = list(task_meta.get("required_experts", []))
109
+ coverage = 0.0
110
+ if required_experts:
111
+ covered = sum(1 for expert in required_experts if expert in brief.consulted_experts)
112
+ coverage = covered / len(required_experts)
113
+
114
+ metric_score = metric_match_score(expected_metrics, brief.metrics)
115
+ hr_score = reports.get("hr").score if reports.get("hr") and reports.get("hr").score is not None else 0.001
116
+ analyst_cats = []
117
+ if reports.get("analyst"):
118
+ analyst_cats = [c for c in reports["analyst"].citations if c]
119
+ evidence_numbers = [str(v) for v in brief.metrics.values()]
120
+ strategy_needed = "strategy" in required_experts
121
+ strategy_score = 1.0 if not strategy_needed else strategy_rubric_score(brief.recommendations, evidence_numbers, analyst_cats)
122
+
123
+ if use_rag:
124
+ ground_score = grounding_score(reports)
125
+ weights = {
126
+ "coverage": 0.2,
127
+ "metrics": 0.40,
128
+ "hr": 0.15,
129
+ "strategy": 0.15,
130
+ "grounding": 0.10,
131
+ }
132
+ if not strategy_needed:
133
+ weights["metrics"] += weights["strategy"]
134
+ weights["strategy"] = 0.0
135
+ total = (
136
+ weights["coverage"] * coverage
137
+ + weights["metrics"] * metric_score
138
+ + weights["hr"] * hr_score
139
+ + weights["strategy"] * strategy_score
140
+ + weights["grounding"] * ground_score
141
+ )
142
+ else:
143
+ weights = {
144
+ "coverage": 0.2,
145
+ "metrics": 0.5,
146
+ "hr": 0.15,
147
+ "strategy": 0.15,
148
+ }
149
+ if not strategy_needed:
150
+ weights["metrics"] += weights["strategy"]
151
+ weights["strategy"] = 0.0
152
+ total = (
153
+ weights["coverage"] * coverage
154
+ + weights["metrics"] * metric_score
155
+ + weights["hr"] * hr_score
156
+ + weights["strategy"] * strategy_score
157
+ )
158
+ return _clamp(total)
ceo_brief_env/models.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ from typing import Any, Dict, List, Literal, Optional
4
+
5
+ from pydantic import BaseModel, ConfigDict, Field
6
+
7
+
8
+ class RewardBreakdown(BaseModel):
9
+ model_config = ConfigDict(extra="forbid")
10
+
11
+ immediate: float
12
+ cumulative: float
13
+ terminal_grader: Optional[float] = None
14
+
15
+
16
+ class CoSAction(BaseModel):
17
+ model_config = ConfigDict(extra="ignore")
18
+
19
+ action_type: Literal["consult", "ask", "summarize", "submit", "noop"]
20
+ expert_id: Optional[Literal["analyst", "finance", "hr", "strategy"]] = None
21
+ sub_question_id: Optional[str] = None
22
+ notes: Optional[str] = None
23
+
24
+
25
+ class ExpertReport(BaseModel):
26
+ model_config = ConfigDict(extra="forbid")
27
+
28
+ expert_id: Literal["analyst", "finance", "hr", "strategy"]
29
+ title: str
30
+ summary: str
31
+ metrics: Dict[str, float | int | str] = Field(default_factory=dict)
32
+ bullet_points: List[str] = Field(default_factory=list)
33
+ issues: List[str] = Field(default_factory=list)
34
+ citations: List[str] = Field(default_factory=list)
35
+ memory_citations: List[str] = Field(default_factory=list)
36
+ memory_snippets: List[str] = Field(default_factory=list)
37
+ memo: Optional[str] = None
38
+ score: Optional[float] = None
39
+
40
+
41
+ class Brief(BaseModel):
42
+ model_config = ConfigDict(extra="forbid")
43
+
44
+ summary: str
45
+ metrics: Dict[str, float | int | str] = Field(default_factory=dict)
46
+ recommendations: List[str] = Field(default_factory=list)
47
+ hr_memo: str = ""
48
+ consulted_experts: List[str] = Field(default_factory=list)
49
+
50
+
51
+ class CoSObservation(BaseModel):
52
+ model_config = ConfigDict(extra="forbid")
53
+
54
+ done: bool
55
+ reward: float = 0.0
56
+ instruction: str
57
+ history: List[str] = Field(default_factory=list)
58
+ issues: List[str] = Field(default_factory=list)
59
+ data_quality_score: float = 0.0
60
+ task_name: str
61
+ task_difficulty: str
62
+ rag_enabled: bool = False
63
+ max_steps: int = 12
64
+ step_count: int = 0
65
+ available_experts: List[str] = Field(default_factory=lambda: ["analyst", "finance", "hr", "strategy"])
66
+ consulted_experts: List[str] = Field(default_factory=list)
67
+ expert_reports: Dict[str, ExpertReport] = Field(default_factory=dict)
68
+ current_brief: Optional[Brief] = None
69
+ reward_breakdown: Optional[RewardBreakdown] = None
70
+ terminal_grader_score: Optional[float] = None
71
+
72
+
73
+ class CoSState(BaseModel):
74
+ model_config = ConfigDict(extra="forbid")
75
+
76
+ episode_id: str
77
+ task_name: str
78
+ step_count: int = 0
79
+ done: bool = False
80
+ rag_enabled: bool = False
81
+ consulted_experts: List[str] = Field(default_factory=list)
82
+ expert_reports: Dict[str, ExpertReport] = Field(default_factory=dict)
83
+ current_brief: Optional[Brief] = None
84
+ cumulative_reward: float = 0.0
ceo_brief_env/stooq_scrape.py ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Lightweight Stooq daily OHLCV fetch (HTTP GET of CSV) for RAG-advanced mode.
3
+
4
+ Not financial advice. For simulation / grounding only. Falls back to bundled fixtures
5
+ when offline or on error so CI and judges stay reproducible.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ import csv
10
+ import io
11
+ from pathlib import Path
12
+ from typing import List, Tuple
13
+ from urllib.error import HTTPError, URLError
14
+ from urllib.request import Request, urlopen
15
+
16
+ # Must match grader `STOOQ_CITATION_SUFFIXES`.
17
+ DEFAULT_WATCHLIST: tuple[str, ...] = ("nvda.us", "aapl.us", "jpm.us")
18
+
19
+ _STOOQ_DAILY = "https://stooq.com/q/d/l/?s={symbol}&i=d"
20
+ _USER_AGENT = "AutoDataLab-Plus/0.1 (research; +https://github.com/)"
21
+ _TIMEOUT_SEC = 8.0
22
+
23
+ _FIXTURES = Path(__file__).resolve().parent / "fixtures" / "stooq"
24
+ # Bundled multi-hundred-row daily history (Stooq-shaped) for Strategy when RAG is off
25
+ # (no network; used as “enterprise tape” context).
26
+ _LONG_FIXTURES = Path(__file__).resolve().parent / "fixtures" / "stooq_long"
27
+
28
+
29
+ def _parse_csv_tail(text: str, symbol: str, last_n: int = 3) -> str:
30
+ text = text.strip()
31
+ if not text or "Date" not in text:
32
+ return f"{symbol}: (no data)"
33
+ lines = [ln for ln in text.splitlines() if ln.strip()]
34
+ if len(lines) < 2:
35
+ return f"{symbol}: (no data)"
36
+ rdr = csv.reader(io.StringIO(text))
37
+ rows: List[list[str]] = list(rdr)
38
+ if not rows:
39
+ return f"{symbol}: (no data)"
40
+ header, *data = rows
41
+ if not data:
42
+ return f"{symbol}: (no data)"
43
+ tail = data[-last_n:]
44
+ parts = [f"Stooq {symbol} daily:"]
45
+ for row in tail:
46
+ if not row or row[0] == "No data":
47
+ continue
48
+ date = row[0]
49
+ try:
50
+ close = row[4] if len(row) > 4 else row[-1]
51
+ except IndexError:
52
+ close = "—"
53
+ parts.append(f" {date} close≈{close}")
54
+ return " ".join(parts) if len(parts) > 1 else f"{symbol}: (unparseable)"
55
+
56
+
57
+ def _read_fixture(symbol: str) -> str | None:
58
+ path = _FIXTURES / f"{symbol.replace('.', '_')}.csv"
59
+ if not path.is_file():
60
+ return None
61
+ try:
62
+ return path.read_text(encoding="utf-8", errors="replace")
63
+ except OSError:
64
+ return None
65
+
66
+
67
+ def _looks_like_stooq_csv(text: str) -> bool:
68
+ t = text.lstrip("\ufeff").strip()
69
+ if not t or "Date" not in t.splitlines()[0]:
70
+ return False
71
+ if "<html" in t.lower() or "<!doctype" in t.lower():
72
+ return False
73
+ return True
74
+
75
+
76
+ def fetch_stooq_daily_csv(symbol: str) -> str:
77
+ """Return raw CSV text from network or local fixture."""
78
+ url = _STOOQ_DAILY.format(symbol=symbol.lower())
79
+ req = Request(url, headers={"User-Agent": _USER_AGENT})
80
+ try:
81
+ with urlopen(req, timeout=_TIMEOUT_SEC) as resp:
82
+ raw = resp.read().decode("utf-8", errors="replace")
83
+ except (HTTPError, URLError, OSError, TimeoutError):
84
+ raw = ""
85
+ if not _looks_like_stooq_csv(raw):
86
+ fix = _read_fixture(symbol)
87
+ if fix is not None:
88
+ return fix
89
+ return "Date,Open,High,Low,Close,Volume\n"
90
+ return raw
91
+
92
+
93
+ def read_long_fixture_csv(symbol: str) -> str:
94
+ """Read the bundled long daily CSV for ``symbol`` (e.g. ``nvda.us``)."""
95
+ path = _LONG_FIXTURES / f"{symbol.replace('.', '_')}.csv"
96
+ if not path.is_file():
97
+ return "Date,Open,High,Low,Close,Volume\n"
98
+ try:
99
+ return path.read_text(encoding="utf-8", errors="replace")
100
+ except OSError:
101
+ return "Date,Open,High,Low,Close,Volume\n"
102
+
103
+
104
+ def scrape_watchlist_from_long_csv(
105
+ symbols: tuple[str, ...] = DEFAULT_WATCHLIST,
106
+ last_n: int = 5,
107
+ ) -> List[Tuple[str, str, str, int]]:
108
+ """
109
+ Like :func:`scrape_watchlist` but only reads local long CSVs (no HTTP).
110
+ Returns ``(stooq_symbol, citation, snippet, row_count_excl_header)``.
111
+ Citations use the same ``stooq:`` prefix so graders stay consistent if RAG is on elsewhere.
112
+ """
113
+ out: list[tuple[str, str, str, int]] = []
114
+ for sym in symbols:
115
+ raw = read_long_fixture_csv(sym)
116
+ rows = list(csv.reader(io.StringIO(raw)))
117
+ n_data = max(0, len(rows) - 1)
118
+ snip = _parse_csv_tail(raw, sym, last_n=last_n)
119
+ cite = f"stooq:{sym}"
120
+ out.append((sym, cite, snip, n_data))
121
+ return out
122
+
123
+
124
+ def scrape_watchlist(
125
+ symbols: tuple[str, ...] = DEFAULT_WATCHLIST,
126
+ ) -> List[Tuple[str, str, str]]:
127
+ """
128
+ For each symbol, fetch Stooq daily history and return
129
+ (stooq_symbol, citation, snippet) for RAG + grounding.
130
+
131
+ Citation format: ``stooq:nvda.us`` (used by ``graders.grounding_score``).
132
+ """
133
+ out: list[tuple[str, str, str]] = []
134
+ for sym in symbols:
135
+ raw = fetch_stooq_daily_csv(sym)
136
+ snip = _parse_csv_tail(raw, sym)
137
+ cite = f"stooq:{sym}"
138
+ out.append((sym, cite, snip))
139
+ return out
ceo_brief_env/tasks/_build_ground_truth.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ import sys
5
+ from pathlib import Path
6
+
7
+ import pandas as pd
8
+
9
+ REPO = Path(__file__).resolve().parents[2]
10
+ if str(REPO) not in sys.path:
11
+ sys.path.insert(0, str(REPO))
12
+
13
+ from ceo_brief_env.experts.data_analyst import DataAnalystExpert
14
+ from ceo_brief_env.experts.finance import FinanceExpert
15
+ from ceo_brief_env.experts.hr import HRExpert
16
+ from ceo_brief_env.experts.strategy import StrategyExpert
17
+
18
+ ROOT = Path(__file__).resolve().parent
19
+
20
+
21
+ def build_task(task_name: str) -> None:
22
+ task_dir = ROOT / task_name
23
+ raw_df = pd.read_csv(task_dir / 'raw.csv')
24
+ meta = json.loads((task_dir / 'metadata.json').read_text(encoding='utf-8'))
25
+ analyst = DataAnalystExpert().run(task_name, meta['instruction'], raw_df)
26
+ finance = FinanceExpert().run(task_name, meta['instruction'], raw_df, analyst.metrics, meta)
27
+ strategy = None
28
+ if 'strategy' in meta.get('required_experts', []):
29
+ strategy = StrategyExpert().run(task_name, meta, analyst, finance)
30
+ hr = HRExpert().run(task_name, meta, analyst, finance, strategy)
31
+ metrics = {
32
+ 'data_quality_score': analyst.metrics['data_quality_score'],
33
+ 'total_revenue': analyst.metrics['total_revenue'],
34
+ 'top_category': analyst.metrics['top_category'],
35
+ 'projection_next_quarter': finance.metrics['projection_next_quarter'],
36
+ 'variance_pct': finance.metrics['variance_pct'],
37
+ 'break_even_units': finance.metrics['break_even_units'],
38
+ 'memo_score': hr.metrics['memo_score'],
39
+ }
40
+ rows = [{'metric': k, 'value': v} for k, v in metrics.items()]
41
+ pd.DataFrame(rows).to_csv(task_dir / 'ground_truth.csv', index=False)
42
+
43
+
44
+ def main() -> int:
45
+ for task_dir in ROOT.iterdir():
46
+ if task_dir.is_dir() and task_dir.name.endswith('_brief'):
47
+ build_task(task_dir.name)
48
+ return 0
49
+
50
+
51
+ if __name__ == '__main__':
52
+ raise SystemExit(main())
ceo_brief_env/tasks/_widen_raw_to_400.py ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ Expand each */raw.csv to 400 columns: 8 business columns (used by the analyst
3
+ pipeline) + 392 wide-table \"enterprise context\" fields (unused by KPI math).
4
+
5
+ Re-run: python3 ceo_brief_env/tasks/_widen_raw_to_400.py
6
+ Then: python3 ceo_brief_env/tasks/_build_ground_truth.py
7
+ """
8
+ from __future__ import annotations
9
+
10
+ import json
11
+ import sys
12
+ from pathlib import Path
13
+
14
+ import numpy as np
15
+ import pandas as pd
16
+
17
+ ROOT = Path(__file__).resolve().parent
18
+ N_COLS = 400
19
+ CORE = [
20
+ "OrderID",
21
+ "CustomerID",
22
+ "ExpiryDays",
23
+ "Product",
24
+ "Category",
25
+ "Price",
26
+ "Quantity",
27
+ "OrderDate",
28
+ ]
29
+ N_EXTRA = N_COLS - len(CORE) # 392
30
+
31
+
32
+ def _wide_frame(df: pd.DataFrame, task_seed: int) -> pd.DataFrame:
33
+ """Append dim_0001..dim_0392 with reproducible pseudo-enterprise noise."""
34
+ n = len(df)
35
+ rng = np.random.default_rng(task_seed)
36
+ cols: dict[str, np.ndarray] = {}
37
+ for j in range(N_EXTRA):
38
+ col = f"dim_{j+1:04d}"
39
+ kind = j % 5
40
+ if kind == 0:
41
+ cols[col] = rng.integers(0, 2, size=n)
42
+ elif kind == 1:
43
+ cols[col] = rng.integers(1, 500, size=n)
44
+ elif kind == 2:
45
+ cols[col] = np.round(rng.random(n) * 100.0, 4)
46
+ elif kind == 3:
47
+ cols[col] = rng.integers(2018, 2025, size=n)
48
+ else:
49
+ cols[col] = (rng.integers(0, 1_000_000, size=n) // 1000).astype(np.int64)
50
+ extra = pd.DataFrame(cols, index=df.index)
51
+ return pd.concat([df.reset_index(drop=True), extra], axis=1)
52
+
53
+
54
+ def main() -> int:
55
+ for task_dir in sorted(ROOT.iterdir()):
56
+ if not task_dir.is_dir() or not str(task_dir.name).endswith("_brief"):
57
+ continue
58
+ p = task_dir / "raw.csv"
59
+ if not p.exists():
60
+ continue
61
+ task_name = task_dir.name
62
+ seed = int.from_bytes(task_name.encode(), "big") % (2**31)
63
+ df = pd.read_csv(p)
64
+ # Keep only core columns if re-run on already-wide file
65
+ if len(df.columns) > len(CORE):
66
+ core_present = [c for c in CORE if c in df.columns]
67
+ df = df[core_present]
68
+ missing = [c for c in CORE if c not in df.columns]
69
+ if missing:
70
+ print(f"skip {task_name}: missing columns {missing}", file=sys.stderr)
71
+ continue
72
+ df = df[[c for c in CORE if c in df.columns]]
73
+ assert len(df.columns) == len(CORE)
74
+ wide = _wide_frame(df, seed)
75
+ if len(wide.columns) != N_COLS:
76
+ print(f"column count {len(wide.columns)} != {N_COLS}", file=sys.stderr)
77
+ return 1
78
+ wide.to_csv(p, index=False)
79
+ print(f"wrote {p} rows={len(wide)} cols={len(wide.columns)}", flush=True)
80
+ return 0
81
+
82
+
83
+ if __name__ == "__main__":
84
+ raise SystemExit(main())
ceo_brief_env/tasks/crisis_brief/ground_truth.csv ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ metric,value
2
+ data_quality_score,0.9167
3
+ total_revenue,282600.0
4
+ top_category,Electronics
5
+ projection_next_quarter,-70800.0
6
+ variance_pct,101.86
7
+ break_even_units,26.67
8
+ memo_score,0.6805
ceo_brief_env/tasks/crisis_brief/metadata.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "title": "Crisis brief — mid-quarter shock with hiring freeze",
3
+ "difficulty": "hard",
4
+ "max_steps": 14,
5
+ "instruction": "A mid-quarter shock has put the operating plan well behind expectation. Run the full office: tight data quality read, finance variance and break-even sensitivity, defensive strategy on NVDA/AAPL/JPM, and an HR memo that names the variance, the projection path, and the strategy stance. Be conservative: prefer holds/trims unless evidence supports otherwise.",
6
+ "required_experts": [
7
+ "analyst",
8
+ "finance",
9
+ "strategy",
10
+ "hr"
11
+ ],
12
+ "memo_audience": "CEO, CFO, COO",
13
+ "hr_required_terms": [
14
+ "variance",
15
+ "projection",
16
+ "strategy",
17
+ "break-even"
18
+ ],
19
+ "plan_value": 140000,
20
+ "fixed_cost": 48000,
21
+ "unit_margin": 1800
22
+ }
ceo_brief_env/tasks/crisis_brief/raw.csv ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ OrderID,CustomerID,ExpiryDays,Product,Category,Price,Quantity,OrderDate,dim_0001,dim_0002,dim_0003,dim_0004,dim_0005,dim_0006,dim_0007,dim_0008,dim_0009,dim_0010,dim_0011,dim_0012,dim_0013,dim_0014,dim_0015,dim_0016,dim_0017,dim_0018,dim_0019,dim_0020,dim_0021,dim_0022,dim_0023,dim_0024,dim_0025,dim_0026,dim_0027,dim_0028,dim_0029,dim_0030,dim_0031,dim_0032,dim_0033,dim_0034,dim_0035,dim_0036,dim_0037,dim_0038,dim_0039,dim_0040,dim_0041,dim_0042,dim_0043,dim_0044,dim_0045,dim_0046,dim_0047,dim_0048,dim_0049,dim_0050,dim_0051,dim_0052,dim_0053,dim_0054,dim_0055,dim_0056,dim_0057,dim_0058,dim_0059,dim_0060,dim_0061,dim_0062,dim_0063,dim_0064,dim_0065,dim_0066,dim_0067,dim_0068,dim_0069,dim_0070,dim_0071,dim_0072,dim_0073,dim_0074,dim_0075,dim_0076,dim_0077,dim_0078,dim_0079,dim_0080,dim_0081,dim_0082,dim_0083,dim_0084,dim_0085,dim_0086,dim_0087,dim_0088,dim_0089,dim_0090,dim_0091,dim_0092,dim_0093,dim_0094,dim_0095,dim_0096,dim_0097,dim_0098,dim_0099,dim_0100,dim_0101,dim_0102,dim_0103,dim_0104,dim_0105,dim_0106,dim_0107,dim_0108,dim_0109,dim_0110,dim_0111,dim_0112,dim_0113,dim_0114,dim_0115,dim_0116,dim_0117,dim_0118,dim_0119,dim_0120,dim_0121,dim_0122,dim_0123,dim_0124,dim_0125,dim_0126,dim_0127,dim_0128,dim_0129,dim_0130,dim_0131,dim_0132,dim_0133,dim_0134,dim_0135,dim_0136,dim_0137,dim_0138,dim_0139,dim_0140,dim_0141,dim_0142,dim_0143,dim_0144,dim_0145,dim_0146,dim_0147,dim_0148,dim_0149,dim_0150,dim_0151,dim_0152,dim_0153,dim_0154,dim_0155,dim_0156,dim_0157,dim_0158,dim_0159,dim_0160,dim_0161,dim_0162,dim_0163,dim_0164,dim_0165,dim_0166,dim_0167,dim_0168,dim_0169,dim_0170,dim_0171,dim_0172,dim_0173,dim_0174,dim_0175,dim_0176,dim_0177,dim_0178,dim_0179,dim_0180,dim_0181,dim_0182,dim_0183,dim_0184,dim_0185,dim_0186,dim_0187,dim_0188,dim_0189,dim_0190,dim_0191,dim_0192,dim_0193,dim_0194,dim_0195,dim_0196,dim_0197,dim_0198,dim_0199,dim_0200,dim_0201,dim_0202,dim_0203,dim_0204,dim_0205,dim_0206,dim_0207,dim_0208,dim_0209,dim_0210,dim_0211,dim_0212,dim_0213,dim_0214,dim_0215,dim_0216,dim_0217,dim_0218,dim_0219,dim_0220,dim_0221,dim_0222,dim_0223,dim_0224,dim_0225,dim_0226,dim_0227,dim_0228,dim_0229,dim_0230,dim_0231,dim_0232,dim_0233,dim_0234,dim_0235,dim_0236,dim_0237,dim_0238,dim_0239,dim_0240,dim_0241,dim_0242,dim_0243,dim_0244,dim_0245,dim_0246,dim_0247,dim_0248,dim_0249,dim_0250,dim_0251,dim_0252,dim_0253,dim_0254,dim_0255,dim_0256,dim_0257,dim_0258,dim_0259,dim_0260,dim_0261,dim_0262,dim_0263,dim_0264,dim_0265,dim_0266,dim_0267,dim_0268,dim_0269,dim_0270,dim_0271,dim_0272,dim_0273,dim_0274,dim_0275,dim_0276,dim_0277,dim_0278,dim_0279,dim_0280,dim_0281,dim_0282,dim_0283,dim_0284,dim_0285,dim_0286,dim_0287,dim_0288,dim_0289,dim_0290,dim_0291,dim_0292,dim_0293,dim_0294,dim_0295,dim_0296,dim_0297,dim_0298,dim_0299,dim_0300,dim_0301,dim_0302,dim_0303,dim_0304,dim_0305,dim_0306,dim_0307,dim_0308,dim_0309,dim_0310,dim_0311,dim_0312,dim_0313,dim_0314,dim_0315,dim_0316,dim_0317,dim_0318,dim_0319,dim_0320,dim_0321,dim_0322,dim_0323,dim_0324,dim_0325,dim_0326,dim_0327,dim_0328,dim_0329,dim_0330,dim_0331,dim_0332,dim_0333,dim_0334,dim_0335,dim_0336,dim_0337,dim_0338,dim_0339,dim_0340,dim_0341,dim_0342,dim_0343,dim_0344,dim_0345,dim_0346,dim_0347,dim_0348,dim_0349,dim_0350,dim_0351,dim_0352,dim_0353,dim_0354,dim_0355,dim_0356,dim_0357,dim_0358,dim_0359,dim_0360,dim_0361,dim_0362,dim_0363,dim_0364,dim_0365,dim_0366,dim_0367,dim_0368,dim_0369,dim_0370,dim_0371,dim_0372,dim_0373,dim_0374,dim_0375,dim_0376,dim_0377,dim_0378,dim_0379,dim_0380,dim_0381,dim_0382,dim_0383,dim_0384,dim_0385,dim_0386,dim_0387,dim_0388,dim_0389,dim_0390,dim_0391,dim_0392
2
+ 601,C300,30,Workstation,Electronics,98000.0,1.0,2024-01-07,1,29,11.2991,2024,570,1,50,81.1799,2023,469,1,398,35.0699,2024,482,1,34,76.8981,2020,913,1,301,49.0841,2019,311,0,404,87.1558,2018,700,1,490,47.5491,2023,213,0,403,17.7827,2022,882,1,40,2.8595,2021,337,0,108,35.8678,2018,173,0,187,11.7391,2021,984,0,218,76.582,2023,619,0,207,7.1317,2020,75,0,480,9.2095,2023,602,0,104,2.6198,2023,945,0,400,24.3749,2022,413,0,123,72.9151,2024,757,0,70,77.7896,2023,787,1,484,79.7165,2023,877,0,111,68.4621,2019,984,1,488,44.3529,2022,647,1,344,36.5666,2024,436,0,199,45.5387,2021,749,1,434,64.7971,2021,535,1,60,22.1585,2019,596,0,267,46.6497,2019,27,1,154,78.7417,2023,205,1,329,54.2622,2021,31,0,73,31.2542,2018,847,1,235,92.122,2021,555,1,246,95.9976,2021,737,0,104,83.7357,2018,583,1,268,13.6289,2021,742,1,52,16.7124,2018,243,1,302,10.2863,2019,510,0,93,92.223,2024,860,1,243,98.1271,2022,827,0,485,18.6065,2021,861,1,269,0.2961,2018,751,0,344,29.387,2021,145,1,200,98.955,2024,112,1,437,34.2847,2020,429,1,485,64.8237,2020,551,1,231,63.1177,2019,631,1,241,7.9994,2018,846,1,373,18.1263,2022,878,0,224,3.7138,2019,504,1,315,80.1548,2023,167,0,246,18.9959,2023,274,1,84,31.0602,2022,863,0,139,89.972,2022,567,1,215,84.2751,2018,465,1,74,77.668,2020,998,0,364,51.6699,2018,107,0,253,18.1034,2022,884,1,114,57.335,2023,856,0,340,78.0612,2022,507,1,128,86.0943,2018,240,0,343,93.8413,2019,537,1,389,3.1262,2024,377,1,393,68.1358,2022,293,0,229,52.2671,2020,601,1,81,71.0462,2023,610,0,257,71.6916,2018,764,1,6,83.0219,2019,739,0,364,49.1545,2018,521,1,146,38.7768,2023,903,1,86,48.2355,2023,478,0,10,60.0645,2021,558,0,49,51.997,2023,544,0,30,68.7592,2018,131,1,101,91.4483,2023,878,0,486,88.0248,2021,599,1,255,67.7937,2019,92,1,42,6.0513,2023,403,0,336,92.4016,2019,585,0,199,71.6468,2018,0,0,31,46.115,2023,963,0,385
3
+ 602,C301,45,Phone,Electronics,42000.0,1.0,2024-01-19,0,47,42.714,2022,388,1,439,23.88,2023,709,0,229,99.5758,2019,551,1,397,39.5286,2019,210,1,49,0.5169,2023,86,1,120,23.3109,2020,477,1,128,71.8955,2023,922,1,296,46.6067,2021,11,0,22,44.3949,2021,69,1,10,56.5891,2018,529,1,82,54.0554,2020,484,1,372,41.1074,2020,447,0,384,4.2352,2021,352,0,61,85.8191,2019,861,0,183,94.536,2019,198,1,163,47.4782,2021,688,0,249,32.0634,2022,119,0,394,66.1202,2024,356,1,105,91.4205,2024,602,0,75,56.426,2021,618,1,349,68.7099,2018,689,0,148,38.807,2020,35,1,98,46.647,2020,100,1,36,39.199,2024,662,0,98,45.8999,2024,419,0,18,2.7541,2019,886,1,187,69.9959,2018,15,0,451,78.0545,2019,906,1,231,4.3398,2024,734,0,203,44.1864,2024,758,1,479,31.4024,2018,251,1,115,24.5504,2024,925,1,256,34.494,2018,428,0,372,91.0575,2020,52,1,206,31.6637,2023,825,0,94,7.1261,2024,36,1,200,31.7797,2020,354,1,313,14.6798,2020,931,1,269,46.5135,2022,450,1,331,60.4155,2018,377,1,357,79.7807,2021,595,0,451,90.5237,2020,100,0,87,20.6699,2023,620,1,395,6.0762,2024,697,0,420,18.3574,2024,507,0,459,46.4478,2023,809,0,316,62.3586,2018,186,0,99,55.6374,2020,818,1,38,56.7895,2021,882,0,342,43.1359,2019,70,0,285,50.5273,2018,918,1,277,15.4151,2022,129,0,394,1.632,2018,584,0,66,10.4551,2022,999,0,370,97.1911,2021,931,1,356,50.9879,2019,139,1,114,6.1589,2019,250,1,34,29.8372,2021,410,0,387,13.5284,2020,138,0,43,98.7983,2023,622,0,184,0.75,2019,991,1,291,57.1036,2021,762,1,325,66.3414,2023,951,0,386,20.4953,2021,55,0,66,20.6337,2019,412,0,214,83.608,2020,167,0,12,93.8023,2023,18,0,70,5.5315,2024,942,1,350,61.1375,2018,304,0,329,46.1645,2021,183,0,111,58.3231,2021,29,0,215,14.455,2020,219,0,329,19.4221,2019,323,1,443,40.7827,2023,42,1,170,15.199,2021,580,1,273,79.2681,2020,378,1,398,80.2092,2021,740,1,185,98.3139,2021,444,0,220
4
+ 603,C302,60,Headphones,Electronics,7900.0,1.0,2024-02-02,1,162,89.2765,2022,442,0,473,74.9081,2023,335,1,53,70.9068,2019,583,1,108,8.2629,2019,982,0,383,18.4114,2020,843,1,269,15.2606,2024,638,0,478,50.1232,2021,625,1,55,12.2749,2023,556,1,104,94.3254,2021,461,0,436,62.1067,2021,88,0,453,63.8216,2021,431,0,282,79.5521,2023,542,1,278,14.6176,2018,143,1,256,33.4572,2018,470,0,421,16.3202,2023,160,0,52,97.5301,2021,651,1,328,88.0274,2021,719,1,250,0.2501,2018,666,1,349,35.597,2023,523,1,279,97.0134,2020,98,1,382,92.4716,2021,862,1,115,5.2908,2023,60,1,387,74.2714,2022,621,0,154,41.3644,2023,135,1,284,92.996,2018,978,1,198,38.6482,2019,982,0,218,86.1945,2023,768,1,220,37.7807,2020,263,1,351,66.6189,2018,339,1,423,66.4048,2024,821,1,41,41.3513,2018,221,1,96,88.633,2019,968,1,499,36.1479,2020,724,1,381,49.5031,2024,555,1,67,75.8066,2022,844,0,256,69.888,2022,694,1,204,68.7238,2022,154,1,222,3.2801,2018,395,0,377,3.889,2023,220,1,21,68.6911,2024,151,0,162,74.0095,2018,778,1,135,61.5566,2022,203,0,388,42.4485,2019,850,1,297,53.4918,2019,249,1,221,6.7502,2020,525,1,192,66.525,2024,639,1,1,55.1035,2022,819,0,168,86.86,2024,436,1,456,42.8609,2020,562,0,496,24.9022,2019,960,0,289,68.7651,2020,366,1,166,39.3911,2018,80,0,260,89.0157,2024,202,0,194,42.2193,2018,396,1,165,97.1287,2019,866,1,220,54.5223,2022,826,1,461,29.1912,2019,737,0,31,27.4888,2021,369,0,498,66.5258,2018,523,1,332,46.2714,2024,938,0,67,74.6614,2020,79,1,333,69.2029,2018,545,1,124,46.8531,2022,896,0,13,80.1894,2019,962,1,149,72.5293,2023,210,0,399,26.3104,2019,959,0,395,71.4436,2020,350,0,81,28.6851,2024,461,0,478,80.0292,2020,402,0,495,37.5534,2021,718,0,343,46.0989,2019,367,0,399,13.4429,2019,806,1,439,53.7388,2018,702,1,196,72.4649,2021,393,1,45,10.256,2019,295,1,167,71.4386,2020,179,0,43,24.2341,2022,798,0,156,57.7549,2018,19,0,452
5
+ 604,C303,30,Camera,Electronics,41000.0,1.0,2024-02-13,1,265,71.8898,2018,336,1,98,88.4471,2023,961,1,456,94.725,2023,907,1,367,93.0463,2022,787,1,404,4.7322,2022,214,0,317,30.0124,2022,595,0,19,59.5029,2023,721,1,86,5.7787,2023,30,1,14,80.266,2022,826,0,96,37.1809,2022,274,0,268,84.2711,2019,411,1,404,43.2429,2020,485,1,219,34.2227,2019,267,0,138,78.0429,2018,746,1,142,44.134,2022,993,0,235,7.0395,2020,258,1,129,64.9228,2024,182,1,342,44.0091,2023,197,1,362,62.7104,2020,224,0,353,56.5413,2020,226,0,461,38.0537,2020,80,1,136,64.1519,2021,398,0,132,89.0276,2020,713,0,215,68.9897,2022,966,1,290,62.9747,2021,134,1,246,60.1625,2023,165,1,284,19.5553,2020,127,1,77,9.4002,2024,379,1,172,2.0021,2018,313,0,187,44.2648,2018,440,1,148,65.3153,2023,961,0,96,88.6686,2018,948,1,427,0.4257,2020,36,1,193,97.9875,2019,805,0,279,83.0474,2018,552,0,468,16.2863,2022,929,0,488,34.4021,2023,504,1,181,84.9543,2024,52,0,40,79.5751,2020,262,1,190,13.2315,2023,831,0,404,9.3724,2022,654,1,86,13.9261,2018,312,0,300,85.8559,2019,510,1,355,77.0651,2019,935,1,260,84.5444,2020,314,1,212,90.4273,2019,376,1,137,9.7238,2020,722,1,74,52.4767,2019,181,1,219,54.3066,2021,716,1,402,4.1763,2018,126,0,373,5.7149,2018,65,0,358,59.4006,2019,65,0,448,36.744,2018,298,0,57,6.3114,2018,671,0,263,2.1276,2023,142,0,397,48.5795,2022,48,0,313,17.4253,2022,660,1,414,6.2271,2024,791,0,289,73.2198,2023,823,0,56,14.5921,2021,672,1,389,41.8046,2019,708,1,466,19.7705,2021,489,0,479,81.2941,2019,341,0,135,66.541,2022,497,0,277,39.9045,2024,732,0,89,9.289,2018,141,1,327,50.7167,2024,759,1,61,58.6488,2018,551,1,26,46.5216,2020,788,1,219,63.8497,2019,620,1,225,99.5888,2021,941,1,172,56.8707,2024,495,0,424,74.1335,2024,905,0,179,77.6533,2018,433,0,311,31.1968,2021,914,1,170,27.8721,2020,735,0,364,11.9546,2023,913,0,397,44.7967,2022,966,1,16
6
+ 605,C304,30,Tablet,Electronics,30500.0,,2024-02-25,0,326,6.9968,2021,611,1,415,32.0166,2024,554,0,320,25.1378,2021,647,1,100,54.2937,2019,997,1,18,54.8351,2018,690,0,171,88.5219,2024,133,1,265,10.2271,2022,218,1,260,11.0745,2020,761,1,417,2.3196,2022,50,1,197,55.1762,2023,69,1,85,19.8423,2020,859,0,414,86.7129,2023,466,0,355,62.7176,2020,522,1,235,43.842,2018,817,1,92,44.3295,2023,571,1,24,39.7175,2018,961,1,103,1.8432,2020,333,0,199,80.7418,2021,581,0,164,30.9832,2022,646,1,298,0.1635,2020,249,1,273,69.1898,2018,51,0,122,21.2284,2021,401,1,88,94.0439,2024,959,1,219,74.1111,2022,645,1,231,92.3911,2022,828,1,205,88.9204,2020,747,1,424,61.6248,2023,635,0,388,29.5128,2018,162,0,356,83.6259,2024,817,0,114,85.6201,2021,133,0,461,11.9734,2023,836,1,189,36.818,2020,655,1,153,83.7223,2018,32,0,161,63.3442,2023,308,1,107,58.7303,2021,731,1,288,44.5737,2023,601,1,75,10.9557,2023,846,1,273,46.9717,2019,996,0,430,12.0217,2021,692,0,6,32.952,2018,871,1,33,9.3636,2020,757,0,313,3.2618,2020,363,1,51,93.964,2018,444,0,111,28.0697,2021,585,1,465,94.2951,2020,725,1,345,45.4705,2019,200,1,407,20.1806,2023,922,0,130,45.487,2023,156,1,64,29.3621,2021,361,0,496,39.7893,2018,607,0,191,24.8653,2021,749,0,422,7.1596,2024,349,0,132,24.5381,2018,4,1,391,24.3354,2024,873,1,131,36.8383,2023,235,1,434,9.7381,2018,86,0,122,40.1331,2018,400,1,248,98.9428,2021,836,1,105,81.3327,2020,844,0,275,48.61,2022,587,0,272,16.9499,2021,274,1,148,63.7686,2023,86,0,408,43.9928,2018,271,0,97,80.2777,2018,832,0,289,24.0179,2024,598,1,204,97.1628,2019,486,0,275,73.7156,2020,708,0,256,17.6641,2024,473,0,459,51.7645,2022,156,0,71,19.7144,2020,459,0,231,33.6317,2018,507,0,494,44.7828,2019,63,0,113,69.0979,2022,154,1,405,53.1931,2018,966,0,45,6.5847,2020,650,0,325,35.3675,2020,674,0,413,63.8429,2024,519,1,12,24.9617,2021,230,1,449
7
+ 606,C305,45,Serum,Beauty,1300.0,2.0,2024-03-07,1,34,45.6125,2020,830,0,41,90.2784,2019,48,1,474,89.2955,2021,735,0,25,24.3007,2024,45,0,130,31.8463,2024,549,1,468,33.7572,2021,919,1,294,36.4716,2018,110,1,388,86.6995,2019,713,0,411,62.6685,2021,512,1,345,80.2094,2020,889,1,236,39.1209,2023,557,0,256,7.3639,2019,371,0,248,98.0003,2018,710,1,241,99.422,2023,199,1,169,72.3343,2021,125,1,209,45.1824,2022,19,0,499,79.1581,2024,540,1,267,94.8339,2019,536,0,234,40.2764,2024,260,1,202,54.6238,2022,542,1,96,67.1621,2021,983,1,466,68.2438,2023,463,0,129,81.5038,2022,909,1,496,47.6105,2018,396,0,141,19.3653,2021,198,0,5,0.4034,2024,778,0,158,38.7775,2024,61,0,148,56.7554,2022,883,0,147,86.1987,2019,821,0,400,15.8295,2022,831,0,67,4.6801,2023,583,0,160,26.8546,2022,322,1,294,32.9468,2020,82,1,180,62.9521,2022,716,1,250,96.6011,2023,456,0,189,12.0439,2021,492,0,17,78.8695,2020,303,0,142,11.3961,2020,290,0,404,62.6016,2022,72,1,5,83.4673,2020,278,1,228,61.3194,2019,546,1,418,17.7742,2024,644,0,331,14.4934,2018,934,1,220,65.5122,2020,428,0,21,71.4861,2023,835,1,43,3.1781,2018,227,1,323,67.1978,2022,807,1,429,75.0757,2023,622,1,383,10.9511,2018,236,0,59,30.7807,2023,459,0,397,93.1844,2023,140,0,448,91.817,2020,764,1,95,42.9711,2019,90,1,161,69.223,2018,741,1,317,80.4519,2023,126,0,326,32.5647,2024,337,1,498,74.0223,2022,522,1,111,43.5206,2018,507,0,156,1.336,2019,185,0,224,64.7166,2022,833,1,250,52.3901,2022,924,1,113,68.1389,2021,13,0,280,4.7899,2019,174,0,178,91.6959,2021,336,1,382,14.2737,2024,437,0,434,88.7794,2024,186,1,277,96.3444,2022,697,1,53,53.584,2024,272,0,195,88.535,2019,108,0,277,3.8178,2023,673,1,239,53.2048,2018,287,1,450,25.8803,2022,820,0,306,28.9628,2020,124,1,234,57.2559,2018,813,0,13,84.3891,2019,428,0,311,36.2306,2019,364,1,67,75.298,2021,140,1,436,57.1664,2023,785,1,26
8
+ 607,C306,60,Desk,Home,12500.0,1.0,2024-03-18,0,345,53.8047,2022,804,0,253,33.0549,2019,44,1,79,22.5355,2020,355,1,377,62.2929,2021,422,0,70,80.0632,2022,545,1,173,50.0556,2024,2,0,97,1.6601,2022,665,1,187,54.262,2023,951,0,426,52.6644,2021,551,1,311,97.2634,2021,138,1,224,19.2569,2022,147,0,72,80.7577,2022,918,1,104,8.4668,2018,122,1,49,63.8585,2021,100,1,466,23.732,2024,895,0,494,23.6486,2020,198,1,197,77.2568,2018,326,0,226,65.3289,2023,647,1,82,86.3155,2024,292,1,151,66.6084,2022,959,0,378,45.3949,2018,424,1,246,94.8786,2018,859,0,464,86.5524,2023,793,1,206,85.1208,2022,92,0,353,91.7173,2019,565,1,345,6.7008,2020,499,0,211,73.9902,2022,359,1,417,98.8436,2023,592,1,408,54.5499,2019,90,0,245,91.0177,2024,274,1,158,27.5686,2023,279,1,106,70.9682,2023,997,0,299,72.2503,2024,815,1,230,43.0567,2018,277,0,121,30.1199,2020,429,0,31,93.3484,2023,575,1,62,53.1013,2020,599,0,467,79.9392,2024,511,1,273,2.2151,2021,545,0,352,12.463,2023,755,0,441,55.8703,2019,461,1,414,83.714,2019,676,0,90,87.0907,2019,315,0,262,63.1309,2018,772,0,336,45.0808,2022,402,1,130,32.6755,2024,152,1,31,27.8969,2020,398,0,367,66.4586,2022,256,1,189,69.9446,2024,687,0,197,44.6948,2022,529,0,470,13.8614,2024,914,0,139,9.179,2023,536,0,291,96.6608,2021,85,1,348,54.4408,2020,650,0,368,14.9704,2021,841,1,39,98.6302,2020,59,0,23,30.4665,2018,532,1,404,24.1201,2022,200,1,105,7.258,2023,259,0,22,33.6908,2021,940,1,167,24.4553,2020,650,0,108,51.1963,2019,735,1,237,49.5187,2023,417,0,490,31.9363,2019,499,0,79,18.7186,2018,612,0,379,7.7791,2020,505,0,392,61.4556,2018,785,0,399,77.1285,2019,34,0,400,55.4015,2021,779,0,29,89.2132,2020,497,0,430,4.7329,2021,775,0,297,40.4557,2023,170,1,158,48.8236,2022,690,1,278,2.814,2024,435,0,39,70.3749,2019,567,1,247,34.3636,2020,721,0,28,6.5223,2023,506,1,371,49.2449,2019,579,0,268
9
+ 608,C307,30,Monitor,Electronics,18500.0,1.0,2024-04-04,0,28,81.0418,2019,329,1,498,26.2027,2018,266,1,423,70.1049,2021,140,0,209,6.8436,2024,969,0,278,41.0682,2020,121,1,167,40.8495,2024,996,1,117,28.2872,2019,114,0,477,41.7888,2022,110,1,43,12.8289,2018,497,0,453,39.3874,2023,626,0,480,88.3355,2019,648,0,168,9.4579,2021,614,0,158,56.0907,2019,58,0,194,53.0077,2022,737,0,395,55.5247,2021,901,0,30,17.7533,2024,457,1,312,83.9569,2020,866,0,211,10.5889,2019,757,1,177,73.1204,2022,589,0,384,62.1249,2019,684,1,314,34.0848,2024,892,0,441,10.3404,2021,255,0,70,97.9444,2021,419,1,327,14.9061,2024,860,1,163,46.0826,2021,995,0,437,38.0631,2021,273,1,339,98.7845,2021,311,1,191,46.2244,2020,78,0,403,41.9937,2019,354,0,121,80.8868,2020,191,1,381,87.1074,2024,532,1,465,71.488,2024,110,0,92,42.7386,2024,468,0,137,67.7976,2019,342,0,350,6.3912,2024,600,1,318,8.9182,2021,918,1,294,4.7646,2021,632,0,382,30.6837,2020,735,0,424,24.1036,2021,572,1,474,19.2626,2020,713,0,1,16.7838,2020,696,0,495,31.3454,2019,162,1,121,63.3282,2019,941,1,187,71.3009,2023,527,0,418,47.3461,2024,547,0,324,47.9481,2023,238,1,488,20.9736,2018,479,0,52,49.8454,2019,825,0,57,72.1301,2021,202,0,12,30.3385,2021,104,1,290,58.5497,2022,119,1,238,94.3822,2022,465,1,4,56.6079,2023,410,0,266,52.7364,2018,568,1,19,24.1914,2018,955,1,138,41.3301,2021,190,0,337,5.0866,2021,304,1,346,58.6776,2024,503,1,27,61.9477,2024,180,1,213,7.9824,2018,910,1,353,1.6168,2023,270,1,317,4.7318,2021,323,1,471,1.5135,2019,993,0,399,43.0371,2022,487,1,211,7.0348,2023,433,0,63,79.4095,2021,310,1,128,41.357,2024,578,1,265,66.0135,2019,585,1,134,97.1917,2021,526,0,10,53.2297,2024,761,0,204,0.6791,2020,372,1,318,85.7888,2021,715,1,457,46.2532,2024,846,1,288,28.4242,2023,302,1,236,98.0117,2022,149,1,368,74.8703,2018,502,0,195,34.3001,2018,203,1,17,61.6395,2022,715,0,336
10
+ 609,C308,75,Shoes,Fashion,3200.0,2.0,2024-04-15,0,175,47.8909,2021,202,1,200,87.079,2021,457,0,477,63.5543,2019,250,0,425,50.7921,2018,251,1,140,18.531,2024,463,1,62,23.7837,2018,866,1,283,63.5852,2018,346,0,182,51.6689,2018,303,0,315,5.8712,2021,37,0,275,47.6738,2019,98,1,213,33.3327,2019,840,1,258,1.7105,2018,346,0,196,1.4748,2018,290,0,397,69.0669,2022,932,0,147,88.4798,2019,777,0,261,97.003,2024,819,1,268,50.5681,2024,515,0,456,81.5716,2022,624,0,299,69.8387,2024,791,0,231,16.0837,2020,943,1,426,0.4444,2022,977,1,309,48.7493,2019,879,1,104,30.4319,2020,653,0,378,76.6094,2019,137,1,68,61.5046,2022,25,0,480,67.6713,2020,494,1,17,96.8785,2022,736,0,167,72.2481,2022,747,0,498,66.0362,2024,618,1,192,64.6547,2022,58,1,122,73.3119,2018,725,0,70,56.1347,2023,588,1,377,81.9548,2018,119,1,308,7.2491,2018,303,0,93,91.2426,2019,819,0,154,51.0652,2023,120,1,249,35.6257,2018,166,0,469,22.5172,2023,953,1,289,52.5254,2023,495,1,418,19.1392,2024,877,1,372,48.4309,2023,263,0,244,21.549,2023,153,0,270,26.1433,2018,20,1,212,12.3694,2018,538,1,476,41.3417,2023,658,0,317,82.8539,2022,555,1,26,25.5726,2018,893,0,329,85.4137,2018,856,1,190,3.9267,2021,915,0,476,93.9418,2018,928,1,233,52.0063,2023,243,0,466,84.561,2018,312,0,56,3.6933,2022,743,0,214,31.2558,2024,343,0,104,68.1593,2024,567,0,18,4.8924,2018,727,0,233,84.0284,2022,730,0,41,14.0718,2018,756,0,485,33.3656,2024,425,0,175,89.6337,2023,281,1,387,46.8855,2020,63,1,406,3.8396,2024,384,0,484,10.7994,2019,985,1,433,41.9599,2019,150,0,71,11.2811,2019,934,1,191,56.3049,2023,50,0,10,10.3323,2019,995,0,291,67.7881,2018,356,0,402,41.1253,2023,493,1,93,28.884,2020,351,1,222,23.0337,2021,753,1,312,39.0545,2019,831,0,107,1.498,2023,185,0,298,71.996,2023,885,1,333,32.0281,2023,799,1,358,69.2373,2021,22,1,29,27.2678,2021,261,1,292,85.948,2024,673,1,317
11
+ 610,C309,90,Keyboard,Electronics,3700.0,1.0,2024-04-28,1,377,36.3951,2018,559,1,82,88.6105,2022,874,1,356,61.5928,2022,58,1,56,76.6528,2023,771,0,356,91.2929,2018,223,0,426,84.918,2024,918,1,233,12.7016,2020,679,0,455,59.6133,2024,379,1,454,3.9599,2021,530,1,169,2.2761,2022,76,1,165,84.3403,2023,243,1,206,64.0305,2022,256,1,353,86.6067,2022,983,1,166,35.3545,2022,958,1,397,94.8278,2021,416,1,85,2.8694,2021,868,0,38,76.396,2018,799,0,475,25.3447,2021,481,1,421,65.0742,2023,942,0,460,94.3213,2021,11,0,36,73.0891,2023,953,1,60,22.1366,2024,155,1,347,19.9297,2022,160,1,287,22.6341,2022,546,0,156,87.2321,2022,748,1,202,13.4762,2022,15,0,379,5.5991,2018,277,1,448,60.948,2022,921,1,64,61.4745,2019,738,1,126,7.2064,2020,270,0,323,87.3784,2021,86,1,364,43.203,2021,64,0,449,87.2666,2024,589,0,316,34.6785,2021,652,1,393,66.5856,2021,660,1,384,5.7473,2021,113,0,98,79.2803,2024,555,0,359,83.4134,2023,904,0,495,88.8027,2022,42,0,453,93.4389,2021,151,0,86,76.0442,2018,263,0,103,2.7304,2019,174,0,270,68.4925,2019,557,1,167,97.1451,2019,467,0,199,46.1039,2020,254,1,128,68.0284,2021,95,1,298,88.7513,2023,117,1,422,27.1523,2021,293,0,424,80.4072,2019,749,0,46,81.709,2021,768,1,68,48.6141,2020,392,0,193,12.8098,2022,389,1,45,67.9927,2020,687,1,56,65.9521,2024,991,0,121,62.7859,2020,449,1,261,87.688,2019,541,1,105,61.8234,2023,43,1,396,14.6636,2022,920,1,195,24.6699,2024,632,0,417,76.7522,2018,422,1,18,91.2658,2020,635,0,124,7.7524,2019,914,0,398,67.0776,2019,103,0,89,99.2569,2019,549,1,338,74.9316,2021,92,0,272,50.1049,2021,77,0,156,44.5596,2023,692,0,167,48.6705,2020,763,0,94,15.8735,2019,349,1,431,3.4488,2024,660,0,405,82.7042,2019,264,0,428,49.8136,2019,338,0,209,57.9633,2020,606,0,158,80.1876,2024,664,0,100,67.1782,2023,196,1,283,47.4361,2018,716,1,320,45.8388,2023,777,1,290,7.3426,2022,771,0,383
12
+ 611,C310,30,Phone,Electronics,42000.0,1.0,2024-05-09,0,272,91.1024,2023,609,1,389,53.5688,2023,754,0,416,28.2974,2024,983,1,40,63.3961,2018,861,1,123,53.4032,2021,504,1,432,96.1176,2018,66,1,288,31.6162,2021,260,0,215,6.1848,2018,581,0,111,89.3017,2021,303,1,410,9.7654,2019,690,1,173,29.1723,2023,359,0,188,15.7017,2018,921,1,375,66.0324,2023,979,0,413,2.0443,2023,967,0,28,22.7686,2020,7,1,38,23.1003,2021,747,1,183,0.4943,2018,628,1,393,58.1929,2023,122,1,498,62.4852,2024,727,1,154,10.8294,2023,69,1,264,97.5929,2023,529,0,61,65.6891,2024,910,0,430,64.2018,2019,51,0,178,28.9301,2022,235,1,158,73.1798,2022,689,0,147,31.5309,2024,63,0,403,68.8166,2023,559,0,332,30.0548,2024,825,1,263,78.507,2018,386,0,205,28.4976,2024,903,0,264,33.5015,2023,495,1,247,55.1445,2019,210,0,436,9.3946,2021,608,1,153,78.919,2022,109,0,102,41.3952,2022,275,0,171,14.1166,2022,145,1,308,11.8544,2024,988,0,364,38.205,2021,731,1,112,86.5166,2022,909,1,161,87.3357,2021,70,0,273,5.3497,2021,218,0,306,93.1111,2022,992,1,477,16.9701,2024,16,1,379,83.157,2023,749,0,188,76.4299,2023,454,0,187,91.9783,2018,797,0,60,44.6919,2023,154,1,227,74.7193,2019,256,1,357,15.4229,2023,108,0,237,36.0042,2019,371,0,380,31.3895,2019,590,1,230,63.7532,2023,113,1,351,43.8288,2024,122,0,229,74.4885,2021,395,1,354,30.1564,2023,818,0,383,51.1065,2019,787,1,451,20.0141,2021,155,0,482,59.0639,2022,448,0,33,69.7741,2021,814,0,434,55.3449,2018,436,0,413,70.5357,2021,115,1,209,27.0294,2019,984,0,157,1.5446,2020,227,0,346,87.2463,2020,627,1,74,11.84,2018,581,0,322,78.6573,2022,390,0,374,99.8867,2021,353,1,152,5.6584,2022,318,0,327,54.731,2024,195,1,447,86.7438,2021,743,0,15,93.1257,2023,865,1,340,98.0048,2020,700,1,446,54.2752,2024,895,1,283,71.2797,2019,845,0,268,35.0642,2018,3,1,383,22.6124,2018,791,0,159,4.0251,2020,506,0,230,67.2233,2023,534,0,304
13
+ 612,C311,45,Headphones,Electronics,8000.0,1.0,2024-05-21,0,114,25.1746,2023,350,1,378,60.6678,2019,185,1,435,95.9221,2022,987,0,103,84.1202,2020,586,1,291,37.9491,2021,930,0,451,75.0386,2021,670,0,173,40.845,2024,345,0,388,41.7529,2021,501,1,205,75.9259,2020,286,1,355,68.8055,2019,585,0,194,46.8454,2023,597,1,322,61.7538,2019,539,1,418,82.3195,2019,140,0,8,65.9815,2020,825,0,404,89.5488,2021,831,1,66,19.5934,2021,657,1,198,75.8448,2018,793,0,55,75.7624,2024,145,0,195,28.4838,2020,727,1,209,94.1845,2018,838,1,183,71.9382,2022,198,0,498,69.5826,2020,384,1,451,92.0282,2022,46,0,112,74.1567,2020,673,0,41,61.211,2019,848,0,354,88.0356,2021,841,0,357,36.4826,2019,455,1,250,30.0309,2018,261,0,286,60.0315,2024,29,0,265,16.4333,2024,260,1,455,23.8735,2019,943,0,332,18.7975,2024,878,0,48,12.5775,2019,637,1,492,30.32,2024,124,0,347,9.34,2019,998,1,34,22.063,2018,831,0,421,52.4875,2023,513,1,219,49.6862,2018,76,0,234,82.4235,2019,538,1,104,46.2018,2023,264,1,66,6.036,2021,244,1,24,6.4716,2024,994,0,13,23.9393,2021,900,0,360,20.2078,2018,5,1,117,97.2884,2018,648,1,80,68.9284,2024,44,1,80,17.6141,2020,765,0,233,76.8382,2021,986,1,393,14.1893,2021,856,0,357,68.0392,2024,21,1,278,93.1926,2021,9,0,91,19.7164,2018,162,0,487,52.228,2018,748,1,387,39.743,2021,495,1,477,9.6685,2022,117,0,257,89.2016,2021,596,1,181,10.9361,2018,118,0,447,26.3534,2020,808,0,358,83.8325,2021,50,1,423,46.3884,2023,592,1,60,82.5943,2018,265,0,179,17.1842,2021,820,0,59,1.235,2024,342,1,321,4.6736,2022,677,0,356,31.3905,2022,701,0,11,6.0762,2024,947,1,147,91.0698,2024,97,0,401,4.2701,2021,994,0,110,78.5132,2022,435,0,108,98.0623,2022,980,0,394,25.1927,2022,579,1,154,21.9261,2020,328,1,107,66.8068,2020,584,1,85,26.7067,2021,684,1,44,32.0077,2023,29,0,128,41.4427,2022,141,1,56,42.6543,2019,232,0,41,63.3698,2019,961,1,226
ceo_brief_env/tasks/easy_brief/ground_truth.csv ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ metric,value
2
+ data_quality_score,1.0
3
+ total_revenue,58998.58
4
+ top_category,Electronics
5
+ projection_next_quarter,102114.97
6
+ variance_pct,126.92
7
+ break_even_units,14.12
8
+ memo_score,0.725
ceo_brief_env/tasks/easy_brief/metadata.json ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "title": "Revenue sanity check",
3
+ "difficulty": "easy",
4
+ "max_steps": 8,
5
+ "instruction": "Is our raw sales file trustworthy, what's next quarter's revenue looking like, and send the team a one-paragraph update.",
6
+ "required_experts": [
7
+ "analyst",
8
+ "finance",
9
+ "hr"
10
+ ],
11
+ "memo_audience": "team",
12
+ "hr_required_terms": [
13
+ "revenue",
14
+ "projection",
15
+ "team"
16
+ ],
17
+ "plan_value": 26000,
18
+ "fixed_cost": 12000,
19
+ "unit_margin": 850
20
+ }
ceo_brief_env/tasks/easy_brief/raw.csv ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ OrderID,CustomerID,ExpiryDays,Product,Category,Price,Quantity,OrderDate,dim_0001,dim_0002,dim_0003,dim_0004,dim_0005,dim_0006,dim_0007,dim_0008,dim_0009,dim_0010,dim_0011,dim_0012,dim_0013,dim_0014,dim_0015,dim_0016,dim_0017,dim_0018,dim_0019,dim_0020,dim_0021,dim_0022,dim_0023,dim_0024,dim_0025,dim_0026,dim_0027,dim_0028,dim_0029,dim_0030,dim_0031,dim_0032,dim_0033,dim_0034,dim_0035,dim_0036,dim_0037,dim_0038,dim_0039,dim_0040,dim_0041,dim_0042,dim_0043,dim_0044,dim_0045,dim_0046,dim_0047,dim_0048,dim_0049,dim_0050,dim_0051,dim_0052,dim_0053,dim_0054,dim_0055,dim_0056,dim_0057,dim_0058,dim_0059,dim_0060,dim_0061,dim_0062,dim_0063,dim_0064,dim_0065,dim_0066,dim_0067,dim_0068,dim_0069,dim_0070,dim_0071,dim_0072,dim_0073,dim_0074,dim_0075,dim_0076,dim_0077,dim_0078,dim_0079,dim_0080,dim_0081,dim_0082,dim_0083,dim_0084,dim_0085,dim_0086,dim_0087,dim_0088,dim_0089,dim_0090,dim_0091,dim_0092,dim_0093,dim_0094,dim_0095,dim_0096,dim_0097,dim_0098,dim_0099,dim_0100,dim_0101,dim_0102,dim_0103,dim_0104,dim_0105,dim_0106,dim_0107,dim_0108,dim_0109,dim_0110,dim_0111,dim_0112,dim_0113,dim_0114,dim_0115,dim_0116,dim_0117,dim_0118,dim_0119,dim_0120,dim_0121,dim_0122,dim_0123,dim_0124,dim_0125,dim_0126,dim_0127,dim_0128,dim_0129,dim_0130,dim_0131,dim_0132,dim_0133,dim_0134,dim_0135,dim_0136,dim_0137,dim_0138,dim_0139,dim_0140,dim_0141,dim_0142,dim_0143,dim_0144,dim_0145,dim_0146,dim_0147,dim_0148,dim_0149,dim_0150,dim_0151,dim_0152,dim_0153,dim_0154,dim_0155,dim_0156,dim_0157,dim_0158,dim_0159,dim_0160,dim_0161,dim_0162,dim_0163,dim_0164,dim_0165,dim_0166,dim_0167,dim_0168,dim_0169,dim_0170,dim_0171,dim_0172,dim_0173,dim_0174,dim_0175,dim_0176,dim_0177,dim_0178,dim_0179,dim_0180,dim_0181,dim_0182,dim_0183,dim_0184,dim_0185,dim_0186,dim_0187,dim_0188,dim_0189,dim_0190,dim_0191,dim_0192,dim_0193,dim_0194,dim_0195,dim_0196,dim_0197,dim_0198,dim_0199,dim_0200,dim_0201,dim_0202,dim_0203,dim_0204,dim_0205,dim_0206,dim_0207,dim_0208,dim_0209,dim_0210,dim_0211,dim_0212,dim_0213,dim_0214,dim_0215,dim_0216,dim_0217,dim_0218,dim_0219,dim_0220,dim_0221,dim_0222,dim_0223,dim_0224,dim_0225,dim_0226,dim_0227,dim_0228,dim_0229,dim_0230,dim_0231,dim_0232,dim_0233,dim_0234,dim_0235,dim_0236,dim_0237,dim_0238,dim_0239,dim_0240,dim_0241,dim_0242,dim_0243,dim_0244,dim_0245,dim_0246,dim_0247,dim_0248,dim_0249,dim_0250,dim_0251,dim_0252,dim_0253,dim_0254,dim_0255,dim_0256,dim_0257,dim_0258,dim_0259,dim_0260,dim_0261,dim_0262,dim_0263,dim_0264,dim_0265,dim_0266,dim_0267,dim_0268,dim_0269,dim_0270,dim_0271,dim_0272,dim_0273,dim_0274,dim_0275,dim_0276,dim_0277,dim_0278,dim_0279,dim_0280,dim_0281,dim_0282,dim_0283,dim_0284,dim_0285,dim_0286,dim_0287,dim_0288,dim_0289,dim_0290,dim_0291,dim_0292,dim_0293,dim_0294,dim_0295,dim_0296,dim_0297,dim_0298,dim_0299,dim_0300,dim_0301,dim_0302,dim_0303,dim_0304,dim_0305,dim_0306,dim_0307,dim_0308,dim_0309,dim_0310,dim_0311,dim_0312,dim_0313,dim_0314,dim_0315,dim_0316,dim_0317,dim_0318,dim_0319,dim_0320,dim_0321,dim_0322,dim_0323,dim_0324,dim_0325,dim_0326,dim_0327,dim_0328,dim_0329,dim_0330,dim_0331,dim_0332,dim_0333,dim_0334,dim_0335,dim_0336,dim_0337,dim_0338,dim_0339,dim_0340,dim_0341,dim_0342,dim_0343,dim_0344,dim_0345,dim_0346,dim_0347,dim_0348,dim_0349,dim_0350,dim_0351,dim_0352,dim_0353,dim_0354,dim_0355,dim_0356,dim_0357,dim_0358,dim_0359,dim_0360,dim_0361,dim_0362,dim_0363,dim_0364,dim_0365,dim_0366,dim_0367,dim_0368,dim_0369,dim_0370,dim_0371,dim_0372,dim_0373,dim_0374,dim_0375,dim_0376,dim_0377,dim_0378,dim_0379,dim_0380,dim_0381,dim_0382,dim_0383,dim_0384,dim_0385,dim_0386,dim_0387,dim_0388,dim_0389,dim_0390,dim_0391,dim_0392
2
+ 101,C001,25,Perfume,Beauty,,3,2024-01-05,1,151,6.6543,2022,742,1,264,83.0928,2022,831,1,381,87.079,2021,554,1,124,94.9615,2021,99,1,141,73.5733,2018,199,1,103,50.7921,2018,997,1,402,25.8798,2020,169,0,464,54.928,2023,341,0,291,23.7837,2018,133,1,295,58.8683,2021,318,1,7,11.0141,2021,520,1,204,51.6689,2018,761,1,92,82.1888,2018,407,1,266,51.2716,2020,393,1,286,47.6738,2019,69,0,319,47.193,2019,452,1,119,55.7923,2022,828,0,201,1.7105,2018,466,0,208,49.6581,2023,377,0,18,71.041,2018,470,1,250,69.0669,2022,817,0,144,33.6834,2024,906,1,83,12.5833,2020,47,1,234,97.003,2024,961,0,335,99.9777,2023,781,1,455,54.0921,2019,397,1,25,81.5716,2022,581,1,90,46.7452,2023,371,1,492,26.0389,2019,596,0,477,16.0837,2020,249,1,254,19.1717,2018,155,1,353,98.3351,2022,243,0,299,48.7493,2019,401,0,374,25.796,2020,396,0,169,90.9689,2019,438,1,474,76.6094,2019,645,1,255,28.0711,2019,692,0,294,19.8954,2020,410,1,356,67.6713,2020,747,1,380,31.4986,2023,392,1,343,6.1121,2018,776,0,139,72.2481,2022,162,0,66,81.6074,2022,419,1,441,9.0394,2023,226,0,221,64.6547,2023,133,1,487,31.6536,2024,871,0,20,27.961,2023,377,0,443,56.1347,2023,655,1,294,59.8245,2020,427,0,1,81.5397,2018,320,0,489,7.2491,2022,308,1,12,24.1107,2019,63,0,124,42.9194,2023,575,1,82,51.0652,2018,601,1,479,12.3134,2019,47,1,28,59.9933,2023,547,1,424,22.5172,2020,996,1,399,54.6272,2024,241,1,381,54.5808,2022,11,1,67,19.1392,2019,871,1,293,88.2664,2018,167,0,379,46.1159,2023,626,0,70,21.549,2020,363,1,164,17.8916,2018,633,0,25,31.5676,2021,220,0,385,12.3694,2022,585,1,413,67.2601,2024,473,1,367,40.2784,2023,690,1,452,82.8539,2021,200,0,314,6.051,2023,209,0,3,39.8109,2024,260,1,262,85.4137,2021,156,0,467,37.8447,2018,721,0,250,68.7795,2020,993,1,21,93.9418,2020,607,0,475,94.184,2020,585,1,391,91.4982,2023,844,0,297,84.561,2024,349,1,58
3
+ 102,C002,45,Headphones,Electronics,2950.0,2,2024-01-12,0,329,5.4567,2018,478,1,5,32.9736,2022,82,1,160,88.6105,2022,48,0,390,84.7199,2019,635,0,333,14.0566,2023,48,1,271,76.6528,2023,45,1,54,55.6728,2021,185,1,64,12.1544,2020,937,1,442,84.918,2024,919,1,400,23.3943,2018,635,1,155,11.4967,2018,776,0,56,59.6133,2024,713,0,390,8.5232,2018,58,0,249,49.7135,2023,690,0,276,2.2761,2022,889,1,483,96.1917,2019,333,0,374,64.8193,2021,512,1,433,64.0305,2022,371,0,404,31.5316,2022,14,1,326,5.8568,2023,482,0,219,35.3545,2022,199,0,471,79.117,2021,884,0,271,90.1492,2022,418,0,199,2.8694,2021,19,0,104,62.4036,2018,505,1,71,86.6347,2020,533,1,403,25.3447,2021,536,1,333,35.387,2020,698,1,366,58.9308,2018,404,1,1,94.3213,2021,542,1,28,62.8638,2022,4,0,418,89.2162,2021,931,0,106,22.1366,2024,463,1,384,13.851,2024,304,0,319,41.9916,2023,992,1,370,22.6341,2022,396,0,102,32.5837,2024,615,1,327,99.5718,2021,9,0,444,13.4762,2022,778,1,25,67.9196,2022,968,0,11,31.1943,2024,295,1,148,60.948,2022,883,1,431,99.6608,2019,530,1,106,61.8301,2024,800,0,112,7.2064,2020,831,1,225,24.3231,2021,713,0,242,72.5311,2022,318,0,349,43.203,2021,322,1,67,75.3554,2021,448,0,489,11.9982,2020,359,0,175,34.6785,2021,716,1,387,18.461,2021,364,1,226,81.9647,2023,378,1,490,5.7473,2021,492,1,244,49.7177,2023,59,0,494,16.627,2021,283,1,340,83.4134,2023,290,1,211,57.8393,2021,511,1,314,49.505,2019,9,0,446,93.4389,2021,278,1,223,74.3825,2019,570,0,41,26.3068,2018,836,1,254,2.7304,2019,644,0,80,54.031,2023,840,1,137,2.0184,2024,439,1,333,97.1451,2019,428,0,22,95.3483,2020,263,1,173,65.8071,2022,84,0,48,68.0284,2021,227,0,268,5.0386,2018,957,0,380,89.3062,2022,859,0,376,27.1523,2021,622,1,104,38.0364,2023,443,1,103,91.5052,2021,118,0,18,81.709,2021,459,0,362,46.5466,2024,465,0,203,24.3056,2018,896,1,9,12.8098,2022,764,0,456
4
+ 103,C003,60,Jeans,Fashion,1580.0,1,2024-02-02,1,54,75.3739,2019,160,1,377,55.9925,2022,506,1,34,53.5688,2023,44,1,3,71.1985,2024,465,0,472,5.8679,2024,754,1,347,63.3961,2018,422,0,313,71.2884,2021,214,0,223,22.366,2023,346,1,235,96.1176,2018,2,0,371,46.6825,2019,821,1,227,67.9788,2018,373,1,483,6.1848,2018,951,1,160,90.8118,2023,569,0,218,53.0183,2023,623,0,413,9.7654,2019,138,0,359,33.0132,2023,515,0,419,24.3553,2019,143,1,450,15.7017,2018,918,1,458,70.7117,2018,186,0,390,98.3891,2020,97,0,145,2.0443,2023,100,0,34,79.535,2019,137,1,179,41.6355,2023,988,1,397,23.1003,2021,198,1,472,7.4488,2022,524,0,3,79.9477,2024,451,1,412,58.1929,2023,647,1,435,84.3114,2024,856,1,475,94.2933,2022,301,1,285,10.8294,2023,959,1,381,7.0746,2019,637,0,393,95.3235,2018,492,1,220,65.6891,2024,859,1,86,69.4908,2020,657,1,132,16.0842,2020,410,0,26,28.9301,2022,92,1,410,31.1881,2020,106,0,317,74.8216,2020,689,1,450,31.5309,2024,499,0,203,75.7573,2023,174,1,422,27.7785,2020,834,0,121,30.0548,2024,592,1,444,52.5845,2023,660,0,39,38.6077,2018,490,1,428,28.4976,2024,274,1,139,52.7624,2018,733,0,415,49.5948,2021,211,1,184,55.1445,2019,997,1,200,87.3053,2023,819,0,273,60.8819,2022,459,0,317,78.919,2022,277,1,42,20.4355,2022,912,1,337,27.5169,2018,62,1,223,14.1166,2022,575,1,332,61.7015,2018,356,1,453,98.8982,2021,935,0,235,38.205,2021,511,0,475,22.3604,2018,525,1,286,90.9225,2023,704,0,165,87.3357,2021,755,0,104,54.5322,2018,484,0,247,21.832,2021,829,0,17,93.1111,2022,676,0,380,95.4845,2024,261,0,435,1.6942,2024,525,1,141,83.157,2023,772,1,178,37.5522,2024,413,0,374,45.437,2018,259,0,227,91.9783,2018,152,1,26,11.8771,2019,255,1,385,15.475,2022,733,1,227,74.7193,2019,256,1,364,71.5253,2020,39,0,361,10.8205,2019,393,0,199,36.0042,2019,529,0,101,76.1046,2019,520,0,139,59.0909,2022,276,1,36,63.7532,2023,536,0,264
5
+ 103,C003,60,Jeans,Fashion,1580.0,1,2024-02-02,1,123,22.6578,2021,363,0,423,35.0098,2021,997,0,451,60.6678,2019,266,1,445,87.0686,2024,615,1,320,98.715,2020,418,0,122,84.1202,2020,969,1,323,58.2904,2020,912,1,233,93.0111,2019,332,0,169,75.0386,2021,996,0,59,34.5087,2020,127,1,447,34.547,2019,955,0,433,41.7529,2021,110,1,459,41.0459,2022,39,1,200,28.6362,2022,906,1,401,68.8055,2019,626,0,24,38.7036,2020,843,0,423,59.7603,2023,334,0,37,61.7538,2019,614,1,325,83.5863,2024,866,0,111,14.0785,2020,388,1,497,65.9815,2020,737,1,4,80.8125,2023,948,1,267,83.1843,2024,59,0,226,19.5934,2021,457,1,263,39.6326,2023,763,1,34,79.3618,2020,421,1,474,75.7624,2024,757,1,229,38.9362,2020,650,0,180,72.7054,2024,768,1,273,94.1845,2018,684,0,487,36.492,2022,730,0,356,19.8507,2019,883,0,341,69.5826,2020,255,0,480,90.219,2023,199,0,340,4.6488,2018,653,0,238,74.1567,2020,860,1,118,8.1789,2019,872,1,101,84.8583,2021,875,0,3,88.0356,2021,273,1,2,71.3824,2020,55,0,73,45.5204,2022,380,1,284,30.0309,2018,78,1,36,13.8745,2023,949,0,485,65.8275,2019,241,0,169,16.4333,2024,191,1,497,45.6478,2019,736,1,104,4.8678,2018,930,0,142,18.7975,2024,110,1,237,51.7928,2022,94,0,119,65.3943,2023,273,0,264,30.32,2024,342,0,244,15.4404,2019,37,0,77,41.7061,2022,635,0,390,22.063,2018,918,0,194,61.8054,2021,89,1,413,36.4303,2023,765,0,287,49.6862,2018,735,0,4,0.7348,2023,503,0,95,18.4396,2023,949,0,384,46.2018,2023,713,0,320,91.2568,2019,11,1,283,66.0704,2022,991,1,33,6.4716,2024,162,0,25,36.8087,2022,351,0,244,85.5086,2021,374,0,13,20.2078,2018,527,1,361,1.2975,2019,595,0,65,98.3333,2022,647,0,42,68.9284,2024,238,1,426,27.2059,2023,579,0,211,73.7256,2019,102,1,142,76.8382,2021,825,1,375,82.9701,2022,261,1,259,52.2804,2019,23,0,84,68.0392,2024,104,0,431,58.2422,2023,826,0,219,77.0009,2019,475,0,429,19.7164,2018,465,0,174
6
+ 104,C004,90,Lamp,Home,870.0,2,2024-02-14,0,29,11.2991,2020,907,0,285,87.6315,2018,399,0,36,74.5718,2021,457,0,398,35.0699,2020,139,0,241,90.9415,2018,850,1,267,28.2215,2024,251,1,301,49.0841,2021,962,0,156,96.7308,2023,123,1,244,32.835,2022,866,1,490,47.5491,2021,338,1,107,93.7307,2023,363,1,384,49.8643,2024,303,1,40,2.8595,2021,699,1,169,85.1374,2019,549,0,498,5.3971,2019,98,1,187,11.7391,2023,650,0,492,84.6579,2021,516,1,487,30.7963,2022,346,0,207,7.1317,2022,582,0,38,23.1429,2024,794,0,306,28.3732,2022,932,1,104,2.6198,2023,579,1,472,81.2493,2023,522,0,453,45.9313,2020,819,1,123,72.9151,2019,102,0,378,34.7917,2018,913,1,442,96.3588,2023,624,0,484,79.7165,2021,713,1,438,12.6743,2019,462,1,108,52.8901,2024,943,1,488,44.3529,2024,877,0,324,48.6673,2022,618,1,5,29.3695,2021,879,1,199,45.5387,2018,1,1,374,81.9871,2024,756,0,370,86.3754,2021,137,1,60,22.1585,2021,722,1,298,19.3957,2021,960,1,388,20.3585,2018,494,1,154,78.7417,2020,900,1,103,25.009,2022,333,0,279,25.424,2018,747,0,73,31.2542,2024,614,1,423,96.7819,2021,383,0,79,98.1138,2021,58,0,246,95.9976,2018,873,1,368,60.569,2019,138,0,135,20.5493,2022,588,1,268,13.6289,2020,872,0,371,57.1197,2018,615,1,315,89.8031,2019,303,1,302,10.2863,2024,665,1,255,31.6239,2019,307,0,61,65.3571,2024,120,1,243,98.1271,2023,792,1,414,93.0922,2024,938,0,57,8.9959,2024,953,0,269,0.2961,2022,888,1,376,75.9751,2022,837,1,417,88.9471,2019,877,1,200,98.955,2022,760,0,57,93.1981,2024,488,1,89,58.4507,2021,153,1,485,64.8237,2019,684,0,276,87.6392,2021,423,0,327,28.4076,2022,538,1,241,7.9994,2023,461,0,423,79.3825,2023,634,0,16,93.095,2024,555,1,224,3.7138,2022,887,1,252,33.5353,2022,658,1,375,85.9028,2019,856,1,246,18.9959,2018,804,0,137,5.1409,2019,953,0,154,22.7695,2024,928,0,139,89.972,2024,486,1,283,77.6769,2021,932,0,459,11.0417,2021,312,0,74
7
+ 105,C005,120,Racket,Sports,1730.0,1,2024-03-03,1,47,42.714,2021,911,0,194,57.2446,2024,162,1,165,76.493,2022,874,1,229,99.5758,2019,282,0,276,56.4798,2023,111,0,311,63.1296,2019,771,0,49,0.5169,2023,534,1,44,34.2597,2019,852,0,250,57.3504,2021,918,1,128,71.8955,2018,316,0,461,55.3715,2022,910,0,271,79.0221,2018,379,0,22,44.3949,2021,893,1,35,31.8996,2018,337,1,486,59.7847,2021,76,1,82,54.0554,2019,291,1,242,62.3806,2023,412,1,403,37.3206,2021,256,0,384,4.2352,2018,660,0,176,47.3081,2018,331,0,319,8.0667,2024,958,1,183,94.536,2019,227,0,99,47.319,2020,169,1,119,41.1509,2022,868,0,249,32.0634,2023,4,1,60,84.5566,2023,951,0,326,73.7287,2020,481,0,105,91.4205,2024,624,1,301,16.1198,2019,921,1,333,33.077,2022,11,1,349,68.7099,2021,975,0,345,61.8571,2020,119,0,474,56.0511,2018,155,0,98,46.647,2024,642,1,51,1.7474,2018,573,0,425,70.3823,2022,546,0,98,45.8999,2024,731,1,210,68.6213,2018,403,0,34,84.2282,2024,15,0,187,69.9959,2023,688,1,8,62.8688,2024,896,0,494,95.9372,2024,921,0,231,4.3398,2023,63,0,367,26.1181,2020,252,0,80,43.092,2023,270,0,479,31.4024,2022,457,1,126,73.8316,2019,728,1,468,33.6178,2024,64,1,256,34.494,2023,713,0,214,48.3446,2023,633,0,280,75.8613,2018,652,1,206,31.6637,2021,708,1,413,92.4943,2019,769,0,29,79.2744,2018,113,0,200,31.7797,2018,680,0,177,55.4834,2022,717,1,17,20.6443,2024,904,0,269,46.5135,2018,333,1,225,0.314,2022,907,1,325,0.9522,2020,151,1,357,79.7807,2020,812,0,298,17.8222,2024,204,0,242,31.6463,2018,174,0,87,20.6699,2024,898,0,310,3.1975,2023,333,0,37,45.6321,2022,467,0,420,18.3574,2023,723,1,254,75.6098,2024,255,1,105,18.3792,2023,95,1,316,62.3586,2024,468,1,93,30.1892,2019,844,1,80,74.2783,2023,293,1,38,56.7895,2021,910,0,441,0.8273,2022,90,0,494,8.0484,2018,768,0,285,50.5273,2022,783,1,459,46.6083,2021,385,1,355,86.8212,2018,389,1,394
8
+ 106,C006,75,Phone,Electronics,28810.0,1,2024-03-10,0,162,89.2765,2024,438,1,221,35.1768,2024,778,1,342,18.6732,2020,754,1,53,70.9068,2020,818,0,292,5.8639,2019,78,1,480,95.2648,2024,861,0,383,18.4114,2023,8,1,421,51.4506,2021,865,1,79,54.1033,2022,66,0,478,50.1232,2023,436,1,313,66.2604,2018,429,1,179,16.5286,2021,581,0,104,94.3254,2019,787,1,231,59.6337,2024,819,0,460,42.525,2018,690,1,453,63.8216,2020,186,1,216,40.9548,2021,374,0,153,27.5346,2021,921,1,278,14.6176,2023,667,0,72,68.6175,2021,826,1,359,77.9182,2021,967,1,421,16.3202,2024,200,1,81,64.5495,2018,74,1,359,63.922,2022,747,1,328,88.0274,2023,890,0,360,73.209,2021,787,0,159,14.6466,2022,122,1,349,35.597,2023,950,1,262,95.6643,2021,307,0,460,62.1779,2018,69,0,382,92.4716,2022,210,0,431,69.2204,2019,121,0,305,78.1939,2018,910,0,387,74.2714,2023,187,1,311,87.2693,2020,355,0,55,4.8737,2018,235,0,284,92.996,2021,840,0,489,40.2421,2020,293,1,412,87.0848,2024,63,0,218,86.1945,2018,257,1,384,0.2459,2021,664,0,401,66.6517,2019,825,1,351,66.6189,2021,785,0,170,3.9129,2023,410,1,455,90.6137,2023,903,1,41,41.3513,2019,335,1,111,54.8415,2019,494,1,355,79.7123,2024,210,0,499,36.1479,2023,93,1,362,50.6429,2023,306,0,215,11.6132,2021,109,0,67,75.8066,2020,413,0,422,46.094,2021,340,1,466,73.9891,2022,145,1,204,68.7238,2021,118,0,77,17.7402,2021,728,0,399,96.0293,2020,731,1,377,3.889,2018,865,1,110,8.7815,2018,320,1,63,81.4889,2019,70,0,162,74.0095,2021,53,0,389,93.5618,2019,612,1,418,19.4281,2019,992,0,388,42.4485,2024,169,0,425,24.8221,2022,759,1,316,10.4367,2019,749,0,221,6.7502,2021,764,1,263,94.7722,2020,373,1,164,93.4439,2022,797,1,1,55.1035,2019,446,0,410,30.0502,2020,453,1,332,61.2768,2021,256,1,456,42.8609,2022,154,1,281,28.924,2024,474,0,224,59.5252,2024,371,0,289,68.7651,2018,313,1,183,25.7745,2020,459,0,46,76.2477,2018,113,0,260
9
+ 107,C007,30,Moisturiser,Beauty,650.0,2,2024-03-18,0,265,71.8898,2023,251,0,168,87.2184,2019,756,1,131,1.8023,2024,185,1,456,94.725,2022,959,1,453,4.1705,2023,205,1,35,92.5176,2023,586,0,404,4.7322,2020,379,0,107,90.9802,2022,903,0,204,86.6962,2022,670,1,19,59.5029,2019,408,0,361,1.7606,2019,776,0,209,70.6459,2018,501,1,14,80.266,2018,759,0,413,26.015,2019,710,0,197,75.7025,2019,585,0,268,84.2711,2024,468,0,206,19.0746,2023,644,0,48,44.6833,2021,539,0,219,34.2227,2021,823,0,134,29.2405,2019,15,1,265,63.2993,2023,825,0,142,44.134,2021,895,0,496,16.6216,2021,130,0,89,89.5891,2019,657,1,129,64.9228,2023,758,0,92,43.5028,2022,108,0,53,18.1607,2019,145,1,362,62.7104,2023,284,1,113,13.6536,2022,417,1,311,24.5513,2019,838,1,461,38.0537,2020,719,1,41,35.6929,2019,996,1,52,48.7308,2020,384,0,132,89.0276,2024,920,0,357,80.2398,2021,223,1,75,87.2403,2024,673,1,290,62.9747,2021,612,1,68,36.7122,2021,708,1,190,46.964,2019,841,1,284,19.5553,2024,364,0,64,96.597,2019,499,0,231,38.9561,2020,261,0,172,2.0021,2023,13,0,157,89.725,2020,529,0,203,68.7313,2021,260,1,148,65.3153,2021,208,1,480,24.5924,2019,663,1,371,79.0403,2024,878,0,427,0.4257,2019,938,1,19,70.2096,2020,985,0,275,1.6965,2023,124,0,279,83.0474,2018,230,1,276,4.4048,2024,66,0,127,81.5582,2024,831,1,488,34.4021,2019,304,1,252,1.434,2020,438,0,426,77.7966,2018,76,0,40,79.5751,2024,934,1,131,85.4413,2020,207,1,232,87.7352,2023,264,0,404,9.3724,2020,946,0,327,4.3843,2019,46,0,163,72.1793,2020,994,1,300,85.8559,2019,983,0,255,68.2368,2022,719,0,174,10.4976,2024,5,0,260,84.5444,2022,964,1,157,30.1674,2020,158,0,348,68.2181,2020,44,1,137,9.7238,2018,985,0,361,39.1171,2019,466,0,217,9.5306,2019,986,0,219,54.3066,2021,860,0,358,32.1899,2023,713,1,153,2.0633,2018,21,1,373,5.7149,2022,546,1,33,11.4459,2023,182,0,466,5.5255,2018,162,1,448
ceo_brief_env/tasks/expert_brief/ground_truth.csv ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ metric,value
2
+ data_quality_score,1.0
3
+ total_revenue,292540.0
4
+ top_category,Electronics
5
+ projection_next_quarter,121332.0
6
+ variance_pct,232.43
7
+ break_even_units,16.0
8
+ memo_score,0.6955
ceo_brief_env/tasks/expert_brief/metadata.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "title": "Full expert stack — data, finance, market strategy, comms",
3
+ "difficulty": "hard",
4
+ "max_steps": 14,
5
+ "instruction": "Run the full office: data quality and KPIs on Q3, finance forecast and variance vs plan, strategy view on the NVDA/AAPL/JPM watchlist aligned to our numbers, and a crisp executive memo. When advanced memory (RAG) is on, tie strategy to SOPs and external tape; otherwise internal metrics only.",
6
+ "required_experts": [
7
+ "analyst",
8
+ "finance",
9
+ "strategy",
10
+ "hr"
11
+ ],
12
+ "memo_audience": "CFO and strategy leads",
13
+ "hr_required_terms": [
14
+ "forecast",
15
+ "variance",
16
+ "strategy"
17
+ ],
18
+ "plan_value": 88000,
19
+ "fixed_cost": 32000,
20
+ "unit_margin": 2000
21
+ }
ceo_brief_env/tasks/expert_brief/raw.csv ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ OrderID,CustomerID,ExpiryDays,Product,Category,Price,Quantity,OrderDate,dim_0001,dim_0002,dim_0003,dim_0004,dim_0005,dim_0006,dim_0007,dim_0008,dim_0009,dim_0010,dim_0011,dim_0012,dim_0013,dim_0014,dim_0015,dim_0016,dim_0017,dim_0018,dim_0019,dim_0020,dim_0021,dim_0022,dim_0023,dim_0024,dim_0025,dim_0026,dim_0027,dim_0028,dim_0029,dim_0030,dim_0031,dim_0032,dim_0033,dim_0034,dim_0035,dim_0036,dim_0037,dim_0038,dim_0039,dim_0040,dim_0041,dim_0042,dim_0043,dim_0044,dim_0045,dim_0046,dim_0047,dim_0048,dim_0049,dim_0050,dim_0051,dim_0052,dim_0053,dim_0054,dim_0055,dim_0056,dim_0057,dim_0058,dim_0059,dim_0060,dim_0061,dim_0062,dim_0063,dim_0064,dim_0065,dim_0066,dim_0067,dim_0068,dim_0069,dim_0070,dim_0071,dim_0072,dim_0073,dim_0074,dim_0075,dim_0076,dim_0077,dim_0078,dim_0079,dim_0080,dim_0081,dim_0082,dim_0083,dim_0084,dim_0085,dim_0086,dim_0087,dim_0088,dim_0089,dim_0090,dim_0091,dim_0092,dim_0093,dim_0094,dim_0095,dim_0096,dim_0097,dim_0098,dim_0099,dim_0100,dim_0101,dim_0102,dim_0103,dim_0104,dim_0105,dim_0106,dim_0107,dim_0108,dim_0109,dim_0110,dim_0111,dim_0112,dim_0113,dim_0114,dim_0115,dim_0116,dim_0117,dim_0118,dim_0119,dim_0120,dim_0121,dim_0122,dim_0123,dim_0124,dim_0125,dim_0126,dim_0127,dim_0128,dim_0129,dim_0130,dim_0131,dim_0132,dim_0133,dim_0134,dim_0135,dim_0136,dim_0137,dim_0138,dim_0139,dim_0140,dim_0141,dim_0142,dim_0143,dim_0144,dim_0145,dim_0146,dim_0147,dim_0148,dim_0149,dim_0150,dim_0151,dim_0152,dim_0153,dim_0154,dim_0155,dim_0156,dim_0157,dim_0158,dim_0159,dim_0160,dim_0161,dim_0162,dim_0163,dim_0164,dim_0165,dim_0166,dim_0167,dim_0168,dim_0169,dim_0170,dim_0171,dim_0172,dim_0173,dim_0174,dim_0175,dim_0176,dim_0177,dim_0178,dim_0179,dim_0180,dim_0181,dim_0182,dim_0183,dim_0184,dim_0185,dim_0186,dim_0187,dim_0188,dim_0189,dim_0190,dim_0191,dim_0192,dim_0193,dim_0194,dim_0195,dim_0196,dim_0197,dim_0198,dim_0199,dim_0200,dim_0201,dim_0202,dim_0203,dim_0204,dim_0205,dim_0206,dim_0207,dim_0208,dim_0209,dim_0210,dim_0211,dim_0212,dim_0213,dim_0214,dim_0215,dim_0216,dim_0217,dim_0218,dim_0219,dim_0220,dim_0221,dim_0222,dim_0223,dim_0224,dim_0225,dim_0226,dim_0227,dim_0228,dim_0229,dim_0230,dim_0231,dim_0232,dim_0233,dim_0234,dim_0235,dim_0236,dim_0237,dim_0238,dim_0239,dim_0240,dim_0241,dim_0242,dim_0243,dim_0244,dim_0245,dim_0246,dim_0247,dim_0248,dim_0249,dim_0250,dim_0251,dim_0252,dim_0253,dim_0254,dim_0255,dim_0256,dim_0257,dim_0258,dim_0259,dim_0260,dim_0261,dim_0262,dim_0263,dim_0264,dim_0265,dim_0266,dim_0267,dim_0268,dim_0269,dim_0270,dim_0271,dim_0272,dim_0273,dim_0274,dim_0275,dim_0276,dim_0277,dim_0278,dim_0279,dim_0280,dim_0281,dim_0282,dim_0283,dim_0284,dim_0285,dim_0286,dim_0287,dim_0288,dim_0289,dim_0290,dim_0291,dim_0292,dim_0293,dim_0294,dim_0295,dim_0296,dim_0297,dim_0298,dim_0299,dim_0300,dim_0301,dim_0302,dim_0303,dim_0304,dim_0305,dim_0306,dim_0307,dim_0308,dim_0309,dim_0310,dim_0311,dim_0312,dim_0313,dim_0314,dim_0315,dim_0316,dim_0317,dim_0318,dim_0319,dim_0320,dim_0321,dim_0322,dim_0323,dim_0324,dim_0325,dim_0326,dim_0327,dim_0328,dim_0329,dim_0330,dim_0331,dim_0332,dim_0333,dim_0334,dim_0335,dim_0336,dim_0337,dim_0338,dim_0339,dim_0340,dim_0341,dim_0342,dim_0343,dim_0344,dim_0345,dim_0346,dim_0347,dim_0348,dim_0349,dim_0350,dim_0351,dim_0352,dim_0353,dim_0354,dim_0355,dim_0356,dim_0357,dim_0358,dim_0359,dim_0360,dim_0361,dim_0362,dim_0363,dim_0364,dim_0365,dim_0366,dim_0367,dim_0368,dim_0369,dim_0370,dim_0371,dim_0372,dim_0373,dim_0374,dim_0375,dim_0376,dim_0377,dim_0378,dim_0379,dim_0380,dim_0381,dim_0382,dim_0383,dim_0384,dim_0385,dim_0386,dim_0387,dim_0388,dim_0389,dim_0390,dim_0391,dim_0392
2
+ 401,C130,30,Monitor,Electronics,18500.0,2,2024-01-08,1,123,22.6578,2024,152,1,176,8.2049,2022,745,0,93,89.055,2021,615,0,368,5.8639,2023,622,0,198,58.6001,2019,47,0,489,54.928,2021,871,0,375,52.3668,2022,233,1,318,14.2836,2024,592,1,433,41.7529,2020,935,1,471,5.8712,2021,851,0,355,80.2094,2019,626,1,236,63.8216,2021,484,0,428,64.4314,2019,446,1,104,49.6581,2023,500,0,71,29.7861,2021,353,1,100,61.4805,2018,237,1,267,83.1843,2021,70,0,319,1.982,2022,729,0,379,6.6713,2019,421,0,408,14.6466,2023,208,1,201,28.4838,2023,136,0,485,16.0837,2018,532,1,183,67.1621,2022,892,1,466,5.2908,2023,35,0,480,90.219,2018,473,1,436,99.2768,2018,863,1,336,23.5451,2019,872,0,100,40.2421,2022,67,0,243,84.1431,2018,195,0,451,6.1121,2021,542,1,150,9.926,2021,816,1,210,92.2315,2019,470,1,428,28.4976,2019,874,0,157,87.1074,2019,48,0,332,26.8546,2020,110,0,294,36.1479,2020,428,1,426,5.526,2020,235,0,290,24.1107,2019,745,1,499,18.568,2018,494,1,246,81.428,2024,8,1,413,36.4303,2024,363,0,146,51.1389,2024,170,1,467,75.1767,2022,949,1,51,81.4889,2018,714,1,133,6.036,2018,304,1,115,21.549,2020,450,1,13,14.4934,2024,941,0,220,53.4918,2018,697,1,361,1.2975,2020,981,0,325,25.9336,2022,720,1,23,44.7849,2018,579,0,403,30.0502,2020,158,1,223,14.4828,2019,707,0,58,68.7795,2020,10,0,168,86.336,2019,580,1,233,87.7534,2021,554,0,429,19.7164,2022,866,1,220,3.6933,2021,381,1,387,69.223,2019,568,0,317,97.1287,2024,931,1,222,80.8092,2023,568,0,488,4.5514,2019,254,1,60,25.6277,2021,240,1,254,64.4252,2024,224,1,250,93.6697,2023,689,1,317,94.0421,2022,52,1,380,29.3441,2021,633,1,50,18.9402,2023,651,1,452,1.235,2018,300,1,72,41.9599,2021,473,0,356,14.2737,2019,433,0,434,26.3104,2023,167,1,279,80.3184,2023,864,1,258,79.838,2021,999,0,497,1.914,2018,547,1,54,40.4241,2020,23,1,343,13.3863,2023,807,0,22,77.511,2021,872,0,445
3
+ 402,C131,45,Serum,Beauty,1100.0,3,2024-01-19,0,29,11.2991,2024,527,0,151,99.7281,2019,762,1,294,45.7429,2019,139,1,178,4.1705,2020,960,0,456,64.8436,2022,335,1,308,12.1544,2022,534,1,11,47.7808,2023,566,1,411,25.1362,2021,109,0,384,49.8643,2020,182,0,373,3.9599,2023,495,0,460,97.2634,2022,98,0,224,84.2711,2019,431,1,218,76.582,2019,110,1,432,31.5316,2021,26,0,41,12.2157,2021,324,1,51,0.0719,2024,893,0,472,81.2493,2019,467,0,208,45.7343,2019,233,1,472,11.9559,2020,913,0,445,18.1607,2022,698,1,238,90.2845,2024,235,1,115,94.3213,2019,579,1,134,45.3949,2023,977,0,246,64.1519,2021,60,1,199,45.5387,2022,336,0,283,65.3956,2019,790,1,389,19.4642,2024,722,1,282,36.7122,2018,824,0,14,85.2095,2023,789,0,310,31.1943,2019,328,1,232,90.6755,2018,805,1,265,28.0504,2024,405,0,169,16.4333,2018,755,0,107,73.3119,2019,605,0,28,70.9682,2021,588,0,299,0.4257,2020,724,0,52,16.7124,2022,16,0,26,18.461,2018,598,1,209,51.1396,2024,57,0,287,95.8226,2019,531,0,414,93.0922,2023,849,1,480,95.3307,2018,2,0,412,22.0019,2019,837,1,96,87.7352,2018,323,0,306,5.78,2019,43,1,308,2.7304,2020,26,0,184,87.0907,2019,20,1,262,77.0651,2019,249,0,241,7.9994,2023,734,1,473,63.4024,2022,930,1,79,0.0412,2018,887,0,199,39.1171,2024,664,0,84,75.8617,2023,543,0,489,91.5052,2023,310,1,340,96.0673,2023,465,1,260,78.3053,2020,332,1,459,11.0417,2020,115,0,445,67.9927,2020,53,0,50,54.4408,2024,343,1,368,2.1276,2023,866,1,114,57.335,2023,45,0,160,46.6561,2021,159,0,350,6.1672,2020,146,1,100,47.6325,2024,72,0,268,88.481,2023,145,0,274,28.1618,2023,681,0,413,7.9943,2018,813,1,20,91.0577,2021,246,1,24,70.9632,2018,726,1,401,99.2569,2021,706,0,106,18.7186,2021,934,0,379,9.289,2018,959,0,146,38.7768,2024,199,1,143,58.217,2019,926,1,3,95.6922,2018,158,1,389,75.0932,2022,892,0,272,35.3021,2023,995,1,250,75.3618,2020,914,1,110
4
+ 403,C132,60,Workstation,Electronics,95000.0,1,2024-02-12,1,47,42.714,2021,9,0,436,16.2917,2024,764,0,167,91.2197,2024,282,0,71,85.4235,2024,68,0,106,65.9199,2019,548,1,211,22.366,2020,233,0,164,59.5803,2023,466,0,64,30.9181,2022,170,1,271,79.0221,2022,780,1,401,89.3017,2018,318,1,179,39.3874,2019,76,1,480,19.8423,2020,411,0,372,41.1074,2020,652,0,39,70.7117,2020,232,0,116,27.5355,2020,20,1,369,94.3381,2023,555,1,99,47.319,2018,397,1,448,86.8745,2019,320,1,315,18.2912,2024,951,0,127,44.5498,2019,723,1,431,42.7441,2023,88,0,283,10.8294,2019,386,1,222,34.0848,2023,953,1,441,21.2284,2021,398,1,98,46.647,2019,637,1,401,57.3556,2021,703,0,77,58.0077,2020,731,1,497,53.7273,2024,380,0,443,51.1824,2023,616,1,223,27.7785,2023,780,1,127,37.9729,2024,996,1,330,88.18,2021,845,0,79,98.1138,2019,974,1,207,87.3784,2024,442,0,159,71.488,2019,64,1,92,83.7223,2018,36,1,372,91.0575,2023,538,0,71,20.4355,2018,26,1,54,57.5166,2021,511,1,459,66.3906,2020,168,1,177,55.4834,2023,679,1,199,73.164,2024,303,0,327,69.2046,2023,907,0,346,44.691,2024,809,1,189,30.8422,2019,74,0,89,93.1111,2020,470,1,150,63.3282,2024,557,1,187,28.0697,2021,935,1,420,18.3574,2023,345,1,153,37.3078,2021,188,1,73,81.5536,2019,468,0,240,69.2473,2021,434,1,409,76.8679,2023,741,1,224,10.8205,2024,462,0,91,60.7351,2019,134,0,413,27.8491,2021,717,1,355,86.8212,2018,913,0,471,43.8288,2018,430,0,48,52.7364,2021,991,0,19,36.8383,2023,142,1,356,50.9879,2021,201,1,236,90.2847,2018,605,1,308,49.5281,2024,566,0,252,15.1072,2018,62,0,70,35.1858,2024,407,1,2,43.6596,2021,603,0,122,27.4913,2021,247,0,390,26.6006,2019,959,1,445,8.5122,2019,445,1,58,87.2463,2023,57,0,216,7.0348,2018,92,1,63,97.1628,2019,141,0,12,93.8023,2024,722,1,386,30.3609,2022,16,0,451,91.9243,2021,676,1,263,67.0188,2021,992,0,92,12.9781,2018,669,1,179,86.5065,2024,646,0,191
5
+ 404,C133,30,Shoes,Fashion,3200.0,2,2024-02-20,1,162,89.2765,2019,755,1,299,75.6653,2024,992,1,253,94.9615,2024,818,1,125,30.0631,2018,74,1,491,24.1479,2022,535,1,464,93.0111,2024,906,0,447,91.9658,2018,575,0,169,89.4187,2022,520,0,179,16.5286,2021,320,1,2,75.9259,2021,600,0,226,47.6738,2019,690,1,213,39.1209,2023,859,1,282,79.5521,2022,2,0,208,83.5863,2018,397,0,352,48.2215,2024,754,1,466,0.6968,2019,906,1,81,64.5495,2018,794,0,450,65.7579,2024,775,1,218,54.0921,2020,787,1,292,96.516,2021,327,1,394,96.9474,2023,629,1,477,94.1845,2021,737,1,297,0.4444,2022,529,1,309,68.2438,2023,401,0,387,74.2714,2024,262,0,114,22.3563,2023,698,1,342,28.0711,2019,840,1,13,44.1694,2020,465,1,491,2.6137,2022,839,1,343,45.5204,2020,45,0,174,88.324,2024,127,0,474,7.8104,2019,373,1,80,43.092,2024,449,0,132,33.5015,2023,738,0,418,56.1347,2024,210,0,377,32.9468,2020,32,1,381,49.5031,2018,594,1,12,15.4404,2020,558,1,158,6.21,2023,141,1,61,48.6048,2023,47,1,77,17.7402,2021,469,1,389,95.5585,2023,465,1,384,54.5808,2023,320,1,467,14.5694,2023,65,0,279,17.0002,2019,498,0,70,6.4716,2022,645,1,324,26.1433,2021,16,1,212,65.5122,2020,585,1,221,6.7502,2024,747,0,151,69.7436,2018,183,0,256,6.051,2023,446,1,446,62.9852,2023,498,0,218,52.2401,2023,293,1,250,52.2804,2018,431,0,114,52.9922,2024,761,1,243,56.7069,2018,844,0,46,76.2477,2019,528,0,184,52.228,2018,673,0,258,31.2558,2021,395,0,104,80.4519,2023,235,0,220,54.5223,2021,147,1,18,69.3036,2020,138,1,215,80.7792,2022,590,1,378,68.7228,2023,619,1,262,16.4702,2023,486,0,422,68.9975,2021,7,1,181,65.0755,2018,418,0,39,60.1489,2018,816,0,248,75.8667,2020,238,0,333,4.6736,2020,294,1,415,11.2811,2022,581,0,191,88.7794,2024,486,1,395,71.4436,2019,490,1,41,82.8742,2023,930,1,55,80.0123,2024,547,0,247,9.7451,2020,532,0,359,3.4564,2023,336,1,280,65.8915,2024,144,1,72
6
+ 405,C134,90,Headphones,Electronics,8000.0,2,2024-03-05,0,265,71.8898,2024,846,1,292,81.1799,2020,186,1,388,84.7199,2020,959,1,30,79.3659,2022,507,0,393,4.2389,2023,318,0,64,96.7308,2020,152,0,287,99.6766,2024,345,0,158,92.2447,2023,776,1,209,70.6459,2023,918,0,12,42.8658,2021,596,0,283,2.2761,2019,585,1,165,19.2569,2022,557,0,404,43.2429,2023,262,1,404,7.1317,2019,91,1,237,38.8495,2022,659,1,479,36.5177,2022,884,1,496,16.6216,2023,451,0,216,3.0805,2020,880,1,469,86.6347,2018,108,1,291,35.6642,2023,467,0,365,63.0225,2019,886,0,1,52.8901,2024,881,1,343,73.0891,2022,198,0,60,94.8786,2018,463,1,132,89.0276,2021,680,0,418,64.7971,2019,48,1,495,32.5837,2021,612,1,374,3.6041,2023,676,0,83,87.8541,2020,387,0,11,25.009,2023,377,1,479,7.8106,2018,525,0,307,84.7469,2021,226,0,455,90.6137,2019,277,1,326,23.8735,2022,478,0,155,43.203,2022,878,0,449,72.2503,2024,82,0,193,97.9875,2020,915,0,387,10.2863,2024,748,1,220,30.7576,2018,895,1,57,40.8812,2022,59,1,252,1.434,2021,573,0,412,39.3946,2021,608,0,163,49.505,2022,207,0,203,15.1097,2018,456,1,155,75.8981,2022,677,1,254,58.4507,2022,29,0,2,68.4925,2021,900,1,167,63.1309,2018,428,1,260,84.5444,2024,128,0,289,18.1263,2023,134,0,265,5.0386,2022,985,1,59,33.5866,2024,346,1,91,93.5597,2023,588,0,103,5.1409,2020,248,0,41,92.8819,2019,555,0,391,36.6055,2019,896,0,466,5.5255,2024,347,1,493,89.4587,2018,593,1,293,65.9521,2018,495,1,121,14.9704,2021,126,1,397,48.5795,2024,429,1,422,78.0612,2023,605,0,492,8.0854,2021,91,1,460,99.7837,2022,340,0,411,25.0686,2024,425,1,20,20.1205,2020,877,0,140,6.3381,2021,357,1,441,54.5731,2021,560,1,296,15.0743,2020,880,1,316,21.7833,2021,873,1,232,74.9316,2023,701,0,272,7.7791,2020,186,0,327,50.7167,2024,910,0,36,48.2355,2022,922,0,286,80.3627,2024,788,1,175,99.0117,2020,932,0,310,96.5513,2018,762,1,98,45.1042,2022,928,1,499
7
+ 406,C135,75,Desk,Home,12000.0,1,2024-03-18,1,326,6.9968,2022,570,0,312,23.88,2024,167,0,4,71.1985,2019,872,1,491,73.419,2024,626,1,498,10.633,2021,483,0,223,34.2597,2020,932,0,495,91.8562,2019,825,0,218,72.1691,2018,373,0,453,91.4978,2019,78,0,358,64.0517,2021,792,1,101,9.7654,2021,141,0,173,88.3355,2019,147,0,414,86.7129,2020,619,1,458,4.2352,2024,96,1,416,33.1595,2022,751,0,483,28.4169,2021,137,0,286,61.6459,2019,907,0,236,80.2235,2022,654,1,179,79.9477,2023,608,1,279,19.7535,2023,163,0,186,73.1922,2018,220,0,285,33.077,2022,135,0,298,97.5929,2022,747,0,61,10.3404,2021,859,0,88,94.0439,2020,749,0,152,39.199,2019,656,0,498,31.1881,2024,192,0,344,49.1334,2022,831,1,373,4.9071,2023,338,0,422,62.8688,2020,97,1,5,74.7235,2019,572,1,32,33.9786,2018,800,0,203,68.7313,2022,994,1,228,4.1149,2019,548,0,123,55.1445,2024,662,0,436,42.7386,2024,815,1,161,63.3442,2020,243,0,42,31.6637,2018,376,0,462,34.0854,2018,220,0,73,14.9649,2018,356,0,423,44.2479,2023,113,0,227,47.9252,2023,38,1,274,90.9225,2022,512,1,436,87.1975,2019,882,1,84,49.3552,2018,874,0,17,31.6463,2019,212,1,104,16.9701,2022,855,0,379,71.3009,2023,772,0,465,94.2951,2024,846,1,24,46.4478,2018,934,0,496,11.8771,2024,176,0,78,26.0189,2020,854,1,79,72.8541,2024,109,1,361,0.8273,2018,249,1,41,37.164,2021,582,1,157,74.9996,2023,276,1,471,71.9424,2019,146,1,123,13.7357,2020,677,0,53,74.4885,2024,462,1,354,24.1914,2018,841,0,434,9.7381,2019,856,1,275,6.1589,2018,81,1,411,96.4072,2022,263,0,224,20.8499,2021,333,0,422,40.6694,2021,647,1,57,23.0667,2022,746,0,276,11.5317,2022,423,0,135,8.6481,2023,474,1,8,32.7241,2019,513,1,401,2.8736,2021,165,1,103,11.84,2020,246,0,322,79.4095,2021,505,1,275,73.7156,2023,903,0,413,5.5315,2022,267,0,145,65.4113,2019,785,1,98,14.0724,2022,288,1,230,43.8475,2024,532,0,410,35.295,2022,134,1,126
8
+ 407,C136,30,Tablet,Electronics,,1,2024-04-02,0,34,45.6125,2022,388,1,269,74.9081,2022,18,0,404,87.0686,2020,174,0,493,4.8469,2019,766,1,23,64.5625,2018,800,0,233,51.4506,2018,300,1,270,67.0545,2024,475,0,204,11.0141,2021,955,1,258,52.671,2023,43,1,313,55.7647,2018,260,1,310,68.8055,2018,635,0,194,33.3327,2019,648,0,256,7.3639,2023,447,0,325,14.6176,2022,182,0,343,1.5572,2023,283,1,413,33.6834,2024,948,1,63,91.395,2023,236,1,280,36.4405,2021,649,1,473,79.3618,2021,777,1,379,53.6179,2019,353,1,349,35.8857,2022,148,0,273,62.1779,2024,888,1,462,71.9382,2024,486,1,498,48.7493,2019,255,0,129,81.5038,2022,100,1,14,41.3644,2018,872,0,100,8.1789,2021,982,1,424,0.9585,2022,134,0,389,0.3585,2022,739,1,73,0.2459,2020,94,0,333,82.5791,2021,138,1,392,81.782,2019,490,0,404,85.7758,2023,491,1,60,77.4271,2021,782,0,439,18.7975,2024,879,1,48,81.9548,2018,468,1,180,62.9521,2024,52,1,244,75.8066,2022,881,0,118,97.3721,2024,956,1,416,12.3134,2020,89,0,152,97.0545,2019,32,0,15,83.0262,2022,413,1,316,18.4396,2018,284,1,220,75.5864,2022,0,1,285,11.2657,2024,903,0,33,19.4281,2019,718,0,482,23.9393,2023,669,0,360,12.3694,2018,527,0,21,71.4861,2020,507,1,338,66.525,2022,827,0,311,27.2059,2019,112,1,383,73.3665,2021,862,1,311,49.1481,2019,564,0,259,28.924,2024,647,1,373,17.3233,2022,458,1,273,91.4982,2018,475,0,74,46.5692,2020,787,0,34,54.3874,2023,129,1,295,39.743,2020,493,1,477,68.1593,2024,955,1,326,32.5647,2022,139,0,396,29.1912,2022,462,1,438,11.486,2019,434,0,404,20.8995,2023,780,1,93,77.9134,2018,191,0,396,66.4161,2023,832,0,329,40.323,2022,27,1,297,73.5384,2020,942,0,85,61.0868,2020,772,0,323,28.0289,2019,872,0,167,31.3905,2019,407,1,11,56.3049,2023,310,0,277,96.3444,2020,18,1,59,28.6851,2021,160,0,204,43.7276,2021,82,1,218,5.7777,2022,409,0,337,5.8318,2022,195,0,341,28.0491,2022,44,0,323
9
+ 408,C137,60,Racket,Sports,2100.0,1,2024-04-14,0,345,53.8047,2018,442,1,50,88.4471,2021,483,0,308,35.0699,2022,238,1,440,41.8442,2021,228,1,212,9.6227,2018,767,1,156,90.9802,2023,581,1,430,51.8984,2018,749,0,419,11.4967,2018,363,0,297,1.1168,2023,208,0,220,12.3311,2021,389,1,138,5.3971,2019,291,0,363,84.3403,2023,840,0,72,80.7577,2020,542,0,207,34.2227,2022,36,0,417,9.2095,2021,89,1,198,79.117,2021,579,0,447,32.4947,2021,719,0,207,60.0091,2018,825,1,37,34.7917,2022,650,1,408,75.7903,2022,598,1,428,60.2616,2019,558,1,108,24.5513,2018,507,1,465,10.6033,2018,552,0,223,22.1366,2024,879,0,464,86.5524,2020,621,1,434,68.9897,2020,175,1,33,22.1585,2021,56,0,176,87.5468,2024,256,0,250,37.4572,2022,87,0,103,96.597,2024,277,1,411,24.1213,2022,66,1,7,9.0394,2024,241,1,318,55.5301,2023,958,0,125,82.5649,2023,245,1,443,20.5493,2024,525,1,259,87.2666,2024,119,0,230,43.0567,2019,555,1,302,83.0474,2022,248,1,231,92.223,2019,653,0,317,49.7177,2023,792,1,300,44.3207,2019,799,0,430,79.8385,2024,795,1,259,75.9751,2020,293,1,231,87.7181,2021,743,1,242,77.878,2022,269,1,89,72.1793,2019,328,0,212,17.8062,2021,876,1,76,97.1451,2019,538,0,336,45.0808,2020,525,0,373,90.4273,2022,682,0,399,3.7138,2018,687,0,368,65.8513,2023,271,0,128,91.3319,2018,699,1,137,32.1899,2018,41,1,298,44.8005,2023,899,1,466,24.3056,2018,932,0,422,8.0967,2018,519,0,215,67.2145,2022,6,1,211,11.5208,2022,857,1,291,62.7859,2020,567,1,39,98.6302,2022,826,1,340,17.4253,2022,702,0,356,86.0943,2022,492,0,139,97.1239,2022,246,1,130,66.4168,2023,336,1,189,76.3234,2018,418,1,189,78.9622,2024,522,0,86,38.4808,2018,969,1,54,89.6083,2018,24,0,458,15.6253,2021,360,0,362,83.8866,2023,68,0,3,50.1049,2021,50,1,392,61.4556,2024,350,0,86,58.6488,2020,13,1,30,60.0645,2018,381,0,131,18.4742,2023,34,1,249,68.669,2020,47,1,66,82.3491,2024,568,1,422
10
+ 409,C138,30,Phone,Electronics,42000.0,1,2024-04-30,0,28,81.0418,2021,336,0,439,32.0166,2020,670,0,494,99.5758,2018,826,1,454,11.1707,2022,633,0,484,80.8464,2022,410,0,44,38.6163,2024,885,1,433,13.4064,2021,718,1,410,67.9788,2018,910,0,298,3.0805,2023,26,1,263,49.855,2020,731,1,186,59.7847,2018,202,1,59,29.1723,2023,243,1,168,9.4579,2023,485,1,384,62.7176,2022,652,0,146,85.8191,2024,80,0,75,79.535,2019,227,0,450,46.9443,2018,177,0,344,20.7373,2020,18,0,204,84.5566,2020,661,0,481,48.1941,2024,843,1,325,22.4724,2024,706,1,333,55.3777,2018,54,1,190,29.8997,2018,618,0,183,65.6891,2024,155,1,70,97.9444,2024,713,0,36,74.1111,2018,633,0,328,45.8999,2022,510,1,97,40.3378,2024,315,0,137,56.7215,2023,987,1,8,98.7706,2022,295,0,195,63.0756,2020,312,1,300,61.8301,2024,383,0,323,82.1514,2023,82,0,24,3.8978,2018,696,0,319,33.6178,2022,566,1,424,9.3946,2021,589,1,137,67.7976,2023,805,1,206,58.7303,2020,451,1,335,7.1261,2018,683,1,467,61.7015,2018,680,0,316,54.7042,2019,852,0,465,95.1119,2019,528,1,255,0.314,2018,79,0,30,7.0625,2019,170,0,6,75.7246,2019,171,0,242,61.0947,2024,158,1,203,9.6113,2021,914,1,392,83.157,2023,467,1,418,47.3461,2020,314,1,459,45.4705,2024,514,1,296,62.3586,2019,339,1,42,45.3853,2021,442,0,412,12.8116,2021,555,0,441,17.6442,2021,34,1,232,37.5141,2020,83,0,45,59.0909,2022,385,1,214,34.9449,2019,896,1,395,99.9074,2018,997,0,329,92.5319,2024,142,0,25,30.1564,2023,449,0,138,41.3301,2018,48,1,114,40.1331,2019,804,1,473,29.8372,2022,878,0,23,6.5054,2023,661,1,90,55.0495,2024,765,1,311,45.664,2023,516,1,392,59.4806,2020,441,1,243,98.4585,2020,795,1,317,27.115,2019,268,1,21,34.08,2022,716,0,160,89.1934,2022,341,1,89,78.6573,2022,77,0,128,41.357,2020,759,0,70,17.6641,2018,410,0,491,61.1375,2024,402,0,16,89.4472,2019,242,0,380,46.1075,2022,603,0,15,95.6966,2022,831,0,234
11
+ 409,C138,30,Phone,Electronics,42000.0,1,2024-04-30,1,175,47.8909,2020,611,1,473,90.2784,2022,833,1,124,70.9068,2022,488,1,468,20.5395,2019,619,1,126,25.8798,2019,169,1,421,28.3051,2024,470,1,17,97.1131,2022,306,0,266,34.547,2019,429,0,51,71.3708,2019,834,0,135,40.0189,2020,759,0,286,42.525,2024,720,1,338,46.8454,2023,359,1,258,1.7105,2019,466,1,278,98.0003,2023,780,1,11,33.4572,2022,116,1,205,80.8125,2023,200,1,389,41.8102,2024,384,0,325,52.6488,2020,643,0,455,73.209,2021,513,0,19,14.5411,2021,997,0,356,26.0389,2024,596,1,460,12.6803,2023,763,0,59,43.8155,2024,229,0,431,69.5826,2020,910,1,104,30.4319,2022,959,0,154,47.6105,2023,714,1,255,92.996,2022,576,0,460,70.8354,2018,788,1,247,31.4986,2024,392,0,384,70.3137,2021,241,0,294,18.2568,2022,136,1,445,38.6077,2018,252,0,230,13.3165,2021,294,1,311,83.0984,2021,540,1,443,79.7123,2020,799,1,69,12.5775,2019,608,0,308,7.2491,2022,308,0,67,96.6011,2019,674,1,22,69.888,2020,792,1,381,61.8054,2021,118,1,83,93.5701,2023,306,1,198,53.8888,2021,120,0,381,8.7815,2018,604,0,444,50.7793,2022,545,0,380,46.1159,2022,626,1,418,42.9566,2024,760,1,429,16.2267,2024,31,1,315,20.2078,2018,749,0,476,41.3417,2023,725,1,192,3.1781,2020,21,0,314,55.1035,2024,855,1,168,83.1635,2019,747,0,428,37.8447,2022,721,1,281,16.685,2022,397,1,11,4.7573,2023,505,1,164,77.0009,2019,459,0,64,53.6161,2024,262,1,483,99.8908,2023,445,0,32,29.809,2023,774,1,91,9.6685,2022,818,1,18,4.8924,2024,86,0,461,74.0223,2018,492,0,147,27.4888,2022,544,1,103,23.2578,2022,697,1,213,4.3644,2019,79,1,469,78.6619,2018,169,0,144,37.4449,2019,571,1,60,55.8521,2021,314,0,335,41.7154,2021,193,1,160,76.4496,2022,776,1,200,11.0284,2021,545,0,246,6.0762,2024,390,0,10,10.3323,2022,708,1,81,53.584,2019,596,1,188,80.0292,2024,702,1,43,78.7573,2022,867,1,176,86.0708,2021,6,0,184,20.2184,2020,447,1,107
12
+ 410,C139,45,Keyboard,Electronics,3500.0,4,2024-05-06,0,377,36.3951,2022,830,1,98,33.0549,2023,197,1,390,94.725,2021,478,1,282,76.8981,2021,841,0,386,55.6728,2024,185,0,107,23.8932,2019,337,0,457,59.5041,2019,501,0,420,93.7307,2023,776,1,31,11.0989,2019,821,1,65,6.9612,2018,690,1,276,75.7025,2018,779,0,270,33.2918,2024,597,0,206,64.0305,2022,371,0,219,8.4668,2020,220,1,361,78.0429,2019,779,1,267,2.6198,2023,895,0,208,5.9954,2022,970,0,129,49.7094,2020,791,1,71,43.5028,2021,2,0,368,83.3729,2024,389,1,312,58.9308,2022,404,1,311,61.8415,2021,975,1,346,92.081,2020,692,0,194,29.3695,2021,384,0,347,19.9297,2023,909,1,215,85.1208,2021,367,0,102,62.9747,2018,501,1,343,46.6497,2023,880,1,8,67.9196,2022,968,1,64,90.3261,2018,567,0,304,96.4461,2020,43,1,70,65.8275,2019,410,0,36,27.4072,2020,922,0,138,73.7158,2024,113,0,349,79.0403,2024,982,0,125,29.0303,2023,637,1,316,34.6785,2018,716,1,279,30.1199,2018,153,0,379,16.2863,2021,547,1,97,98.1271,2023,304,1,278,93.8561,2018,673,0,26,75.4492,2018,749,1,314,85.4413,2022,607,0,388,38.7945,2020,131,0,406,26.3068,2024,836,1,163,20.3665,2024,49,1,373,4.82,2020,604,0,232,28.4076,2022,5,0,199,46.1039,2022,835,1,212,32.6755,2022,859,1,268,9.7238,2019,639,1,449,80.1548,2023,662,0,147,38.0364,2021,443,0,358,99.3657,2022,168,0,235,95.0801,2024,500,1,63,77.6769,2021,182,0,46,31.2831,2020,189,0,73,20.2355,2020,942,0,338,93.598,2022,876,0,132,15.3047,2024,117,0,261,87.688,2020,337,0,313,30.4665,2018,10,0,330,6.2271,2018,58,1,189,93.8413,2018,118,0,316,35.0588,2021,4,1,336,13.3286,2022,854,1,210,97.9624,2019,600,0,263,55.3138,2019,116,0,469,98.5379,2018,356,0,355,96.276,2021,465,0,255,14.8676,2022,414,0,111,24.2169,2021,947,0,156,44.5596,2018,697,0,61,77.1285,2018,508,0,127,46.5216,2020,249,0,437,51.997,2018,184,1,330,44.3134,2021,962,0,470,79.9028,2023,401,1,75
ceo_brief_env/tasks/hard_brief/ground_truth.csv ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ metric,value
2
+ data_quality_score,1.0
3
+ total_revenue,153877.78
4
+ top_category,Electronics
5
+ projection_next_quarter,-7672.0
6
+ variance_pct,102.47
7
+ break_even_units,16.67
8
+ memo_score,0.6955
ceo_brief_env/tasks/hard_brief/metadata.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "title": "Board-ready summary with risks",
3
+ "difficulty": "hard",
4
+ "max_steps": 12,
5
+ "instruction": "Prepare a board-ready revenue summary with risk flags, Q4 forecast with scenarios, strategic recommendation, and a CFO-facing memo.",
6
+ "required_experts": [
7
+ "analyst",
8
+ "finance",
9
+ "strategy",
10
+ "hr"
11
+ ],
12
+ "memo_audience": "CFO",
13
+ "hr_required_terms": [
14
+ "board",
15
+ "forecast",
16
+ "CFO"
17
+ ],
18
+ "plan_value": 76000,
19
+ "fixed_cost": 30000,
20
+ "unit_margin": 1800
21
+ }
ceo_brief_env/tasks/hard_brief/raw.csv ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ OrderID,CustomerID,ExpiryDays,Product,Category,Price,Quantity,OrderDate,dim_0001,dim_0002,dim_0003,dim_0004,dim_0005,dim_0006,dim_0007,dim_0008,dim_0009,dim_0010,dim_0011,dim_0012,dim_0013,dim_0014,dim_0015,dim_0016,dim_0017,dim_0018,dim_0019,dim_0020,dim_0021,dim_0022,dim_0023,dim_0024,dim_0025,dim_0026,dim_0027,dim_0028,dim_0029,dim_0030,dim_0031,dim_0032,dim_0033,dim_0034,dim_0035,dim_0036,dim_0037,dim_0038,dim_0039,dim_0040,dim_0041,dim_0042,dim_0043,dim_0044,dim_0045,dim_0046,dim_0047,dim_0048,dim_0049,dim_0050,dim_0051,dim_0052,dim_0053,dim_0054,dim_0055,dim_0056,dim_0057,dim_0058,dim_0059,dim_0060,dim_0061,dim_0062,dim_0063,dim_0064,dim_0065,dim_0066,dim_0067,dim_0068,dim_0069,dim_0070,dim_0071,dim_0072,dim_0073,dim_0074,dim_0075,dim_0076,dim_0077,dim_0078,dim_0079,dim_0080,dim_0081,dim_0082,dim_0083,dim_0084,dim_0085,dim_0086,dim_0087,dim_0088,dim_0089,dim_0090,dim_0091,dim_0092,dim_0093,dim_0094,dim_0095,dim_0096,dim_0097,dim_0098,dim_0099,dim_0100,dim_0101,dim_0102,dim_0103,dim_0104,dim_0105,dim_0106,dim_0107,dim_0108,dim_0109,dim_0110,dim_0111,dim_0112,dim_0113,dim_0114,dim_0115,dim_0116,dim_0117,dim_0118,dim_0119,dim_0120,dim_0121,dim_0122,dim_0123,dim_0124,dim_0125,dim_0126,dim_0127,dim_0128,dim_0129,dim_0130,dim_0131,dim_0132,dim_0133,dim_0134,dim_0135,dim_0136,dim_0137,dim_0138,dim_0139,dim_0140,dim_0141,dim_0142,dim_0143,dim_0144,dim_0145,dim_0146,dim_0147,dim_0148,dim_0149,dim_0150,dim_0151,dim_0152,dim_0153,dim_0154,dim_0155,dim_0156,dim_0157,dim_0158,dim_0159,dim_0160,dim_0161,dim_0162,dim_0163,dim_0164,dim_0165,dim_0166,dim_0167,dim_0168,dim_0169,dim_0170,dim_0171,dim_0172,dim_0173,dim_0174,dim_0175,dim_0176,dim_0177,dim_0178,dim_0179,dim_0180,dim_0181,dim_0182,dim_0183,dim_0184,dim_0185,dim_0186,dim_0187,dim_0188,dim_0189,dim_0190,dim_0191,dim_0192,dim_0193,dim_0194,dim_0195,dim_0196,dim_0197,dim_0198,dim_0199,dim_0200,dim_0201,dim_0202,dim_0203,dim_0204,dim_0205,dim_0206,dim_0207,dim_0208,dim_0209,dim_0210,dim_0211,dim_0212,dim_0213,dim_0214,dim_0215,dim_0216,dim_0217,dim_0218,dim_0219,dim_0220,dim_0221,dim_0222,dim_0223,dim_0224,dim_0225,dim_0226,dim_0227,dim_0228,dim_0229,dim_0230,dim_0231,dim_0232,dim_0233,dim_0234,dim_0235,dim_0236,dim_0237,dim_0238,dim_0239,dim_0240,dim_0241,dim_0242,dim_0243,dim_0244,dim_0245,dim_0246,dim_0247,dim_0248,dim_0249,dim_0250,dim_0251,dim_0252,dim_0253,dim_0254,dim_0255,dim_0256,dim_0257,dim_0258,dim_0259,dim_0260,dim_0261,dim_0262,dim_0263,dim_0264,dim_0265,dim_0266,dim_0267,dim_0268,dim_0269,dim_0270,dim_0271,dim_0272,dim_0273,dim_0274,dim_0275,dim_0276,dim_0277,dim_0278,dim_0279,dim_0280,dim_0281,dim_0282,dim_0283,dim_0284,dim_0285,dim_0286,dim_0287,dim_0288,dim_0289,dim_0290,dim_0291,dim_0292,dim_0293,dim_0294,dim_0295,dim_0296,dim_0297,dim_0298,dim_0299,dim_0300,dim_0301,dim_0302,dim_0303,dim_0304,dim_0305,dim_0306,dim_0307,dim_0308,dim_0309,dim_0310,dim_0311,dim_0312,dim_0313,dim_0314,dim_0315,dim_0316,dim_0317,dim_0318,dim_0319,dim_0320,dim_0321,dim_0322,dim_0323,dim_0324,dim_0325,dim_0326,dim_0327,dim_0328,dim_0329,dim_0330,dim_0331,dim_0332,dim_0333,dim_0334,dim_0335,dim_0336,dim_0337,dim_0338,dim_0339,dim_0340,dim_0341,dim_0342,dim_0343,dim_0344,dim_0345,dim_0346,dim_0347,dim_0348,dim_0349,dim_0350,dim_0351,dim_0352,dim_0353,dim_0354,dim_0355,dim_0356,dim_0357,dim_0358,dim_0359,dim_0360,dim_0361,dim_0362,dim_0363,dim_0364,dim_0365,dim_0366,dim_0367,dim_0368,dim_0369,dim_0370,dim_0371,dim_0372,dim_0373,dim_0374,dim_0375,dim_0376,dim_0377,dim_0378,dim_0379,dim_0380,dim_0381,dim_0382,dim_0383,dim_0384,dim_0385,dim_0386,dim_0387,dim_0388,dim_0389,dim_0390,dim_0391,dim_0392
2
+ 301,C020,45,Camera,Electronics,42500.0,1,2024-01-06,1,54,75.3739,2023,699,1,305,58.4566,2021,684,1,417,87.4468,2022,305,0,409,66.5334,2023,214,1,347,63.3961,2024,76,1,123,54.8351,2018,843,0,400,85.2639,2020,895,1,34,80.0559,2020,813,1,227,67.9788,2021,887,1,200,91.4978,2023,208,1,358,89.3017,2018,495,0,410,55.1762,2023,88,0,359,33.0132,2021,480,1,180,53.3545,2022,305,1,2,25.6145,2022,616,1,334,65.2375,2023,511,1,145,2.0443,2023,408,0,28,44.3295,2023,160,0,387,16.9309,2020,430,0,374,20.7373,2023,746,1,3,79.9477,2020,650,1,279,44.5498,2019,698,1,431,62.4852,2022,690,0,154,0.1635,2020,98,1,381,7.0746,2019,444,1,265,55.9868,2023,610,1,492,15.5929,2019,962,0,94,63.7886,2022,307,1,26,28.9301,2022,684,0,158,92.3911,2022,978,0,172,40.3378,2021,272,0,32,4.9071,2023,87,1,422,27.7785,2023,328,1,114,60.8744,2024,462,1,110,61.4745,2020,183,0,126,44.2648,2018,758,0,225,24.3231,2021,70,0,44,24.5924,2020,937,0,268,58.8934,2023,849,1,357,0.108,2022,745,1,175,34.6785,2023,524,0,393,83.0474,2018,825,1,379,30.7576,2019,956,0,57,95.8226,2019,8,0,494,16.627,2020,734,1,356,77.7966,2018,539,0,264,88.8027,2019,635,1,453,13.2315,2023,377,0,223,74.3825,2020,434,1,132,4.3843,2023,483,1,102,15.3093,2022,299,1,449,4.82,2024,791,1,333,97.1451,2024,403,1,199,84.5444,2020,507,1,289,63.4024,2022,720,1,48,62.7412,2022,922,1,380,89.3062,2019,222,0,221,9.5306,2023,74,1,371,80.4072,2023,267,0,46,4.1763,2018,70,0,362,46.5466,2022,88,0,196,11.4459,2018,710,1,341,31.2831,2024,313,0,458,67.2145,2021,130,1,338,65.9521,2022,493,1,121,2.1276,2023,931,0,377,3.4745,2018,152,0,271,3.5433,2022,596,0,402,73.0773,2023,257,1,283,12.4307,2020,774,1,306,24.6699,2023,2,1,417,14.5921,2021,622,1,498,77.5319,2021,244,0,318,97.9624,2021,239,1,105,38.4808,2024,860,1,469,15.0743,2018,772,1,316,99.2569,2021,473,0,338,39.9045,2024,412,1,249
3
+ 302,C021,30,Moisturiser,Beauty,720.0,2,2024-01-20,0,123,22.6578,2021,116,0,175,53.7339,2023,262,1,99,18.5698,2024,995,0,479,64.0496,2018,734,1,122,84.1202,2018,659,0,291,31.8463,2024,214,1,142,90.3383,2019,573,0,335,11.7731,2021,282,1,447,34.547,2023,466,1,209,52.671,2019,26,0,313,75.9259,2021,318,0,355,80.2094,2020,274,1,24,38.7036,2020,260,0,299,85.6753,2023,94,0,131,53.9089,2021,42,0,411,22.098,2022,275,0,497,65.9815,2019,534,0,404,72.3343,2021,993,1,457,13.0438,2024,411,1,329,52.6488,2024,839,1,34,79.3618,2021,661,1,379,96.516,2021,723,1,201,28.4838,2019,161,0,209,54.6238,2022,226,1,487,36.492,2018,298,1,100,23.3502,2018,103,0,162,38.4617,2019,466,1,460,68.0748,2024,430,1,238,74.1567,2020,991,0,41,19.3653,2021,134,0,221,70.8354,2022,842,1,420,0.3585,2024,987,0,73,45.5204,2020,780,1,150,9.926,2019,702,0,418,78.507,2023,967,0,205,85.6201,2021,821,1,139,52.7624,2024,41,1,248,54.0101,2019,709,0,82,21.0916,2020,136,0,47,54.5093,2021,762,0,317,78.919,2020,664,1,102,58.7303,2021,844,0,34,34.0854,2018,653,1,73,66.3906,2020,531,1,453,98.8982,2021,186,0,191,45.4332,2021,754,0,60,86.5166,2022,759,1,161,32.952,2018,151,1,104,54.5322,2019,57,0,109,49.8538,2024,837,0,305,99.2013,2018,648,0,85,87.1028,2018,594,0,141,83.157,2022,611,0,188,94.2951,2020,525,1,24,37.3078,2021,930,1,399,5.0934,2022,278,0,385,15.475,2019,801,1,373,18.6287,2023,913,1,147,15.4229,2020,51,0,237,39.7893,2018,960,0,101,76.1046,2022,327,1,295,58.3205,2019,91,0,359,11.3296,2019,776,0,219,99.9074,2022,388,0,122,74.4885,2024,857,1,354,36.8383,2023,866,1,166,76.7114,2020,587,1,394,55.0105,2018,304,0,246,15.5821,2021,860,0,295,68.3735,2024,997,0,406,69.7741,2023,884,1,434,48.61,2022,938,1,228,82.6348,2018,361,0,58,56.6793,2021,511,0,133,98.4585,2023,710,0,8,32.7241,2019,24,0,401,87.2463,2023,706,0,74,24.0179,2024,210,0,115
4
+ 303,C022,90,Sofa,Home,18800.0,1,2024-02-10,1,29,11.2991,2019,471,0,369,87.9216,2022,963,1,235,33.4647,2019,777,0,436,55.1259,2024,199,1,267,28.2215,2020,673,1,393,80.0632,2022,690,1,404,87.1558,2023,990,1,464,25.4842,2024,318,1,107,93.7307,2020,866,0,329,1.1168,2019,834,1,220,42.8658,2021,600,1,460,97.2634,2021,69,0,187,11.7391,2021,408,0,103,74.3899,2020,590,1,310,20.2072,2019,208,1,163,35.2033,2023,470,0,306,28.3732,2018,748,1,124,23.732,2024,571,0,400,24.3749,2019,96,1,102,49.7094,2022,781,0,378,34.7917,2021,513,0,408,35.6642,2023,327,1,238,90.2845,2020,873,1,221,66.6084,2022,249,1,488,44.3529,2022,101,1,373,29.6182,2020,527,1,218,90.6092,2024,99,1,224,10.0628,2021,438,0,370,86.3754,2018,996,1,10,91.7173,2019,828,1,267,46.6497,2023,332,1,462,37.4572,2022,392,1,103,25.009,2023,45,1,232,90.6755,2018,342,0,365,60.0315,2023,465,0,265,15.8295,2022,440,1,497,45.6478,2022,815,0,471,20.6832,2024,743,1,499,66.244,2022,248,1,469,74.2975,2022,385,0,264,30.32,2023,96,0,347,96.6011,2023,552,0,293,97.3721,2020,683,0,416,48.6048,2023,168,0,413,36.4303,2019,266,0,91,86.1215,2018,78,0,374,82.4235,2018,771,1,104,83.4673,2020,831,1,320,91.2568,2021,589,1,122,87.4121,2019,325,0,432,97.5049,2022,2,1,491,55.161,2022,711,1,13,20.2078,2020,527,1,117,71.4861,2023,314,0,338,69.7436,2018,188,1,23,44.7849,2020,98,0,211,73.7256,2024,910,0,331,16.7001,2021,438,1,294,14.1893,2019,720,1,357,30.7807,2023,126,0,431,58.2422,2021,125,1,5,42.9786,2022,933,1,9,88.284,2019,759,1,175,99.8908,2022,114,0,187,39.743,2023,142,1,477,80.4519,2023,142,1,222,80.8092,2019,614,0,298,68.0945,2021,431,0,6,69.9958,2019,474,1,46,24.0007,2018,577,1,345,83.8325,2019,466,0,423,64.7166,2022,672,0,263,66.9145,2018,279,1,133,45.8577,2022,823,0,233,55.8521,2021,343,1,498,61.0868,2021,268,0,323,4.6736,2020,57,0,356,14.2737,2024,732,0,84
5
+ 304,C023,75,Racket,Sports,1820.0,2,2024-02-14,1,47,42.714,2020,312,0,438,19.4635,2024,870,1,354,77.6051,2023,709,1,88,90.7177,2018,48,0,311,63.1296,2024,241,1,245,41.0682,2020,549,0,120,23.3109,2023,541,1,259,3.6265,2022,635,1,461,55.3715,2024,122,0,249,3.0805,2024,821,0,263,64.0517,2021,596,0,179,39.3874,2023,889,0,82,54.0554,2023,846,0,423,80.7724,2021,17,0,224,52.9675,2020,146,1,250,26.7396,2020,482,1,319,8.0667,2023,614,0,14,55.5247,2021,125,0,163,47.4782,2018,639,0,16,25.6543,2022,505,1,60,84.5566,2020,2,0,481,19.7535,2023,467,1,431,42.7441,2022,956,1,342,62.1249,2019,542,0,349,68.7099,2023,438,0,243,27.0909,2022,487,1,18,28.0433,2018,742,1,165,71.3714,2023,992,0,425,70.3823,2024,199,1,111,46.0826,2021,198,1,18,2.7541,2018,870,0,426,56.7215,2019,968,0,8,62.8688,2020,377,0,127,37.9729,2024,713,0,431,13.9674,2018,261,1,232,91.0177,2024,133,1,246,95.9976,2023,774,0,25,19.1692,2024,714,0,292,52.555,2022,344,1,63,72.434,2021,320,0,315,89.8031,2019,517,0,78,30.1199,2020,731,0,93,92.223,2021,792,1,317,40.8812,2022,47,1,414,93.0922,2024,146,1,248,39.563,2023,861,0,313,76.7891,2021,3,0,256,12.463,2023,871,0,200,98.955,2021,308,1,330,26.9515,2022,313,1,215,2.6928,2019,206,1,120,85.0633,2019,220,1,327,28.4076,2023,573,0,7,45.0808,2022,725,1,373,18.1263,2023,183,1,79,0.0412,2021,209,1,252,33.5353,2023,556,1,384,43.6743,2021,128,0,55,33.4484,2022,8,1,322,44.6948,2022,607,0,139,89.972,2021,518,0,385,33.2375,2020,943,0,233,39.8259,2022,16,1,261,20.2355,2022,782,1,346,11.5208,2022,774,0,291,14.9704,2021,235,1,114,57.335,2018,107,1,22,92.3611,2020,50,0,254,43.0767,2023,298,0,132,36.9529,2022,208,1,7,6.3694,2019,351,1,468,33.6908,2021,587,0,393,68.1358,2021,551,0,202,66.5348,2022,47,0,301,55.3138,2021,663,0,7,89.6083,2018,193,1,458,21.7833,2021,294,0,106,18.7186,2018,598,0,364
6
+ 305,C024,60,Laptop,Electronics,61500.0,1,2024-03-09,0,162,89.2765,2024,683,1,17,8.2049,2023,296,1,168,80.8305,2024,824,0,119,73.5733,2018,754,1,480,95.2648,2019,289,0,55,18.531,2024,545,0,269,15.2606,2024,860,0,66,58.8683,2021,821,1,313,66.2604,2020,928,1,406,71.3708,2019,853,1,135,55.7647,2018,792,0,226,47.6738,2019,138,1,453,63.8216,2022,581,1,162,51.2769,2020,78,1,271,20.7859,2020,586,0,14,71.041,2018,97,0,359,77.9182,2024,799,0,2,88.4798,2019,895,1,52,97.5301,2024,416,1,463,99.9777,2023,524,0,360,73.209,2024,398,0,19,53.6179,2019,163,0,394,96.9474,2023,694,1,473,16.0837,2020,959,1,382,92.4716,2024,100,0,276,93.1951,2022,23,0,31,43.0362,2019,287,0,346,90.9689,2019,410,0,55,4.8737,2018,64,0,239,61.5046,2022,565,1,198,38.6482,2019,350,1,91,31.4986,2023,174,1,384,0.2459,2020,97,1,174,88.324,2021,293,0,363,92.2315,2020,465,0,236,80.8868,2020,831,1,479,31.4024,2023,765,1,284,37.7957,2022,980,0,462,79.9134,2019,241,0,26,3.2444,2018,359,0,280,75.8613,2020,580,1,410,6.3912,2024,456,0,94,7.1261,2021,547,1,467,14.9649,2018,59,1,177,55.4834,2023,784,1,195,99.6502,2020,808,0,62,54.8141,2022,762,0,142,19.2626,2020,278,0,357,79.7807,2018,145,1,1,62.6761,2019,327,0,51,64.5489,2019,965,0,369,44.4957,2023,439,0,37,45.6321,2021,259,1,211,47.3461,2024,835,1,459,46.4478,2018,134,0,73,81.5536,2021,957,0,93,30.1892,2018,813,0,144,15.6662,2018,766,0,282,48.2179,2019,3,1,6,30.3385,2021,459,0,285,50.5273,2023,765,0,317,84.4094,2019,146,0,65,24.2266,2018,439,0,16,0.4916,2018,322,1,342,92.5319,2021,876,1,25,24.1914,2018,126,0,356,50.9879,2018,978,0,455,24.2767,2024,404,1,126,82.2161,2022,197,1,217,83.6948,2023,311,1,113,31.8553,2019,114,0,234,7.9824,2018,833,1,184,0.75,2024,657,1,336,29.6457,2024,98,1,381,24.3893,2024,709,1,380,27.115,2020,356,1,21,2.8736,2021,873,1,216,7.0348,2023,437,0,214
7
+ 306,C025,30,Jeans,Fashion,1490.0,3,2024-03-20,1,265,71.8898,2024,152,1,286,99.7281,2020,886,0,480,98.8885,2022,947,1,413,14.0566,2023,418,0,35,92.5176,2023,42,0,3,91.2929,2018,121,1,317,30.0124,2024,866,1,67,23.3943,2018,127,0,361,1.7606,2024,57,1,395,11.0989,2023,85,1,65,12.3311,2021,260,1,283,2.2761,2022,626,1,268,84.2711,2020,178,1,312,33.4871,2024,640,0,243,7.6375,2022,342,0,117,5.8568,2023,388,0,265,63.2993,2024,0,0,472,94.8278,2021,901,1,235,7.0395,2019,895,0,401,62.4036,2018,763,1,92,43.5028,2024,440,1,368,75.7903,2022,353,0,365,63.0225,2024,136,0,282,94.3213,2021,684,1,461,38.0537,2024,920,1,309,88.3726,2019,221,1,199,23.1782,2022,890,0,164,41.9916,2023,653,0,75,87.2403,2021,656,0,230,87.2321,2022,995,0,246,60.1625,2020,469,1,256,67.9196,2022,55,1,64,96.597,2024,94,1,479,7.8106,2018,816,0,273,28.0504,2022,39,0,460,64.6547,2022,274,0,41,41.3513,2024,825,1,303,21.1781,2024,561,0,484,21.2811,2023,361,0,145,81.5397,2022,459,1,215,11.6132,2020,50,0,52,91.2426,2019,429,1,256,69.888,2018,739,1,381,12.3134,2020,356,1,77,17.7402,2024,32,0,45,51.1389,2023,546,0,12,51.7834,2021,87,0,147,19.1392,2024,755,1,162,74.0095,2023,170,1,466,82.929,2018,215,0,102,21.2847,2021,424,1,89,31.5676,2022,525,0,316,10.4367,2021,187,1,40,41.3417,2023,402,1,192,66.525,2022,934,0,256,6.051,2018,255,1,410,30.0502,2022,868,0,429,25.6013,2024,378,1,350,97.96,2024,289,1,155,93.9418,2018,529,0,289,68.7651,2021,877,1,388,27.6949,2022,845,1,41,38.2101,2018,890,1,447,8.5159,2018,695,0,272,29.809,2020,36,0,91,68.1593,2024,841,1,220,54.5223,2024,297,0,428,4.5514,2019,840,0,369,71.3366,2018,274,1,246,20.0072,2021,208,0,37,78.3636,2020,164,1,16,89.6337,2023,940,0,67,74.6614,2024,377,0,395,21.632,2019,38,1,273,53.4317,2024,468,0,355,41.7154,2023,981,0,160,28.0289,2019,165,1,415,11.2811,2019,612,1,399
8
+ 307,C026,30,Phone,Electronics,,1,2024-04-15,0,326,6.9968,2021,527,1,396,16.2917,2018,626,0,277,78.0478,2023,470,0,244,5.8679,2024,850,1,38,77.5723,2024,805,0,299,53.4032,2021,463,1,171,88.5219,2020,32,0,377,46.6825,2019,338,1,109,2.3744,2021,408,1,206,37.943,2020,630,1,204,49.855,2020,389,1,101,9.7654,2019,98,1,85,19.8423,2019,238,0,167,41.2778,2024,250,1,233,80.8563,2023,853,0,199,98.3891,2020,794,1,492,62.4195,2024,287,1,377,22.7686,2020,777,0,24,39.7175,2019,901,0,465,7.4488,2022,102,0,167,35.8765,2023,50,1,224,48.1941,2024,598,1,186,73.1922,2023,235,0,332,10.8294,2023,943,0,273,69.1898,2019,706,0,115,11.9538,2021,403,0,201,76.832,2024,387,1,481,16.0842,2020,756,0,282,63.3782,2019,510,1,39,73.1798,2022,25,1,205,88.9204,2023,325,0,411,75.7573,2023,900,1,318,98.7706,2022,277,0,5,74.7235,2024,805,1,422,88.18,2023,264,1,54,7.2064,2020,191,0,148,65.3153,2021,949,1,221,13.8518,2022,911,1,474,58.7717,2024,649,0,193,11.9982,2020,273,0,275,1.6965,2022,141,1,126,66.5856,2021,600,0,468,16.2863,2021,486,0,97,49.7177,2023,89,0,252,1.434,2023,363,1,440,95.3307,2020,849,1,482,76.2162,2018,831,0,40,93.4389,2021,713,1,404,9.3724,2023,320,1,306,48.8411,2021,837,1,157,32.8304,2021,405,1,72,2.0184,2024,374,0,174,10.4976,2021,459,0,107,46.1039,2020,547,1,212,90.4273,2022,827,0,265,5.0386,2018,579,1,361,39.1171,2023,420,0,130,85.626,2019,114,1,278,49.9748,2023,460,0,231,81.709,2021,104,0,373,5.7149,2023,574,0,194,93.2419,2018,427,0,33,11.5342,2018,942,0,19,74.3725,2024,532,1,52,93.598,2024,837,1,132,62.7859,2020,955,0,397,48.5795,2023,568,0,209,46.6561,2023,94,1,330,29.321,2023,333,1,439,75.6471,2024,52,1,31,95.8228,2022,990,0,405,76.7522,2018,910,1,389,41.8046,2018,783,1,462,81.3103,2018,781,1,245,39.1732,2023,828,0,110,98.5379,2021,797,0,355,15.6253,2021,872,1,232,74.9316,2021,433,0,89
9
+ 308,C027,365,Yoga Mat,Sports,840.0,2,2024-04-25,0,34,45.6125,2019,9,0,176,75.6653,2024,535,0,25,89.055,2024,251,1,239,98.715,2020,111,1,254,39.5214,2022,106,1,92,37.9491,2021,223,1,468,33.7572,2023,914,1,485,34.5087,2020,316,0,55,26.6298,2023,110,1,83,50.186,2024,908,1,30,40.0189,2020,731,1,310,68.8055,2019,76,0,236,39.1209,2021,748,1,205,64.4314,2018,157,0,186,65.1142,2023,627,1,46,14.0785,2020,331,1,345,32.4528,2023,943,1,82,89.5488,2021,416,0,209,45.1824,2019,431,0,182,39.6326,2023,4,0,270,35.4614,2018,807,0,74,14.5411,2021,843,1,349,35.8857,2023,88,1,485,94.1845,2018,11,1,96,67.1621,2023,835,1,346,99.6091,2022,656,0,232,96.0584,2024,940,0,304,4.6488,2018,573,1,383,36.7511,2022,202,0,465,61.211,2019,748,0,5,0.4034,2024,664,0,14,71.3824,2020,688,0,31,70.3137,2021,295,1,333,82.5791,2024,996,1,210,7.8104,2020,897,0,221,28.4976,2024,58,1,461,11.9734,2020,38,0,369,49.4185,2020,432,1,328,39.9847,2024,4,1,51,60.8819,2022,615,0,339,59.4373,2018,23,0,159,41.3952,2022,819,0,288,44.5737,2018,815,1,448,61.7015,2018,792,0,423,44.2479,2023,849,0,104,73.164,2024,578,0,121,57.1823,2024,854,1,302,87.3357,2021,877,0,33,9.3636,2018,758,0,89,61.2364,2018,27,0,182,76.0114,2024,858,0,48,1.6942,2024,423,1,356,72.7303,2023,826,1,92,76.4299,2023,658,1,345,45.4705,2024,682,0,496,11.8771,2019,887,0,461,69.2473,2021,524,1,371,25.6699,2023,380,0,360,72.1913,2018,321,0,216,36.0042,2019,928,0,191,24.8653,2020,783,1,233,45.9097,2018,128,1,175,52.8222,2022,367,0,69,12.2785,2021,427,0,264,51.3836,2020,363,1,485,30.1564,2023,567,1,434,9.7381,2021,45,0,93,90.2847,2020,618,0,200,44.5822,2024,62,0,272,44.8256,2019,971,1,310,49.3915,2023,250,0,494,55.3449,2018,281,1,272,16.9499,2022,288,1,297,41.8737,2022,77,0,44,35.3019,2020,812,0,43,22.7301,2019,866,1,215,34.08,2022,360,0,103,11.84,2018,934,0,204
10
+ 309,C028,120,Lamp,Home,910.0,3,2024-05-01,0,345,53.8047,2024,755,0,151,81.1799,2018,311,0,23,45.7429,2019,971,0,144,90.9415,2018,78,0,313,21.0576,2022,625,0,481,81.3885,2020,504,1,173,50.0556,2018,9,1,145,47.5491,2021,436,0,333,59.201,2024,966,0,403,15.1981,2018,222,0,285,6.9612,2018,759,1,138,5.3971,2019,690,1,224,19.2569,2021,839,1,140,76.582,2024,296,0,459,76.7963,2022,108,1,49,23.1429,2024,826,1,134,86.1328,2020,67,0,295,21.8408,2024,7,0,494,23.6486,2022,472,1,355,72.9151,2019,890,1,163,78.8243,2022,824,1,401,83.3729,2024,997,1,428,60.2616,2019,629,0,115,52.8901,2024,69,1,378,45.3949,2022,787,1,340,36.5666,2018,416,0,429,19.5549,2022,368,0,376,81.9871,2024,355,1,142,66.2994,2023,821,0,450,98.2593,2022,689,0,345,6.7008,2019,975,0,215,78.7417,2020,257,1,180,90.3261,2018,241,0,411,24.1213,2018,127,1,265,84.7469,2018,861,0,53,16.4333,2024,270,1,67,4.6801,2019,483,1,239,5.571,2019,400,1,161,53.6205,2018,550,0,213,65.3943,2023,633,0,248,24.3403,2018,774,1,389,9.34,2019,660,1,189,12.0439,2024,553,1,92,61.8054,2021,680,1,152,97.0545,2021,679,1,146,95.5585,2018,991,0,256,75.1767,2021,208,1,304,46.2018,2023,151,0,228,61.3194,2024,81,1,300,35.7494,2018,91,0,322,97.0763,2018,746,0,52,85.5086,2021,333,0,180,63.1792,2018,43,1,15,97.2884,2018,254,0,43,3.1781,2020,514,0,311,27.2059,2023,468,0,403,62.9852,2021,752,1,377,14.4828,2023,847,1,222,27.4199,2023,430,0,124,68.0392,2024,768,1,397,93.1844,2021,405,0,12,13.3758,2024,91,1,382,14.6875,2024,986,0,95,39.0819,2024,111,1,149,10.7066,2021,26,0,296,9.6685,2022,449,1,326,32.5647,2021,201,0,488,69.3036,2022,584,0,261,25.6277,2024,363,0,30,27.8107,2021,390,0,171,53.7022,2018,406,0,94,46.3884,2023,422,1,250,52.3901,2023,418,0,368,42.3946,2018,882,1,7,16.1292,2018,229,1,123,32.778,2024,176,0,181,76.4496,2022,716,0,167,31.3905,2022,92,0,434
11
+ 309,C028,120,Lamp,Home,910.0,3,2024-05-01,1,28,81.0418,2022,846,1,436,23.88,2020,606,1,133,91.2197,2020,892,0,280,56.4798,2023,205,1,383,78.7518,2022,645,1,24,65.9768,2018,930,0,167,40.8495,2020,523,1,297,71.8955,2018,408,0,58,17.0828,2019,866,0,353,82.0915,2018,410,0,20,82.6782,2023,690,0,186,59.7847,2021,585,1,480,88.3355,2020,847,0,96,41.1074,2023,617,1,307,43.8865,2018,980,1,92,47.3081,2018,15,0,177,74.63,2019,6,1,221,66.6641,2019,831,1,30,17.7533,2021,559,1,300,32.0634,2023,758,0,433,68.3869,2023,948,1,91,63.8775,2019,389,0,325,22.4724,2018,886,1,283,33.077,2022,838,0,314,34.0848,2018,711,1,179,38.807,2024,695,1,128,26.27,2021,815,1,237,1.7474,2018,223,1,113,96.6986,2019,235,0,315,51.0998,2020,848,1,437,38.0631,2019,485,0,439,69.9959,2023,364,0,156,15.3276,2021,567,0,195,63.0756,2019,525,0,330,33.9786,2022,29,0,332,98.1138,2021,903,1,158,27.5686,2019,830,1,274,83.7357,2019,551,1,498,99.93,2021,837,1,456,57.1197,2018,306,1,37,55.5488,2023,83,0,379,59.8664,2021,275,0,31,93.3484,2019,709,0,407,98.1271,2023,118,0,300,44.3207,2021,469,1,480,39.3946,2021,223,1,263,22.0019,2019,766,1,343,88.9471,2019,70,1,441,55.8703,2018,493,0,467,34.2847,2019,931,1,338,77.6915,2020,939,1,81,87.6392,2021,759,1,62,24.9775,2024,355,1,34,32.1206,2023,454,0,130,32.6755,2022,21,1,399,3.7138,2022,446,0,199,33.5866,2023,454,0,306,75.8617,2021,715,1,20,56.2796,2021,176,1,125,22.7695,2024,371,1,470,13.8614,2024,278,0,129,84.2751,2024,637,0,268,51.9326,2020,245,1,272,5.3236,2023,457,0,156,39.6928,2021,597,0,485,15.3047,2024,818,0,39,98.6302,2024,147,1,160,78.0612,2023,200,1,266,6.1672,2018,989,0,340,20.5161,2022,65,1,167,52.3368,2024,406,0,231,85.7274,2020,436,1,167,24.4553,2023,489,0,187,52.2671,2022,270,1,367,24.6744,2023,439,1,379,32.4349,2021,691,1,210,96.276,2021,776,0,362,83.8866,2023,581,1,379
ceo_brief_env/tasks/medium_brief/ground_truth.csv ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ metric,value
2
+ data_quality_score,1.0
3
+ total_revenue,76562.5
4
+ top_category,Electronics
5
+ projection_next_quarter,123243.75
6
+ variance_pct,82.29
7
+ break_even_units,15.0
8
+ memo_score,0.725
ceo_brief_env/tasks/medium_brief/metadata.json ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "title": "Category growth and Q4 forecast",
3
+ "difficulty": "medium",
4
+ "max_steps": 10,
5
+ "instruction": "Which category drove Q3 growth, what is the Q4 forecast plus variance versus plan, what should we do about it, and send the leads a heads-up.",
6
+ "required_experts": [
7
+ "analyst",
8
+ "finance",
9
+ "strategy",
10
+ "hr"
11
+ ],
12
+ "memo_audience": "department leads",
13
+ "hr_required_terms": [
14
+ "forecast",
15
+ "variance",
16
+ "leads"
17
+ ],
18
+ "plan_value": 42000,
19
+ "fixed_cost": 18000,
20
+ "unit_margin": 1200
21
+ }
ceo_brief_env/tasks/medium_brief/raw.csv ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ OrderID,CustomerID,ExpiryDays,Product,Category,Price,Quantity,OrderDate,dim_0001,dim_0002,dim_0003,dim_0004,dim_0005,dim_0006,dim_0007,dim_0008,dim_0009,dim_0010,dim_0011,dim_0012,dim_0013,dim_0014,dim_0015,dim_0016,dim_0017,dim_0018,dim_0019,dim_0020,dim_0021,dim_0022,dim_0023,dim_0024,dim_0025,dim_0026,dim_0027,dim_0028,dim_0029,dim_0030,dim_0031,dim_0032,dim_0033,dim_0034,dim_0035,dim_0036,dim_0037,dim_0038,dim_0039,dim_0040,dim_0041,dim_0042,dim_0043,dim_0044,dim_0045,dim_0046,dim_0047,dim_0048,dim_0049,dim_0050,dim_0051,dim_0052,dim_0053,dim_0054,dim_0055,dim_0056,dim_0057,dim_0058,dim_0059,dim_0060,dim_0061,dim_0062,dim_0063,dim_0064,dim_0065,dim_0066,dim_0067,dim_0068,dim_0069,dim_0070,dim_0071,dim_0072,dim_0073,dim_0074,dim_0075,dim_0076,dim_0077,dim_0078,dim_0079,dim_0080,dim_0081,dim_0082,dim_0083,dim_0084,dim_0085,dim_0086,dim_0087,dim_0088,dim_0089,dim_0090,dim_0091,dim_0092,dim_0093,dim_0094,dim_0095,dim_0096,dim_0097,dim_0098,dim_0099,dim_0100,dim_0101,dim_0102,dim_0103,dim_0104,dim_0105,dim_0106,dim_0107,dim_0108,dim_0109,dim_0110,dim_0111,dim_0112,dim_0113,dim_0114,dim_0115,dim_0116,dim_0117,dim_0118,dim_0119,dim_0120,dim_0121,dim_0122,dim_0123,dim_0124,dim_0125,dim_0126,dim_0127,dim_0128,dim_0129,dim_0130,dim_0131,dim_0132,dim_0133,dim_0134,dim_0135,dim_0136,dim_0137,dim_0138,dim_0139,dim_0140,dim_0141,dim_0142,dim_0143,dim_0144,dim_0145,dim_0146,dim_0147,dim_0148,dim_0149,dim_0150,dim_0151,dim_0152,dim_0153,dim_0154,dim_0155,dim_0156,dim_0157,dim_0158,dim_0159,dim_0160,dim_0161,dim_0162,dim_0163,dim_0164,dim_0165,dim_0166,dim_0167,dim_0168,dim_0169,dim_0170,dim_0171,dim_0172,dim_0173,dim_0174,dim_0175,dim_0176,dim_0177,dim_0178,dim_0179,dim_0180,dim_0181,dim_0182,dim_0183,dim_0184,dim_0185,dim_0186,dim_0187,dim_0188,dim_0189,dim_0190,dim_0191,dim_0192,dim_0193,dim_0194,dim_0195,dim_0196,dim_0197,dim_0198,dim_0199,dim_0200,dim_0201,dim_0202,dim_0203,dim_0204,dim_0205,dim_0206,dim_0207,dim_0208,dim_0209,dim_0210,dim_0211,dim_0212,dim_0213,dim_0214,dim_0215,dim_0216,dim_0217,dim_0218,dim_0219,dim_0220,dim_0221,dim_0222,dim_0223,dim_0224,dim_0225,dim_0226,dim_0227,dim_0228,dim_0229,dim_0230,dim_0231,dim_0232,dim_0233,dim_0234,dim_0235,dim_0236,dim_0237,dim_0238,dim_0239,dim_0240,dim_0241,dim_0242,dim_0243,dim_0244,dim_0245,dim_0246,dim_0247,dim_0248,dim_0249,dim_0250,dim_0251,dim_0252,dim_0253,dim_0254,dim_0255,dim_0256,dim_0257,dim_0258,dim_0259,dim_0260,dim_0261,dim_0262,dim_0263,dim_0264,dim_0265,dim_0266,dim_0267,dim_0268,dim_0269,dim_0270,dim_0271,dim_0272,dim_0273,dim_0274,dim_0275,dim_0276,dim_0277,dim_0278,dim_0279,dim_0280,dim_0281,dim_0282,dim_0283,dim_0284,dim_0285,dim_0286,dim_0287,dim_0288,dim_0289,dim_0290,dim_0291,dim_0292,dim_0293,dim_0294,dim_0295,dim_0296,dim_0297,dim_0298,dim_0299,dim_0300,dim_0301,dim_0302,dim_0303,dim_0304,dim_0305,dim_0306,dim_0307,dim_0308,dim_0309,dim_0310,dim_0311,dim_0312,dim_0313,dim_0314,dim_0315,dim_0316,dim_0317,dim_0318,dim_0319,dim_0320,dim_0321,dim_0322,dim_0323,dim_0324,dim_0325,dim_0326,dim_0327,dim_0328,dim_0329,dim_0330,dim_0331,dim_0332,dim_0333,dim_0334,dim_0335,dim_0336,dim_0337,dim_0338,dim_0339,dim_0340,dim_0341,dim_0342,dim_0343,dim_0344,dim_0345,dim_0346,dim_0347,dim_0348,dim_0349,dim_0350,dim_0351,dim_0352,dim_0353,dim_0354,dim_0355,dim_0356,dim_0357,dim_0358,dim_0359,dim_0360,dim_0361,dim_0362,dim_0363,dim_0364,dim_0365,dim_0366,dim_0367,dim_0368,dim_0369,dim_0370,dim_0371,dim_0372,dim_0373,dim_0374,dim_0375,dim_0376,dim_0377,dim_0378,dim_0379,dim_0380,dim_0381,dim_0382,dim_0383,dim_0384,dim_0385,dim_0386,dim_0387,dim_0388,dim_0389,dim_0390,dim_0391,dim_0392
2
+ 201,C010,30,Serum,Beauty,1250.0,2,2024-01-04,1,329,5.4567,2020,911,1,168,87.6315,2021,238,0,268,1.8023,2022,780,0,497,22.5355,2020,907,1,427,41.8442,2021,633,1,393,64.8436,2018,5,0,267,42.2249,2020,386,0,117,50.0556,2024,595,1,400,23.3943,2021,316,1,361,93.7307,2020,466,1,31,70.6459,2023,780,1,222,52.6644,2021,826,0,365,90.6417,2024,97,1,137,63.5336,2021,540,1,146,17.8335,2019,533,0,206,80.7577,2022,485,0,404,31.5316,2022,660,0,134,23.1429,2018,858,1,11,63.2993,2020,943,1,472,23.732,2024,993,0,308,5.9954,2024,231,0,129,3.0805,2020,320,0,3,40.8466,2019,358,0,330,65.3289,2023,197,1,333,35.387,2021,624,1,113,12.6743,2020,564,0,55,24.5513,2021,54,1,343,45.3949,2018,80,1,280,88.3726,2018,656,0,199,90.6092,2024,466,0,321,47.3513,2024,836,0,196,85.1208,2022,966,1,102,32.5837,2021,731,0,68,19.3957,2022,27,1,158,46.964,2024,49,0,350,73.9902,2022,127,1,493,38.0783,2021,300,1,190,24.1213,2020,312,1,307,28.0504,2018,897,1,460,15.8295,2022,821,0,487,31.6536,2019,873,1,111,4.8678,2020,837,0,216,79.7123,2024,587,1,69,32.9468,2020,724,1,351,45.9584,2021,346,1,278,79.2483,2021,102,0,333,37.6627,2024,44,0,461,12.0439,2021,694,1,479,12.3134,2021,792,0,77,36.4303,2019,186,1,417,96.0293,2018,798,1,2,62.6016,2022,220,1,427,70.4983,2023,934,0,76,50.7793,2021,989,0,380,17.0002,2019,43,1,172,17.7742,2024,203,1,164,17.8916,2022,684,0,425,85.5086,2021,631,0,485,10.4367,2018,826,0,40,71.4861,2023,525,1,151,25.9336,2018,680,0,319,15.6732,2022,37,1,443,41.8112,2023,391,1,400,75.0757,2023,436,1,467,37.8447,2022,804,0,281,52.2804,2018,310,0,408,59.5252,2018,950,1,449,93.1844,2023,366,0,58,27.6949,2024,128,0,41,88.284,2019,776,0,340,54.3874,2023,6,0,258,69.223,2018,396,0,182,73.65,2019,627,1,433,85.9166,2022,573,1,438,29.7823,2022,35,1,390,74.0223,2022,737,0,147,80.7792,2022,146,0,185,27.8107,2020,938,1,124
3
+ 202,C011,45,Headphones,Electronics,3100.0,2,2024-01-11,0,54,75.3739,2021,438,0,306,57.2446,2024,471,0,156,67.0035,2020,5,1,388,70.1049,2021,647,1,430,11.1707,2022,619,1,498,65.9199,2021,598,1,5,12.7113,2024,800,0,453,40.8495,2024,133,1,371,46.6825,2018,436,0,109,55.3715,2024,866,1,200,91.4978,2019,320,0,283,12.8289,2018,50,1,379,33.769,2024,761,1,35,20.2785,2024,570,0,94,74.8463,2023,249,0,330,9.4579,2021,466,0,458,70.7117,2018,667,0,261,47.3081,2020,354,1,377,62.4195,2019,67,1,377,55.5247,2021,571,1,387,16.9309,2019,224,1,480,80.2235,2022,775,1,445,14.0649,2020,891,0,257,10.5889,2019,581,1,435,84.3114,2024,950,1,323,16.1198,2023,665,1,104,55.3777,2021,763,1,298,34.0848,2024,51,0,65,11.9538,2024,416,0,201,28.0433,2018,99,1,94,63.7886,2023,302,1,27,14.9061,2024,645,0,410,31.1881,2024,840,1,414,68.6213,2024,993,0,394,66.4764,2023,404,1,391,98.7845,2021,635,0,209,89.6202,2024,227,0,82,63.0756,2023,136,1,32,88.18,2022,861,0,54,91.0177,2024,440,1,225,24.3231,2018,457,1,480,60.569,2019,309,0,200,79.0403,2022,132,1,125,72.2503,2024,36,1,146,61.5763,2022,671,0,403,66.4277,2019,251,1,354,24.8371,2020,758,0,21,93.3484,2023,929,1,244,49.7177,2023,680,0,252,93.0922,2024,266,0,356,77.7966,2024,421,1,152,2.2151,2021,262,0,104,83.7163,2023,406,1,415,38.7945,2024,147,1,406,75.8981,2022,74,1,402,83.714,2019,312,1,80,54.031,2019,898,0,255,87.6392,2021,463,1,347,10.4976,2024,43,1,107,45.0808,2022,314,1,289,63.4024,2018,603,1,188,51.1038,2018,636,1,234,0.4813,2023,660,1,455,66.4586,2022,181,0,104,38.0364,2018,910,1,358,5.1409,2020,462,0,459,2.0633,2019,725,1,42,13.8614,2024,65,1,28,93.2419,2024,91,1,33,39.8259,2022,759,0,458,67.2145,2020,997,1,293,54.4408,2020,671,0,14,20.7163,2023,503,1,72,59.7554,2018,665,0,420,4.589,2018,845,0,290,30.4665,2018,660,1,330,8.0854,2021,566,1,396,20.5161,2019,892,0,331
4
+ 203,C012,90,Shoes,Fashion,2050.0,2,2024-02-08,1,123,22.6578,2024,251,1,415,35.1768,2020,749,1,303,19.7217,2021,890,1,354,63.5543,2019,735,1,151,20.5395,2024,841,0,23,24.1479,2019,184,1,190,46.541,2023,283,0,77,23.7837,2018,919,0,59,34.5087,2023,408,0,55,66.2604,2020,122,0,209,52.671,2023,918,1,471,5.8712,2021,512,0,345,71.0826,2024,688,0,444,77.9019,2020,638,0,234,84.7583,2020,856,1,397,1.7105,2018,371,1,325,83.5863,2023,823,0,355,68.6175,2023,334,1,330,32.4528,2020,6,0,82,88.4798,2019,125,0,457,13.0438,2023,195,1,10,36.4405,2021,880,1,379,6.6713,2022,354,1,2,81.5716,2022,536,1,229,38.9362,2023,284,1,130,95.6643,2021,970,1,470,12.6803,2022,975,1,462,0.4444,2022,983,1,117,99.6091,2022,695,0,232,43.0362,2019,742,1,460,68.0748,2020,27,1,207,76.6094,2019,396,1,118,8.1789,2021,612,1,100,40.2421,2024,386,1,440,48.5996,2019,3,0,431,96.8785,2022,61,1,351,49.965,2023,300,1,441,18.2568,2023,43,1,392,7.8104,2019,29,0,221,80.8868,2020,133,1,139,52.7624,2022,335,1,418,73.8316,2024,245,1,276,16.2488,2024,399,0,173,42.7386,2024,32,0,341,30.6011,2021,789,0,154,51.7819,2022,316,1,207,67.4651,2018,67,1,36,8.9182,2021,601,1,332,61.7015,2018,118,1,423,55.4834,2023,146,0,191,45.4332,2022,951,1,233,24.1036,2021,692,1,383,32.0905,2022,873,0,436,86.197,2018,797,0,27,49.3552,2018,498,1,452,31.3454,2019,363,0,380,95.4845,2024,169,0,223,3.1975,2020,60,0,415,72.7303,2020,355,1,92,47.3461,2024,725,0,24,37.3078,2019,919,1,100,99.2602,2024,623,1,224,77.1028,2018,692,0,278,49.8454,2019,156,1,364,71.5253,2021,154,0,181,0.8273,2018,431,1,180,23.1721,2021,200,1,253,58.5497,2022,749,1,292,45.9097,2022,637,1,175,24.2266,2018,16,1,219,99.9074,2020,445,1,53,52.7364,2018,873,0,299,70.8662,2023,301,0,118,94.227,2019,509,1,256,14.7357,2024,550,1,31,5.0866,2021,400,1,223,96.4072,2022,590,1,418,96.7052,2018,135,0,349
5
+ 204,C013,60,Rug,Home,2300.0,1,2024-02-18,1,29,11.2991,2023,883,0,402,87.2184,2019,607,0,359,70.9287,2023,796,1,412,61.5928,2022,355,1,34,76.8981,2018,418,1,212,4.2389,2022,962,0,88,8.6193,2020,808,1,466,84.918,2024,2,0,490,47.5491,2019,838,0,333,1.7606,2024,928,0,329,1.1168,2023,78,1,373,3.9599,2021,551,0,108,35.8678,2020,118,1,70,29.5505,2020,755,1,270,48.473,2022,434,0,153,64.0305,2022,918,1,207,7.1317,2021,326,1,62,29.2405,2020,528,1,375,86.1328,2021,207,1,295,94.8278,2021,895,0,400,24.3749,2019,703,0,100,60.0091,2018,654,1,472,11.9559,2023,139,1,199,25.3447,2021,647,1,484,79.7165,2023,800,1,147,13.6536,2024,228,1,121,61.8415,2020,976,0,465,73.0891,2023,424,1,344,36.5666,2018,863,1,429,23.1782,2022,287,1,224,10.0628,2018,869,1,38,22.6341,2022,92,1,60,22.1585,2021,192,1,282,36.7122,2020,741,0,133,88.652,2021,307,1,348,5.5991,2018,359,1,329,54.2622,2021,463,1,296,96.4461,2024,621,1,7,84.7469,2024,254,0,53,64.6547,2022,831,1,497,45.6478,2019,208,0,292,54.8415,2018,877,1,249,58.3708,2021,473,1,121,81.9548,2018,82,1,426,5.526,2021,24,0,358,5.0407,2019,777,0,115,51.0319,2020,587,0,223,51.0652,2023,492,1,194,61.8054,2021,304,0,152,17.7402,2024,784,1,91,86.1215,2020,7,1,304,52.5254,2023,72,1,369,51.2647,2018,439,1,139,5.8726,2023,854,1,473,11.2657,2024,677,0,115,21.549,2023,644,0,25,36.8087,2024,983,0,467,24.8221,2020,34,1,157,63.1792,2022,722,1,15,41.3417,2023,835,1,338,69.7436,2020,294,1,114,79.9118,2018,347,0,492,50.421,2020,250,1,407,85.4137,2018,622,1,375,82.9701,2022,860,0,118,28.924,2024,248,0,168,86.336,2021,862,0,250,52.0063,2023,140,1,73,13.3758,2018,911,0,382,38.2101,2018,439,1,175,99.8908,2018,942,0,295,31.2558,2024,741,1,397,58.2419,2019,3,1,63,65.113,2018,303,1,243,85.6043,2023,792,0,252,84.0284,2022,522,0,213,11.486,2019,91,0,254,64.4252,2024,731,0,60
6
+ 205,C014,75,Cycle,Sports,14500.0,1,2024-03-05,0,47,42.714,2023,677,1,165,58.4566,2023,884,1,373,96.1176,2018,457,1,473,28.2974,2024,140,1,397,39.5286,2018,282,0,484,10.633,2019,47,0,407,21.4044,2018,238,1,150,96.1176,2018,996,1,128,71.8955,2020,820,0,58,2.3744,2021,57,1,249,3.0805,2023,43,0,401,89.3017,2021,497,1,10,56.5891,2019,53,0,313,96.6426,2020,842,0,167,41.1131,2020,743,0,216,15.7017,2018,614,0,384,4.2352,2020,500,1,30,72.2705,2023,780,1,142,74.63,2023,365,0,221,22.7686,2020,901,1,163,47.4782,2020,459,0,229,20.7373,2020,649,1,315,18.2912,2019,788,1,220,58.1929,2023,757,0,105,91.4205,2020,902,1,295,8.8267,2020,565,1,264,22.6258,2023,698,1,190,97.5929,2023,892,0,148,38.807,2021,293,1,128,76.832,2024,890,0,165,71.3714,2022,71,0,345,28.9301,2022,860,1,98,45.8999,2022,982,1,497,53.7273,2020,601,0,102,16.5588,2023,374,1,98,68.8166,2023,311,0,451,78.0545,2023,254,1,39,13.1254,2018,666,1,300,33.9786,2021,470,0,332,7.2064,2020,274,1,246,95.9976,2021,238,0,140,24.5924,2023,886,1,94,96.8568,2021,536,1,181,87.2666,2024,815,1,52,16.7124,2021,303,1,139,2.3419,2023,758,0,47,84.4644,2021,185,1,349,5.7473,2021,575,0,243,98.1271,2019,524,1,300,1.434,2023,32,1,248,39.563,2018,538,1,20,88.8027,2022,545,1,344,29.387,2021,462,1,378,58.596,2019,740,0,31,77.878,2022,874,0,308,2.7304,2019,676,0,485,64.8237,2019,239,0,158,68.2368,2020,534,0,101,24.9775,2021,482,0,34,46.1039,2020,402,1,373,18.1263,2022,689,1,77,62.7412,2022,551,0,88,81.9682,2024,629,1,434,27.1523,2021,256,1,246,18.9959,2021,141,0,344,32.1899,2018,249,0,340,96.0673,2020,277,0,344,48.6141,2020,914,0,215,84.2751,2024,197,1,268,11.5342,2018,890,0,261,20.2355,2021,727,0,211,65.9521,2024,650,0,253,18.1034,2022,96,0,420,27.0103,2021,545,0,446,82.6798,2020,680,0,146,61.8234,2023,532,1,128,86.0943,2022,263,1,100,47.6325,2020,665,0,419
7
+ 206,C015,75,Phone,Electronics,30100.0,1,2024-03-17,1,162,89.2765,2021,699,1,102,53.7339,2023,762,1,381,4.861,2023,104,1,235,95.9221,2022,250,0,108,8.2629,2021,191,0,126,64.5625,2022,335,0,193,54.928,2021,537,1,291,75.0386,2021,866,1,478,50.1232,2022,531,1,173,26.6298,2023,408,1,406,71.3708,2019,208,0,2,75.9259,2020,37,1,436,62.1067,2021,432,0,49,4.7471,2020,247,0,240,55.7923,2020,563,1,201,61.7538,2019,346,0,278,14.6176,2018,26,0,145,29.7861,2018,500,1,45,19.9693,2022,843,1,434,89.5488,2021,777,1,52,97.5301,2024,430,1,409,52.6488,2020,825,1,218,54.0921,2023,500,0,25,75.7624,2024,624,0,349,35.597,2022,842,0,396,88.638,2020,954,0,180,54.2351,2024,764,0,59,71.9382,2022,977,1,115,5.2908,2021,790,0,439,96.0584,2024,387,0,346,90.9689,2024,307,0,474,74.1567,2020,137,0,284,92.996,2022,56,0,13,44.1694,2022,712,1,136,77.8202,2018,435,1,394,36.4826,2019,736,0,220,37.7807,2023,348,0,239,88.8664,2021,683,0,445,81.782,2019,405,0,25,28.4976,2024,191,0,479,31.4024,2024,70,1,266,54.0101,2021,638,1,458,65.57,2023,512,1,325,9.3946,2021,468,0,372,91.0575,2022,420,1,171,8.3443,2019,277,0,373,73.1571,2024,187,0,117,14.1166,2022,918,1,200,31.7797,2018,286,1,316,44.2479,2023,363,0,195,99.6502,2021,539,0,207,86.5166,2022,572,0,331,60.4155,2019,58,0,356,20.655,2021,716,0,217,75.7246,2019,903,1,89,93.1111,2022,162,1,87,20.6699,2022,737,1,470,88.7305,2023,126,1,479,58.5555,2022,839,0,153,76.4299,2023,547,1,459,46.4478,2021,720,0,119,5.0934,2018,538,0,56,92.2164,2020,196,0,210,74.7193,2019,825,1,38,56.7895,2023,537,1,101,17.6442,2021,647,0,91,60.7351,2020,570,1,278,31.3895,2019,119,0,277,15.4151,2024,706,1,233,52.8222,2022,942,1,16,0.4916,2022,130,0,329,74.4885,2021,568,1,370,97.1911,2019,510,1,478,33.2489,2023,313,0,76,8.6017,2019,226,1,455,20.0141,2021,304,1,34,29.8372,2022,434,1,252,15.1072,2018,459,1,206
8
+ 207,C016,30,Tablet,Electronics,,1,2024-04-03,0,265,71.8898,2019,116,1,280,87.9216,2023,320,0,382,26.6246,2022,912,0,126,17.4748,2021,58,1,367,93.0463,2022,631,1,386,9.6227,2023,548,0,330,12.1544,2023,634,0,442,32.835,2022,918,0,19,59.5029,2023,840,0,340,59.201,2024,110,1,395,11.0989,2019,26,1,12,42.8658,2020,530,1,96,37.1809,2021,597,0,39,16.3902,2023,198,1,130,64.8193,2019,807,0,433,30.7963,2022,256,1,219,34.2227,2019,232,0,491,12.2157,2024,438,0,41,73.7527,2023,284,0,222,21.8408,2024,416,0,235,7.0395,2019,411,0,434,49.7094,2020,18,1,469,86.6347,2018,683,1,403,96.3588,2023,481,1,362,62.7104,2023,427,1,471,14.8864,2021,1,0,166,68.4557,2018,922,0,346,10.6033,2022,953,1,136,64.1519,2018,560,0,78,19.5549,2022,940,1,164,41.9916,2021,430,1,370,86.3754,2021,546,0,290,62.9747,2018,510,1,374,3.6041,2024,889,1,421,27.3496,2021,567,0,308,7.7162,2019,277,1,77,9.4002,2020,959,0,373,14.6274,2022,20,1,70,9.0394,2021,845,1,221,16.4333,2024,58,0,41,41.3513,2022,41,0,362,20.6832,2022,886,1,103,99.787,2024,999,0,3,12.5775,2019,119,1,381,49.5031,2021,898,1,152,60.3482,2022,830,0,299,42.9194,2019,511,0,82,22.063,2018,120,0,204,68.7238,2018,631,1,83,97.0545,2021,849,1,45,51.1389,2018,754,0,398,82.4235,2019,495,1,21,68.6911,2018,889,1,438,40.0348,2018,93,1,29,46.1159,2022,269,0,70,6.4716,2024,153,0,388,42.4485,2023,178,0,11,46.2245,2023,770,0,142,77.2047,2019,442,0,422,97.2884,2018,658,1,192,66.525,2018,930,1,278,44.7849,2019,97,1,343,39.8109,2024,335,0,262,76.8382,2021,856,1,456,42.8609,2021,334,1,457,16.685,2022,41,1,114,52.9922,2021,578,1,29,93.1926,2021,243,0,166,39.3911,2019,110,0,157,14.6875,2024,367,0,447,8.5159,2022,388,1,32,39.743,2021,343,1,165,97.1287,2019,153,1,284,22.6679,2021,485,0,293,5.9869,2024,923,0,87,10.9361,2018,730,1,31,27.4888,2022,492,0,378,68.7228,2023,732,0,32
9
+ 208,C017,60,Perfume,Beauty,2400.0,2,2024-04-12,0,326,6.9968,2020,471,0,305,19.4635,2023,66,1,496,87.4468,2024,640,0,485,82.6297,2021,983,0,100,54.2937,2023,231,0,430,80.8464,2021,535,1,12,22.366,2024,341,1,235,57.3504,2021,66,1,265,10.2271,2018,602,1,130,17.0828,2019,966,1,206,37.943,2024,834,0,358,64.0517,2018,303,0,197,55.1762,2018,747,1,345,53.6794,2018,853,1,204,24.3553,2019,828,1,450,37.3206,2021,921,0,355,62.7176,2024,397,0,489,27.5355,2018,289,0,59,95.8878,2018,183,0,109,66.6641,2019,7,0,24,39.7175,2018,96,1,374,25.6543,2023,643,1,179,79.9477,2021,397,1,412,73.7287,2020,122,1,164,30.9832,2022,653,1,363,70.6665,2022,571,1,197,1.1548,2024,546,0,121,29.8997,2022,529,0,122,21.2284,2019,456,0,455,26.27,2021,368,0,481,16.0842,2023,438,1,26,70.3823,2022,235,1,231,92.3911,2024,576,0,344,49.1334,2021,901,0,166,1.5027,2024,848,1,419,31.0963,2018,559,1,388,29.5128,2022,9,1,460,70.2901,2018,219,1,40,61.8301,2018,373,0,112,98.1138,2021,270,1,148,65.3153,2023,815,1,44,19.1692,2018,697,1,3,58.8934,2019,854,1,275,29.0303,2023,589,1,193,97.9875,2018,223,0,326,13.3591,2019,433,1,14,81.9647,2021,937,1,490,65.3571,2024,113,1,488,34.4021,2020,781,1,278,44.3207,2021,679,0,440,95.3307,2023,78,0,264,76.7891,2023,42,0,190,13.2315,2019,776,0,76,32.3114,2024,266,0,295,26.3068,2024,171,0,254,58.4507,2021,174,0,300,85.8559,2019,143,1,279,59.4612,2019,665,0,135,53.8899,2019,519,0,186,32.1206,2023,254,1,212,90.4273,2023,188,1,48,0.0412,2019,85,0,170,89.3062,2020,148,1,376,85.9028,2019,293,1,219,54.3066,2018,549,0,375,99.3657,2022,34,1,41,92.8819,2018,746,1,470,32.7056,2021,392,0,358,59.4006,2023,249,0,195,51.9326,2020,986,0,19,74.3725,2022,114,0,338,11.5208,2018,991,0,263,2.1276,2022,793,1,225,44.0696,2023,904,0,307,72.72,2020,626,1,400,15.9934,2021,43,1,414,6.2271,2018,878,0,460,99.7837,2019,612,0,381
10
+ 208,C017,60,Perfume,Beauty,2400.0,2,2024-04-12,0,34,45.6125,2024,312,0,175,8.2049,2023,902,1,94,18.5698,2019,949,0,446,47.8692,2022,987,0,25,24.3007,2019,952,1,293,25.8798,2018,318,1,489,93.0111,2023,937,1,169,54.1033,2022,670,1,294,36.4716,2020,142,1,173,77.6098,2024,866,0,83,50.186,2019,821,1,313,55.7647,2021,286,0,345,80.2094,2024,425,0,293,47.193,2022,391,1,423,59.7603,2022,512,1,37,27.5346,2021,539,0,248,98.0003,2022,91,0,71,48.2215,2019,994,0,389,82.5785,2020,336,0,361,43.8958,2019,831,0,209,45.1824,2024,639,1,329,99.9777,2019,791,0,473,79.3618,2019,533,1,474,14.6466,2022,145,0,234,40.2764,2022,969,1,363,40.4386,2024,546,1,311,83.8329,2021,191,1,336,43.8155,2024,198,1,466,68.2438,2020,781,0,192,25.796,2024,815,0,304,4.6488,2019,992,0,238,4.8737,2018,673,1,141,19.3653,2023,501,1,424,0.9585,2022,4,0,435,84.1431,2023,314,1,194,90.3502,2023,455,0,148,56.7554,2019,666,0,413,71.3292,2018,836,1,461,38.6077,2019,226,0,428,43.092,2023,903,1,461,11.9734,2023,774,0,248,37.7957,2020,368,1,168,21.0916,2019,304,1,418,10.0847,2020,608,0,161,63.3442,2024,758,0,55,21.3317,2023,587,0,279,27.5169,2022,575,1,223,79.2744,2018,145,1,75,10.9557,2018,848,0,494,54.7042,2023,469,1,104,73.164,2020,861,0,60,54.8141,2021,909,1,6,32.952,2022,9,0,36,6.5099,2020,93,0,154,21.832,2020,626,1,17,31.6463,2018,992,1,51,93.964,2020,96,1,9,22.0469,2023,280,1,228,74.9672,2021,930,0,471,39.8195,2021,454,0,345,45.4705,2018,183,1,399,81.5536,2018,201,1,428,15.475,2020,260,0,227,74.2783,2023,256,0,64,29.3621,2019,482,1,54,99.3205,2018,397,1,41,37.164,2024,382,0,125,51.8648,2024,590,1,422,7.1596,2020,868,0,57,26.298,2020,245,0,69,12.2785,2018,782,0,122,92.5319,2024,395,1,131,36.8383,2020,829,1,409,86.8219,2018,97,0,54,78.7951,2021,242,0,201,13.8689,2019,155,1,248,98.9428,2019,544,0,224,20.8499,2022,813,1,159
ceo_brief_env/tasks/risk_brief/ground_truth.csv ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ metric,value
2
+ data_quality_score,0.8333
3
+ total_revenue,271309.09
4
+ top_category,Electronics
5
+ projection_next_quarter,-64505.45
6
+ variance_pct,117.05
7
+ break_even_units,25.88
8
+ memo_score,0.703
ceo_brief_env/tasks/risk_brief/metadata.json ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "title": "Board risk brief — data quality, compliance exposure, and capital allocation",
3
+ "difficulty": "hard",
4
+ "max_steps": 14,
5
+ "instruction": "Prepare a board-level risk brief after an internal audit flagged data-quality gaps, delivery exposure, and uncertainty in the operating plan. Run the full office: quantify data issues, finance downside and break-even sensitivity, strategy stance on NVDA/AAPL/JPM under risk controls, and an HR/comms memo that names variance, projection, strategy, and risk governance. The final brief must be suitable for audit committee review.",
6
+ "required_experts": [
7
+ "analyst",
8
+ "finance",
9
+ "strategy",
10
+ "hr"
11
+ ],
12
+ "memo_audience": "Board audit committee and CFO",
13
+ "hr_required_terms": [
14
+ "variance",
15
+ "projection",
16
+ "strategy",
17
+ "risk"
18
+ ],
19
+ "plan_value": 125000,
20
+ "fixed_cost": 44000,
21
+ "unit_margin": 1700
22
+ }
ceo_brief_env/tasks/risk_brief/raw.csv ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ OrderID,CustomerID,ExpiryDays,Product,Category,Price,Quantity,OrderDate,dim_0001,dim_0002,dim_0003,dim_0004,dim_0005,dim_0006,dim_0007,dim_0008,dim_0009,dim_0010,dim_0011,dim_0012,dim_0013,dim_0014,dim_0015,dim_0016,dim_0017,dim_0018,dim_0019,dim_0020,dim_0021,dim_0022,dim_0023,dim_0024,dim_0025,dim_0026,dim_0027,dim_0028,dim_0029,dim_0030,dim_0031,dim_0032,dim_0033,dim_0034,dim_0035,dim_0036,dim_0037,dim_0038,dim_0039,dim_0040,dim_0041,dim_0042,dim_0043,dim_0044,dim_0045,dim_0046,dim_0047,dim_0048,dim_0049,dim_0050,dim_0051,dim_0052,dim_0053,dim_0054,dim_0055,dim_0056,dim_0057,dim_0058,dim_0059,dim_0060,dim_0061,dim_0062,dim_0063,dim_0064,dim_0065,dim_0066,dim_0067,dim_0068,dim_0069,dim_0070,dim_0071,dim_0072,dim_0073,dim_0074,dim_0075,dim_0076,dim_0077,dim_0078,dim_0079,dim_0080,dim_0081,dim_0082,dim_0083,dim_0084,dim_0085,dim_0086,dim_0087,dim_0088,dim_0089,dim_0090,dim_0091,dim_0092,dim_0093,dim_0094,dim_0095,dim_0096,dim_0097,dim_0098,dim_0099,dim_0100,dim_0101,dim_0102,dim_0103,dim_0104,dim_0105,dim_0106,dim_0107,dim_0108,dim_0109,dim_0110,dim_0111,dim_0112,dim_0113,dim_0114,dim_0115,dim_0116,dim_0117,dim_0118,dim_0119,dim_0120,dim_0121,dim_0122,dim_0123,dim_0124,dim_0125,dim_0126,dim_0127,dim_0128,dim_0129,dim_0130,dim_0131,dim_0132,dim_0133,dim_0134,dim_0135,dim_0136,dim_0137,dim_0138,dim_0139,dim_0140,dim_0141,dim_0142,dim_0143,dim_0144,dim_0145,dim_0146,dim_0147,dim_0148,dim_0149,dim_0150,dim_0151,dim_0152,dim_0153,dim_0154,dim_0155,dim_0156,dim_0157,dim_0158,dim_0159,dim_0160,dim_0161,dim_0162,dim_0163,dim_0164,dim_0165,dim_0166,dim_0167,dim_0168,dim_0169,dim_0170,dim_0171,dim_0172,dim_0173,dim_0174,dim_0175,dim_0176,dim_0177,dim_0178,dim_0179,dim_0180,dim_0181,dim_0182,dim_0183,dim_0184,dim_0185,dim_0186,dim_0187,dim_0188,dim_0189,dim_0190,dim_0191,dim_0192,dim_0193,dim_0194,dim_0195,dim_0196,dim_0197,dim_0198,dim_0199,dim_0200,dim_0201,dim_0202,dim_0203,dim_0204,dim_0205,dim_0206,dim_0207,dim_0208,dim_0209,dim_0210,dim_0211,dim_0212,dim_0213,dim_0214,dim_0215,dim_0216,dim_0217,dim_0218,dim_0219,dim_0220,dim_0221,dim_0222,dim_0223,dim_0224,dim_0225,dim_0226,dim_0227,dim_0228,dim_0229,dim_0230,dim_0231,dim_0232,dim_0233,dim_0234,dim_0235,dim_0236,dim_0237,dim_0238,dim_0239,dim_0240,dim_0241,dim_0242,dim_0243,dim_0244,dim_0245,dim_0246,dim_0247,dim_0248,dim_0249,dim_0250,dim_0251,dim_0252,dim_0253,dim_0254,dim_0255,dim_0256,dim_0257,dim_0258,dim_0259,dim_0260,dim_0261,dim_0262,dim_0263,dim_0264,dim_0265,dim_0266,dim_0267,dim_0268,dim_0269,dim_0270,dim_0271,dim_0272,dim_0273,dim_0274,dim_0275,dim_0276,dim_0277,dim_0278,dim_0279,dim_0280,dim_0281,dim_0282,dim_0283,dim_0284,dim_0285,dim_0286,dim_0287,dim_0288,dim_0289,dim_0290,dim_0291,dim_0292,dim_0293,dim_0294,dim_0295,dim_0296,dim_0297,dim_0298,dim_0299,dim_0300,dim_0301,dim_0302,dim_0303,dim_0304,dim_0305,dim_0306,dim_0307,dim_0308,dim_0309,dim_0310,dim_0311,dim_0312,dim_0313,dim_0314,dim_0315,dim_0316,dim_0317,dim_0318,dim_0319,dim_0320,dim_0321,dim_0322,dim_0323,dim_0324,dim_0325,dim_0326,dim_0327,dim_0328,dim_0329,dim_0330,dim_0331,dim_0332,dim_0333,dim_0334,dim_0335,dim_0336,dim_0337,dim_0338,dim_0339,dim_0340,dim_0341,dim_0342,dim_0343,dim_0344,dim_0345,dim_0346,dim_0347,dim_0348,dim_0349,dim_0350,dim_0351,dim_0352,dim_0353,dim_0354,dim_0355,dim_0356,dim_0357,dim_0358,dim_0359,dim_0360,dim_0361,dim_0362,dim_0363,dim_0364,dim_0365,dim_0366,dim_0367,dim_0368,dim_0369,dim_0370,dim_0371,dim_0372,dim_0373,dim_0374,dim_0375,dim_0376,dim_0377,dim_0378,dim_0379,dim_0380,dim_0381,dim_0382,dim_0383,dim_0384,dim_0385,dim_0386,dim_0387,dim_0388,dim_0389,dim_0390,dim_0391,dim_0392
2
+ 701,C400,30,Workstation,Electronics,96000.0,1.0,2024-01-05,1,29,11.2991,2024,570,1,50,81.1799,2023,469,1,398,35.0699,2024,482,1,34,76.8981,2020,913,1,301,49.0841,2019,311,0,404,87.1558,2018,700,1,490,47.5491,2023,213,0,403,17.7827,2022,882,1,40,2.8595,2021,337,0,108,35.8678,2018,173,0,187,11.7391,2021,984,0,218,76.582,2023,619,0,207,7.1317,2020,75,0,480,9.2095,2023,602,0,104,2.6198,2023,945,0,400,24.3749,2022,413,0,123,72.9151,2024,757,0,70,77.7896,2023,787,1,484,79.7165,2023,877,0,111,68.4621,2019,984,1,488,44.3529,2022,647,1,344,36.5666,2024,436,0,199,45.5387,2021,749,1,434,64.7971,2021,535,1,60,22.1585,2019,596,0,267,46.6497,2019,27,1,154,78.7417,2023,205,1,329,54.2622,2021,31,0,73,31.2542,2018,847,1,235,92.122,2021,555,1,246,95.9976,2021,737,0,104,83.7357,2018,583,1,268,13.6289,2021,742,1,52,16.7124,2018,243,1,302,10.2863,2019,510,0,93,92.223,2024,860,1,243,98.1271,2022,827,0,485,18.6065,2021,861,1,269,0.2961,2018,751,0,344,29.387,2021,145,1,200,98.955,2024,112,1,437,34.2847,2020,429,1,485,64.8237,2020,551,1,231,63.1177,2019,631,1,241,7.9994,2018,846,1,373,18.1263,2022,878,0,224,3.7138,2019,504,1,315,80.1548,2023,167,0,246,18.9959,2023,274,1,84,31.0602,2022,863,0,139,89.972,2022,567,1,215,84.2751,2018,465,1,74,77.668,2020,998,0,364,51.6699,2018,107,0,253,18.1034,2022,884,1,114,57.335,2023,856,0,340,78.0612,2022,507,1,128,86.0943,2018,240,0,343,93.8413,2019,537,1,389,3.1262,2024,377,1,393,68.1358,2022,293,0,229,52.2671,2020,601,1,81,71.0462,2023,610,0,257,71.6916,2018,764,1,6,83.0219,2019,739,0,364,49.1545,2018,521,1,146,38.7768,2023,903,1,86,48.2355,2023,478,0,10,60.0645,2021,558,0,49,51.997,2023,544,0,30,68.7592,2018,131,1,101,91.4483,2023,878,0,486,88.0248,2021,599,1,255,67.7937,2019,92,1,42,6.0513,2023,403,0,336,92.4016,2019,585,0,199,71.6468,2018,0,0,31,46.115,2023,963,0,385
3
+ 702,C401,45,Phone,Electronics,43000.0,,2024-01-17,0,47,42.714,2022,388,1,439,23.88,2023,709,0,229,99.5758,2019,551,1,397,39.5286,2019,210,1,49,0.5169,2023,86,1,120,23.3109,2020,477,1,128,71.8955,2023,922,1,296,46.6067,2021,11,0,22,44.3949,2021,69,1,10,56.5891,2018,529,1,82,54.0554,2020,484,1,372,41.1074,2020,447,0,384,4.2352,2021,352,0,61,85.8191,2019,861,0,183,94.536,2019,198,1,163,47.4782,2021,688,0,249,32.0634,2022,119,0,394,66.1202,2024,356,1,105,91.4205,2024,602,0,75,56.426,2021,618,1,349,68.7099,2018,689,0,148,38.807,2020,35,1,98,46.647,2020,100,1,36,39.199,2024,662,0,98,45.8999,2024,419,0,18,2.7541,2019,886,1,187,69.9959,2018,15,0,451,78.0545,2019,906,1,231,4.3398,2024,734,0,203,44.1864,2024,758,1,479,31.4024,2018,251,1,115,24.5504,2024,925,1,256,34.494,2018,428,0,372,91.0575,2020,52,1,206,31.6637,2023,825,0,94,7.1261,2024,36,1,200,31.7797,2020,354,1,313,14.6798,2020,931,1,269,46.5135,2022,450,1,331,60.4155,2018,377,1,357,79.7807,2021,595,0,451,90.5237,2020,100,0,87,20.6699,2023,620,1,395,6.0762,2024,697,0,420,18.3574,2024,507,0,459,46.4478,2023,809,0,316,62.3586,2018,186,0,99,55.6374,2020,818,1,38,56.7895,2021,882,0,342,43.1359,2019,70,0,285,50.5273,2018,918,1,277,15.4151,2022,129,0,394,1.632,2018,584,0,66,10.4551,2022,999,0,370,97.1911,2021,931,1,356,50.9879,2019,139,1,114,6.1589,2019,250,1,34,29.8372,2021,410,0,387,13.5284,2020,138,0,43,98.7983,2023,622,0,184,0.75,2019,991,1,291,57.1036,2021,762,1,325,66.3414,2023,951,0,386,20.4953,2021,55,0,66,20.6337,2019,412,0,214,83.608,2020,167,0,12,93.8023,2023,18,0,70,5.5315,2024,942,1,350,61.1375,2018,304,0,329,46.1645,2021,183,0,111,58.3231,2021,29,0,215,14.455,2020,219,0,329,19.4221,2019,323,1,443,40.7827,2023,42,1,170,15.199,2021,580,1,273,79.2681,2020,378,1,398,80.2092,2021,740,1,185,98.3139,2021,444,0,220
4
+ 703,C402,15,Headphones,Electronics,8200.0,2.0,2024-01-26,1,162,89.2765,2022,442,0,473,74.9081,2023,335,1,53,70.9068,2019,583,1,108,8.2629,2019,982,0,383,18.4114,2020,843,1,269,15.2606,2024,638,0,478,50.1232,2021,625,1,55,12.2749,2023,556,1,104,94.3254,2021,461,0,436,62.1067,2021,88,0,453,63.8216,2021,431,0,282,79.5521,2023,542,1,278,14.6176,2018,143,1,256,33.4572,2018,470,0,421,16.3202,2023,160,0,52,97.5301,2021,651,1,328,88.0274,2021,719,1,250,0.2501,2018,666,1,349,35.597,2023,523,1,279,97.0134,2020,98,1,382,92.4716,2021,862,1,115,5.2908,2023,60,1,387,74.2714,2022,621,0,154,41.3644,2023,135,1,284,92.996,2018,978,1,198,38.6482,2019,982,0,218,86.1945,2023,768,1,220,37.7807,2020,263,1,351,66.6189,2018,339,1,423,66.4048,2024,821,1,41,41.3513,2018,221,1,96,88.633,2019,968,1,499,36.1479,2020,724,1,381,49.5031,2024,555,1,67,75.8066,2022,844,0,256,69.888,2022,694,1,204,68.7238,2022,154,1,222,3.2801,2018,395,0,377,3.889,2023,220,1,21,68.6911,2024,151,0,162,74.0095,2018,778,1,135,61.5566,2022,203,0,388,42.4485,2019,850,1,297,53.4918,2019,249,1,221,6.7502,2020,525,1,192,66.525,2024,639,1,1,55.1035,2022,819,0,168,86.86,2024,436,1,456,42.8609,2020,562,0,496,24.9022,2019,960,0,289,68.7651,2020,366,1,166,39.3911,2018,80,0,260,89.0157,2024,202,0,194,42.2193,2018,396,1,165,97.1287,2019,866,1,220,54.5223,2022,826,1,461,29.1912,2019,737,0,31,27.4888,2021,369,0,498,66.5258,2018,523,1,332,46.2714,2024,938,0,67,74.6614,2020,79,1,333,69.2029,2018,545,1,124,46.8531,2022,896,0,13,80.1894,2019,962,1,149,72.5293,2023,210,0,399,26.3104,2019,959,0,395,71.4436,2020,350,0,81,28.6851,2024,461,0,478,80.0292,2020,402,0,495,37.5534,2021,718,0,343,46.0989,2019,367,0,399,13.4429,2019,806,1,439,53.7388,2018,702,1,196,72.4649,2021,393,1,45,10.256,2019,295,1,167,71.4386,2020,179,0,43,24.2341,2022,798,0,156,57.7549,2018,19,0,452
5
+ 704,C403,60,Tablet,Electronics,,1.0,2024-02-09,1,265,71.8898,2018,336,1,98,88.4471,2023,961,1,456,94.725,2023,907,1,367,93.0463,2022,787,1,404,4.7322,2022,214,0,317,30.0124,2022,595,0,19,59.5029,2023,721,1,86,5.7787,2023,30,1,14,80.266,2022,826,0,96,37.1809,2022,274,0,268,84.2711,2019,411,1,404,43.2429,2020,485,1,219,34.2227,2019,267,0,138,78.0429,2018,746,1,142,44.134,2022,993,0,235,7.0395,2020,258,1,129,64.9228,2024,182,1,342,44.0091,2023,197,1,362,62.7104,2020,224,0,353,56.5413,2020,226,0,461,38.0537,2020,80,1,136,64.1519,2021,398,0,132,89.0276,2020,713,0,215,68.9897,2022,966,1,290,62.9747,2021,134,1,246,60.1625,2023,165,1,284,19.5553,2020,127,1,77,9.4002,2024,379,1,172,2.0021,2018,313,0,187,44.2648,2018,440,1,148,65.3153,2023,961,0,96,88.6686,2018,948,1,427,0.4257,2020,36,1,193,97.9875,2019,805,0,279,83.0474,2018,552,0,468,16.2863,2022,929,0,488,34.4021,2023,504,1,181,84.9543,2024,52,0,40,79.5751,2020,262,1,190,13.2315,2023,831,0,404,9.3724,2022,654,1,86,13.9261,2018,312,0,300,85.8559,2019,510,1,355,77.0651,2019,935,1,260,84.5444,2020,314,1,212,90.4273,2019,376,1,137,9.7238,2020,722,1,74,52.4767,2019,181,1,219,54.3066,2021,716,1,402,4.1763,2018,126,0,373,5.7149,2018,65,0,358,59.4006,2019,65,0,448,36.744,2018,298,0,57,6.3114,2018,671,0,263,2.1276,2023,142,0,397,48.5795,2022,48,0,313,17.4253,2022,660,1,414,6.2271,2024,791,0,289,73.2198,2023,823,0,56,14.5921,2021,672,1,389,41.8046,2019,708,1,466,19.7705,2021,489,0,479,81.2941,2019,341,0,135,66.541,2022,497,0,277,39.9045,2024,732,0,89,9.289,2018,141,1,327,50.7167,2024,759,1,61,58.6488,2018,551,1,26,46.5216,2020,788,1,219,63.8497,2019,620,1,225,99.5888,2021,941,1,172,56.8707,2024,495,0,424,74.1335,2024,905,0,179,77.6533,2018,433,0,311,31.1968,2021,914,1,170,27.8721,2020,735,0,364,11.9546,2023,913,0,397,44.7967,2022,966,1,16
6
+ 705,C404,30,Desk,Home,11800.0,1.0,2024-02-19,0,326,6.9968,2021,611,1,415,32.0166,2024,554,0,320,25.1378,2021,647,1,100,54.2937,2019,997,1,18,54.8351,2018,690,0,171,88.5219,2024,133,1,265,10.2271,2022,218,1,260,11.0745,2020,761,1,417,2.3196,2022,50,1,197,55.1762,2023,69,1,85,19.8423,2020,859,0,414,86.7129,2023,466,0,355,62.7176,2020,522,1,235,43.842,2018,817,1,92,44.3295,2023,571,1,24,39.7175,2018,961,1,103,1.8432,2020,333,0,199,80.7418,2021,581,0,164,30.9832,2022,646,1,298,0.1635,2020,249,1,273,69.1898,2018,51,0,122,21.2284,2021,401,1,88,94.0439,2024,959,1,219,74.1111,2022,645,1,231,92.3911,2022,828,1,205,88.9204,2020,747,1,424,61.6248,2023,635,0,388,29.5128,2018,162,0,356,83.6259,2024,817,0,114,85.6201,2021,133,0,461,11.9734,2023,836,1,189,36.818,2020,655,1,153,83.7223,2018,32,0,161,63.3442,2023,308,1,107,58.7303,2021,731,1,288,44.5737,2023,601,1,75,10.9557,2023,846,1,273,46.9717,2019,996,0,430,12.0217,2021,692,0,6,32.952,2018,871,1,33,9.3636,2020,757,0,313,3.2618,2020,363,1,51,93.964,2018,444,0,111,28.0697,2021,585,1,465,94.2951,2020,725,1,345,45.4705,2019,200,1,407,20.1806,2023,922,0,130,45.487,2023,156,1,64,29.3621,2021,361,0,496,39.7893,2018,607,0,191,24.8653,2021,749,0,422,7.1596,2024,349,0,132,24.5381,2018,4,1,391,24.3354,2024,873,1,131,36.8383,2023,235,1,434,9.7381,2018,86,0,122,40.1331,2018,400,1,248,98.9428,2021,836,1,105,81.3327,2020,844,0,275,48.61,2022,587,0,272,16.9499,2021,274,1,148,63.7686,2023,86,0,408,43.9928,2018,271,0,97,80.2777,2018,832,0,289,24.0179,2024,598,1,204,97.1628,2019,486,0,275,73.7156,2020,708,0,256,17.6641,2024,473,0,459,51.7645,2022,156,0,71,19.7144,2020,459,0,231,33.6317,2018,507,0,494,44.7828,2019,63,0,113,69.0979,2022,154,1,405,53.1931,2018,966,0,45,6.5847,2020,650,0,325,35.3675,2020,674,0,413,63.8429,2024,519,1,12,24.9617,2021,230,1,449
7
+ 706,C405,45,Camera,Electronics,40500.0,1.0,2024-03-04,1,34,45.6125,2020,830,0,41,90.2784,2019,48,1,474,89.2955,2021,735,0,25,24.3007,2024,45,0,130,31.8463,2024,549,1,468,33.7572,2021,919,1,294,36.4716,2018,110,1,388,86.6995,2019,713,0,411,62.6685,2021,512,1,345,80.2094,2020,889,1,236,39.1209,2023,557,0,256,7.3639,2019,371,0,248,98.0003,2018,710,1,241,99.422,2023,199,1,169,72.3343,2021,125,1,209,45.1824,2022,19,0,499,79.1581,2024,540,1,267,94.8339,2019,536,0,234,40.2764,2024,260,1,202,54.6238,2022,542,1,96,67.1621,2021,983,1,466,68.2438,2023,463,0,129,81.5038,2022,909,1,496,47.6105,2018,396,0,141,19.3653,2021,198,0,5,0.4034,2024,778,0,158,38.7775,2024,61,0,148,56.7554,2022,883,0,147,86.1987,2019,821,0,400,15.8295,2022,831,0,67,4.6801,2023,583,0,160,26.8546,2022,322,1,294,32.9468,2020,82,1,180,62.9521,2022,716,1,250,96.6011,2023,456,0,189,12.0439,2021,492,0,17,78.8695,2020,303,0,142,11.3961,2020,290,0,404,62.6016,2022,72,1,5,83.4673,2020,278,1,228,61.3194,2019,546,1,418,17.7742,2024,644,0,331,14.4934,2018,934,1,220,65.5122,2020,428,0,21,71.4861,2023,835,1,43,3.1781,2018,227,1,323,67.1978,2022,807,1,429,75.0757,2023,622,1,383,10.9511,2018,236,0,59,30.7807,2023,459,0,397,93.1844,2023,140,0,448,91.817,2020,764,1,95,42.9711,2019,90,1,161,69.223,2018,741,1,317,80.4519,2023,126,0,326,32.5647,2024,337,1,498,74.0223,2022,522,1,111,43.5206,2018,507,0,156,1.336,2019,185,0,224,64.7166,2022,833,1,250,52.3901,2022,924,1,113,68.1389,2021,13,0,280,4.7899,2019,174,0,178,91.6959,2021,336,1,382,14.2737,2024,437,0,434,88.7794,2024,186,1,277,96.3444,2022,697,1,53,53.584,2024,272,0,195,88.535,2019,108,0,277,3.8178,2023,673,1,239,53.2048,2018,287,1,450,25.8803,2022,820,0,306,28.9628,2020,124,1,234,57.2559,2018,813,0,13,84.3891,2019,428,0,311,36.2306,2019,364,1,67,75.298,2021,140,1,436,57.1664,2023,785,1,26
8
+ 707,C406,90,Serum,Beauty,1200.0,3.0,2024-03-18,0,345,53.8047,2022,804,0,253,33.0549,2019,44,1,79,22.5355,2020,355,1,377,62.2929,2021,422,0,70,80.0632,2022,545,1,173,50.0556,2024,2,0,97,1.6601,2022,665,1,187,54.262,2023,951,0,426,52.6644,2021,551,1,311,97.2634,2021,138,1,224,19.2569,2022,147,0,72,80.7577,2022,918,1,104,8.4668,2018,122,1,49,63.8585,2021,100,1,466,23.732,2024,895,0,494,23.6486,2020,198,1,197,77.2568,2018,326,0,226,65.3289,2023,647,1,82,86.3155,2024,292,1,151,66.6084,2022,959,0,378,45.3949,2018,424,1,246,94.8786,2018,859,0,464,86.5524,2023,793,1,206,85.1208,2022,92,0,353,91.7173,2019,565,1,345,6.7008,2020,499,0,211,73.9902,2022,359,1,417,98.8436,2023,592,1,408,54.5499,2019,90,0,245,91.0177,2024,274,1,158,27.5686,2023,279,1,106,70.9682,2023,997,0,299,72.2503,2024,815,1,230,43.0567,2018,277,0,121,30.1199,2020,429,0,31,93.3484,2023,575,1,62,53.1013,2020,599,0,467,79.9392,2024,511,1,273,2.2151,2021,545,0,352,12.463,2023,755,0,441,55.8703,2019,461,1,414,83.714,2019,676,0,90,87.0907,2019,315,0,262,63.1309,2018,772,0,336,45.0808,2022,402,1,130,32.6755,2024,152,1,31,27.8969,2020,398,0,367,66.4586,2022,256,1,189,69.9446,2024,687,0,197,44.6948,2022,529,0,470,13.8614,2024,914,0,139,9.179,2023,536,0,291,96.6608,2021,85,1,348,54.4408,2020,650,0,368,14.9704,2021,841,1,39,98.6302,2020,59,0,23,30.4665,2018,532,1,404,24.1201,2022,200,1,105,7.258,2023,259,0,22,33.6908,2021,940,1,167,24.4553,2020,650,0,108,51.1963,2019,735,1,237,49.5187,2023,417,0,490,31.9363,2019,499,0,79,18.7186,2018,612,0,379,7.7791,2020,505,0,392,61.4556,2018,785,0,399,77.1285,2019,34,0,400,55.4015,2021,779,0,29,89.2132,2020,497,0,430,4.7329,2021,775,0,297,40.4557,2023,170,1,158,48.8236,2022,690,1,278,2.814,2024,435,0,39,70.3749,2019,567,1,247,34.3636,2020,721,0,28,6.5223,2023,506,1,371,49.2449,2019,579,0,268
9
+ 708,C407,30,Shoes,Fashion,3300.0,2.0,2024-03-29,0,28,81.0418,2019,329,1,498,26.2027,2018,266,1,423,70.1049,2021,140,0,209,6.8436,2024,969,0,278,41.0682,2020,121,1,167,40.8495,2024,996,1,117,28.2872,2019,114,0,477,41.7888,2022,110,1,43,12.8289,2018,497,0,453,39.3874,2023,626,0,480,88.3355,2019,648,0,168,9.4579,2021,614,0,158,56.0907,2019,58,0,194,53.0077,2022,737,0,395,55.5247,2021,901,0,30,17.7533,2024,457,1,312,83.9569,2020,866,0,211,10.5889,2019,757,1,177,73.1204,2022,589,0,384,62.1249,2019,684,1,314,34.0848,2024,892,0,441,10.3404,2021,255,0,70,97.9444,2021,419,1,327,14.9061,2024,860,1,163,46.0826,2021,995,0,437,38.0631,2021,273,1,339,98.7845,2021,311,1,191,46.2244,2020,78,0,403,41.9937,2019,354,0,121,80.8868,2020,191,1,381,87.1074,2024,532,1,465,71.488,2024,110,0,92,42.7386,2024,468,0,137,67.7976,2019,342,0,350,6.3912,2024,600,1,318,8.9182,2021,918,1,294,4.7646,2021,632,0,382,30.6837,2020,735,0,424,24.1036,2021,572,1,474,19.2626,2020,713,0,1,16.7838,2020,696,0,495,31.3454,2019,162,1,121,63.3282,2019,941,1,187,71.3009,2023,527,0,418,47.3461,2024,547,0,324,47.9481,2023,238,1,488,20.9736,2018,479,0,52,49.8454,2019,825,0,57,72.1301,2021,202,0,12,30.3385,2021,104,1,290,58.5497,2022,119,1,238,94.3822,2022,465,1,4,56.6079,2023,410,0,266,52.7364,2018,568,1,19,24.1914,2018,955,1,138,41.3301,2021,190,0,337,5.0866,2021,304,1,346,58.6776,2024,503,1,27,61.9477,2024,180,1,213,7.9824,2018,910,1,353,1.6168,2023,270,1,317,4.7318,2021,323,1,471,1.5135,2019,993,0,399,43.0371,2022,487,1,211,7.0348,2023,433,0,63,79.4095,2021,310,1,128,41.357,2024,578,1,265,66.0135,2019,585,1,134,97.1917,2021,526,0,10,53.2297,2024,761,0,204,0.6791,2020,372,1,318,85.7888,2021,715,1,457,46.2532,2024,846,1,288,28.4242,2023,302,1,236,98.0117,2022,149,1,368,74.8703,2018,502,0,195,34.3001,2018,203,1,17,61.6395,2022,715,0,336
10
+ 709,C408,60,Monitor,Electronics,19000.0,1.0,2024-04-08,0,175,47.8909,2021,202,1,200,87.079,2021,457,0,477,63.5543,2019,250,0,425,50.7921,2018,251,1,140,18.531,2024,463,1,62,23.7837,2018,866,1,283,63.5852,2018,346,0,182,51.6689,2018,303,0,315,5.8712,2021,37,0,275,47.6738,2019,98,1,213,33.3327,2019,840,1,258,1.7105,2018,346,0,196,1.4748,2018,290,0,397,69.0669,2022,932,0,147,88.4798,2019,777,0,261,97.003,2024,819,1,268,50.5681,2024,515,0,456,81.5716,2022,624,0,299,69.8387,2024,791,0,231,16.0837,2020,943,1,426,0.4444,2022,977,1,309,48.7493,2019,879,1,104,30.4319,2020,653,0,378,76.6094,2019,137,1,68,61.5046,2022,25,0,480,67.6713,2020,494,1,17,96.8785,2022,736,0,167,72.2481,2022,747,0,498,66.0362,2024,618,1,192,64.6547,2022,58,1,122,73.3119,2018,725,0,70,56.1347,2023,588,1,377,81.9548,2018,119,1,308,7.2491,2018,303,0,93,91.2426,2019,819,0,154,51.0652,2023,120,1,249,35.6257,2018,166,0,469,22.5172,2023,953,1,289,52.5254,2023,495,1,418,19.1392,2024,877,1,372,48.4309,2023,263,0,244,21.549,2023,153,0,270,26.1433,2018,20,1,212,12.3694,2018,538,1,476,41.3417,2023,658,0,317,82.8539,2022,555,1,26,25.5726,2018,893,0,329,85.4137,2018,856,1,190,3.9267,2021,915,0,476,93.9418,2018,928,1,233,52.0063,2023,243,0,466,84.561,2018,312,0,56,3.6933,2022,743,0,214,31.2558,2024,343,0,104,68.1593,2024,567,0,18,4.8924,2018,727,0,233,84.0284,2022,730,0,41,14.0718,2018,756,0,485,33.3656,2024,425,0,175,89.6337,2023,281,1,387,46.8855,2020,63,1,406,3.8396,2024,384,0,484,10.7994,2019,985,1,433,41.9599,2019,150,0,71,11.2811,2019,934,1,191,56.3049,2023,50,0,10,10.3323,2019,995,0,291,67.7881,2018,356,0,402,41.1253,2023,493,1,93,28.884,2020,351,1,222,23.0337,2021,753,1,312,39.0545,2019,831,0,107,1.498,2023,185,0,298,71.996,2023,885,1,333,32.0281,2023,799,1,358,69.2373,2021,22,1,29,27.2678,2021,261,1,292,85.948,2024,673,1,317
11
+ 710,C409,30,Keyboard,Electronics,3600.0,3.0,2024-04-17,1,377,36.3951,2018,559,1,82,88.6105,2022,874,1,356,61.5928,2022,58,1,56,76.6528,2023,771,0,356,91.2929,2018,223,0,426,84.918,2024,918,1,233,12.7016,2020,679,0,455,59.6133,2024,379,1,454,3.9599,2021,530,1,169,2.2761,2022,76,1,165,84.3403,2023,243,1,206,64.0305,2022,256,1,353,86.6067,2022,983,1,166,35.3545,2022,958,1,397,94.8278,2021,416,1,85,2.8694,2021,868,0,38,76.396,2018,799,0,475,25.3447,2021,481,1,421,65.0742,2023,942,0,460,94.3213,2021,11,0,36,73.0891,2023,953,1,60,22.1366,2024,155,1,347,19.9297,2022,160,1,287,22.6341,2022,546,0,156,87.2321,2022,748,1,202,13.4762,2022,15,0,379,5.5991,2018,277,1,448,60.948,2022,921,1,64,61.4745,2019,738,1,126,7.2064,2020,270,0,323,87.3784,2021,86,1,364,43.203,2021,64,0,449,87.2666,2024,589,0,316,34.6785,2021,652,1,393,66.5856,2021,660,1,384,5.7473,2021,113,0,98,79.2803,2024,555,0,359,83.4134,2023,904,0,495,88.8027,2022,42,0,453,93.4389,2021,151,0,86,76.0442,2018,263,0,103,2.7304,2019,174,0,270,68.4925,2019,557,1,167,97.1451,2019,467,0,199,46.1039,2020,254,1,128,68.0284,2021,95,1,298,88.7513,2023,117,1,422,27.1523,2021,293,0,424,80.4072,2019,749,0,46,81.709,2021,768,1,68,48.6141,2020,392,0,193,12.8098,2022,389,1,45,67.9927,2020,687,1,56,65.9521,2024,991,0,121,62.7859,2020,449,1,261,87.688,2019,541,1,105,61.8234,2023,43,1,396,14.6636,2022,920,1,195,24.6699,2024,632,0,417,76.7522,2018,422,1,18,91.2658,2020,635,0,124,7.7524,2019,914,0,398,67.0776,2019,103,0,89,99.2569,2019,549,1,338,74.9316,2021,92,0,272,50.1049,2021,77,0,156,44.5596,2023,692,0,167,48.6705,2020,763,0,94,15.8735,2019,349,1,431,3.4488,2024,660,0,405,82.7042,2019,264,0,428,49.8136,2019,338,0,209,57.9633,2020,606,0,158,80.1876,2024,664,0,100,67.1782,2023,196,1,283,47.4361,2018,716,1,320,45.8388,2023,777,1,290,7.3426,2022,771,0,383
12
+ 711,C410,45,Phone,Electronics,42000.0,1.0,2024-04-29,0,272,91.1024,2023,609,1,389,53.5688,2023,754,0,416,28.2974,2024,983,1,40,63.3961,2018,861,1,123,53.4032,2021,504,1,432,96.1176,2018,66,1,288,31.6162,2021,260,0,215,6.1848,2018,581,0,111,89.3017,2021,303,1,410,9.7654,2019,690,1,173,29.1723,2023,359,0,188,15.7017,2018,921,1,375,66.0324,2023,979,0,413,2.0443,2023,967,0,28,22.7686,2020,7,1,38,23.1003,2021,747,1,183,0.4943,2018,628,1,393,58.1929,2023,122,1,498,62.4852,2024,727,1,154,10.8294,2023,69,1,264,97.5929,2023,529,0,61,65.6891,2024,910,0,430,64.2018,2019,51,0,178,28.9301,2022,235,1,158,73.1798,2022,689,0,147,31.5309,2024,63,0,403,68.8166,2023,559,0,332,30.0548,2024,825,1,263,78.507,2018,386,0,205,28.4976,2024,903,0,264,33.5015,2023,495,1,247,55.1445,2019,210,0,436,9.3946,2021,608,1,153,78.919,2022,109,0,102,41.3952,2022,275,0,171,14.1166,2022,145,1,308,11.8544,2024,988,0,364,38.205,2021,731,1,112,86.5166,2022,909,1,161,87.3357,2021,70,0,273,5.3497,2021,218,0,306,93.1111,2022,992,1,477,16.9701,2024,16,1,379,83.157,2023,749,0,188,76.4299,2023,454,0,187,91.9783,2018,797,0,60,44.6919,2023,154,1,227,74.7193,2019,256,1,357,15.4229,2023,108,0,237,36.0042,2019,371,0,380,31.3895,2019,590,1,230,63.7532,2023,113,1,351,43.8288,2024,122,0,229,74.4885,2021,395,1,354,30.1564,2023,818,0,383,51.1065,2019,787,1,451,20.0141,2021,155,0,482,59.0639,2022,448,0,33,69.7741,2021,814,0,434,55.3449,2018,436,0,413,70.5357,2021,115,1,209,27.0294,2019,984,0,157,1.5446,2020,227,0,346,87.2463,2020,627,1,74,11.84,2018,581,0,322,78.6573,2022,390,0,374,99.8867,2021,353,1,152,5.6584,2022,318,0,327,54.731,2024,195,1,447,86.7438,2021,743,0,15,93.1257,2023,865,1,340,98.0048,2020,700,1,446,54.2752,2024,895,1,283,71.2797,2019,845,0,268,35.0642,2018,3,1,383,22.6124,2018,791,0,159,4.0251,2020,506,0,230,67.2233,2023,534,0,304
13
+ 712,C411,75,Racket,Sports,2100.0,,2024-05-10,0,114,25.1746,2023,350,1,378,60.6678,2019,185,1,435,95.9221,2022,987,0,103,84.1202,2020,586,1,291,37.9491,2021,930,0,451,75.0386,2021,670,0,173,40.845,2024,345,0,388,41.7529,2021,501,1,205,75.9259,2020,286,1,355,68.8055,2019,585,0,194,46.8454,2023,597,1,322,61.7538,2019,539,1,418,82.3195,2019,140,0,8,65.9815,2020,825,0,404,89.5488,2021,831,1,66,19.5934,2021,657,1,198,75.8448,2018,793,0,55,75.7624,2024,145,0,195,28.4838,2020,727,1,209,94.1845,2018,838,1,183,71.9382,2022,198,0,498,69.5826,2020,384,1,451,92.0282,2022,46,0,112,74.1567,2020,673,0,41,61.211,2019,848,0,354,88.0356,2021,841,0,357,36.4826,2019,455,1,250,30.0309,2018,261,0,286,60.0315,2024,29,0,265,16.4333,2024,260,1,455,23.8735,2019,943,0,332,18.7975,2024,878,0,48,12.5775,2019,637,1,492,30.32,2024,124,0,347,9.34,2019,998,1,34,22.063,2018,831,0,421,52.4875,2023,513,1,219,49.6862,2018,76,0,234,82.4235,2019,538,1,104,46.2018,2023,264,1,66,6.036,2021,244,1,24,6.4716,2024,994,0,13,23.9393,2021,900,0,360,20.2078,2018,5,1,117,97.2884,2018,648,1,80,68.9284,2024,44,1,80,17.6141,2020,765,0,233,76.8382,2021,986,1,393,14.1893,2021,856,0,357,68.0392,2024,21,1,278,93.1926,2021,9,0,91,19.7164,2018,162,0,487,52.228,2018,748,1,387,39.743,2021,495,1,477,9.6685,2022,117,0,257,89.2016,2021,596,1,181,10.9361,2018,118,0,447,26.3534,2020,808,0,358,83.8325,2021,50,1,423,46.3884,2023,592,1,60,82.5943,2018,265,0,179,17.1842,2021,820,0,59,1.235,2024,342,1,321,4.6736,2022,677,0,356,31.3905,2022,701,0,11,6.0762,2024,947,1,147,91.0698,2024,97,0,401,4.2701,2021,994,0,110,78.5132,2022,435,0,108,98.0623,2022,980,0,394,25.1927,2022,579,1,154,21.9261,2020,328,1,107,66.8068,2020,584,1,85,26.7067,2021,684,1,44,32.0077,2023,29,0,128,41.4427,2022,141,1,56,42.6543,2019,232,0,41,63.3698,2019,961,1,226
evaluation.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
inference.py ADDED
@@ -0,0 +1,365 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ from __future__ import annotations
3
+
4
+ import argparse
5
+ import hashlib
6
+ import json
7
+ import os
8
+ import sys
9
+ from pathlib import Path
10
+ from typing import Any, Callable, Optional
11
+
12
+ API_BASE_URL = os.getenv('API_BASE_URL', 'https://router.huggingface.co/v1')
13
+ MODEL_NAME = os.getenv('MODEL_NAME', 'Qwen/Qwen2.5-72B-Instruct')
14
+ API_KEY = os.getenv('API_KEY') or os.getenv('HF_TOKEN') or ''
15
+ BENCHMARK = 'autodatalab_plus'
16
+ TASKS = [t.strip() for t in os.getenv('AUTODATALAB_PLUS_TASKS', 'easy_brief,medium_brief,hard_brief,expert_brief').split(',') if t.strip()]
17
+
18
+ _LOG_SCORE_MIN = 0.001
19
+ _LOG_SCORE_MAX = 0.999
20
+
21
+ REPO = Path(__file__).resolve().parent
22
+ if str(REPO) not in sys.path:
23
+ sys.path.insert(0, str(REPO))
24
+
25
+ from ceo_brief_env.environment import CEOBriefEnvironment, oracle_action_for_observation, required_experts_for_task
26
+ from ceo_brief_env.models import CoSAction
27
+
28
+
29
+ def _bool_str(v: bool) -> str:
30
+ return str(bool(v)).lower()
31
+
32
+
33
+ def log_start(task: str, env: str, model: str) -> None:
34
+ print(f'[START] task={task} env={env} model={model}', flush=True)
35
+
36
+
37
+ def _clamp_log_reward(r: float) -> float:
38
+ return max(_LOG_SCORE_MIN, min(_LOG_SCORE_MAX, float(r)))
39
+
40
+
41
+ def log_step(step: int, action: str, reward: float, done: bool, error: Optional[str]) -> None:
42
+ err = error if error else 'null'
43
+ r = _clamp_log_reward(reward)
44
+ print(f'[STEP] step={step} action={action} reward={r:.2f} done={_bool_str(done)} error={err}', flush=True)
45
+
46
+
47
+ def log_end(success: bool, steps: int, score: float, rewards: list[float]) -> None:
48
+ s = _clamp_log_reward(score)
49
+ rewards_str = ','.join(f'{_clamp_log_reward(r):.2f}' for r in rewards)
50
+ print(f'[END] success={_bool_str(success)} steps={steps} score={s:.2f} rewards={rewards_str}', flush=True)
51
+
52
+
53
+ def _action_str(action: CoSAction) -> str:
54
+ return json.dumps(action.model_dump(exclude_none=True), separators=(',', ':'), sort_keys=True)
55
+
56
+
57
+ def _single_baseline(obs) -> CoSAction:
58
+ for e in required_experts_for_task(obs.task_name):
59
+ if e not in obs.consulted_experts:
60
+ return CoSAction(action_type='consult', expert_id=e)
61
+ if obs.current_brief is None:
62
+ return CoSAction(action_type='summarize')
63
+ return CoSAction(action_type='submit')
64
+
65
+
66
+ def _roundrobin_baseline(obs) -> CoSAction:
67
+ for expert in ['analyst', 'finance', 'strategy', 'hr']:
68
+ if expert not in obs.consulted_experts:
69
+ return CoSAction(action_type='consult', expert_id=expert)
70
+ if obs.current_brief is None:
71
+ return CoSAction(action_type='summarize')
72
+ return CoSAction(action_type='submit')
73
+
74
+
75
+ _TRAINED_POLICY: dict = {"model": None, "load_status": None, "load_warned": False}
76
+
77
+
78
+ def _trained_action(obs) -> CoSAction:
79
+ import numpy as np
80
+ import torch
81
+
82
+ from training.train_cos_local import (
83
+ ACTIONS,
84
+ PolicyNet,
85
+ featurize,
86
+ load_policy_state_dict_from_file,
87
+ )
88
+
89
+ if _TRAINED_POLICY["model"] is None:
90
+ import sys
91
+
92
+ ckpt = REPO / "training" / "checkpoints" / "cos_final.pt"
93
+ if not ckpt.exists():
94
+ ckpt = REPO / "training" / "checkpoints" / "cos_ckpt0.pt"
95
+ model = PolicyNet()
96
+ status = "random_init"
97
+ if ckpt.exists():
98
+ try:
99
+ status = load_policy_state_dict_from_file(model, ckpt)
100
+ except (OSError, RuntimeError, KeyError) as e:
101
+ print(
102
+ f"[inference] warning: could not load {ckpt} ({e}); using random init.",
103
+ file=sys.stderr,
104
+ )
105
+ model = PolicyNet()
106
+ status = f"load_failed: {e}"
107
+ else:
108
+ print(
109
+ "[inference] warning: no checkpoint; using random PolicyNet. "
110
+ "Run: python3 training/train_cos_local.py",
111
+ file=sys.stderr,
112
+ )
113
+ if status != "ok" and "padded" in status and not _TRAINED_POLICY.get("load_warned"):
114
+ print(
115
+ f"[inference] loaded checkpoint with compat: {status}. "
116
+ "Re-run training for best results: python3 training/train_cos_local.py",
117
+ file=sys.stderr,
118
+ )
119
+ _TRAINED_POLICY["load_warned"] = True
120
+ model.eval()
121
+ _TRAINED_POLICY["model"] = model
122
+ _TRAINED_POLICY["load_status"] = status
123
+ model = _TRAINED_POLICY["model"]
124
+ feats = torch.from_numpy(featurize(obs)).unsqueeze(0)
125
+ with torch.no_grad():
126
+ logits = model(feats)
127
+ idx = int(torch.argmax(logits, dim=-1).item())
128
+ return ACTIONS[idx]
129
+
130
+
131
+ def _cache_path(task_name: str, step_count: int, prompt: str) -> Path:
132
+ prompt_hash = hashlib.sha256(prompt.encode('utf-8')).hexdigest()[:16]
133
+ cache_dir = REPO / 'cache'
134
+ cache_dir.mkdir(exist_ok=True)
135
+ return cache_dir / f'{task_name}_step{step_count}_{prompt_hash}.json'
136
+
137
+
138
+ def _llm_action(obs) -> CoSAction:
139
+ from openai import OpenAI
140
+
141
+ client = OpenAI(base_url=API_BASE_URL, api_key=API_KEY)
142
+ prompt = (
143
+ 'You are the Chief of Staff in a multi-agent company simulation. '
144
+
145
+ f'Task: {obs.task_name}. Instruction: {obs.instruction}. '
146
+
147
+ f'Consulted experts: {obs.consulted_experts}. Current issues: {obs.issues}. '
148
+
149
+ 'Return exactly one JSON object with keys action_type, expert_id, sub_question_id, notes. '
150
+
151
+ 'Valid experts: analyst, finance, hr, strategy. Valid actions: consult, ask, summarize, submit, noop.'
152
+ )
153
+ cache_path = _cache_path(obs.task_name, obs.step_count, prompt)
154
+ if cache_path.exists():
155
+ try:
156
+ payload = json.loads(cache_path.read_text(encoding='utf-8'))
157
+ except json.JSONDecodeError:
158
+ payload = {}
159
+ if not payload or 'action_type' not in payload:
160
+ payload = {'action_type': 'noop'}
161
+ return CoSAction.model_validate(payload)
162
+ completion = client.chat.completions.create(
163
+ model=MODEL_NAME,
164
+ temperature=0.1,
165
+ messages=[{'role': 'system', 'content': 'Respond with strict JSON only.'}, {'role': 'user', 'content': prompt}],
166
+ )
167
+ text = completion.choices[0].message.content or '{}'
168
+ start = text.find('{')
169
+ end = text.rfind('}')
170
+ if start != -1 and end != -1 and end >= start:
171
+ try:
172
+ payload = json.loads(text[start : end + 1])
173
+ except json.JSONDecodeError:
174
+ payload = {}
175
+ else:
176
+ payload = {}
177
+ if not payload or 'action_type' not in payload:
178
+ payload = {'action_type': 'noop'}
179
+ cache_path.write_text(json.dumps(payload, indent=2), encoding='utf-8')
180
+ return CoSAction.model_validate(payload)
181
+
182
+
183
+ def run_episode_collect(
184
+ task: str,
185
+ picker: Callable,
186
+ label: str,
187
+ use_rag: bool = False,
188
+ quiet: bool = False,
189
+ ) -> dict[str, Any]:
190
+ """
191
+ Run one episode and return structured data (for --export). Same dynamics as `run_episode`.
192
+ """
193
+ env = CEOBriefEnvironment()
194
+ obs = env.reset(task=task, use_rag=use_rag)
195
+ rewards: list[float] = []
196
+ trace: list[dict[str, Any]] = []
197
+ steps = 0
198
+ score = 0.001
199
+ success = False
200
+ err: Optional[str] = None
201
+ if not quiet:
202
+ log_start(task=task, env=f'{BENCHMARK} rag={use_rag}', model=label)
203
+ try:
204
+ while not obs.done and steps < obs.max_steps:
205
+ steps += 1
206
+ action = picker(obs)
207
+ obs = env.step(action)
208
+ r = float(obs.reward)
209
+ rewards.append(r)
210
+ if not quiet:
211
+ log_step(steps, _action_str(action), r, bool(obs.done), None)
212
+ trace.append(
213
+ {
214
+ "step": steps,
215
+ "action": action.model_dump(exclude_none=True),
216
+ "reward": round(r, 4),
217
+ "done": bool(obs.done),
218
+ "consulted_experts": list(obs.consulted_experts),
219
+ }
220
+ )
221
+ score = float(obs.terminal_grader_score or 0.001)
222
+ score = max(0.001, min(0.999, score))
223
+ success = score >= 0.5
224
+ except Exception as exc: # noqa: BLE001
225
+ err = str(exc).replace('\n', ' ')
226
+ if not quiet:
227
+ log_step(max(steps, 1), 'exception', _LOG_SCORE_MIN, True, err)
228
+ finally:
229
+ if not quiet:
230
+ log_end(success, steps, score, rewards)
231
+ return {
232
+ "task": task,
233
+ "policy_label": label,
234
+ "use_rag": use_rag,
235
+ "success": success,
236
+ "steps": steps,
237
+ "terminal_score": round(score, 4),
238
+ "cumulative_reward": round(sum(rewards), 4),
239
+ "step_rewards": [round(x, 4) for x in rewards],
240
+ "trace": trace,
241
+ "error": err,
242
+ "final_instruction": obs.instruction,
243
+ "task_difficulty": obs.task_difficulty,
244
+ "max_steps": obs.max_steps,
245
+ "consulted_experts": list(obs.consulted_experts),
246
+ "current_brief": obs.current_brief.model_dump() if obs.current_brief is not None else None,
247
+ "expert_reports": {k: v.model_dump() for k, v in obs.expert_reports.items()},
248
+ }
249
+
250
+
251
+ def run_episode(task: str, picker: Callable, label: str, use_rag: bool = False) -> float:
252
+ out = run_episode_collect(task, picker, label, use_rag=use_rag, quiet=False)
253
+ return float(out["terminal_score"])
254
+
255
+
256
+ def main() -> int:
257
+ parser = argparse.ArgumentParser()
258
+ parser.add_argument('--oracle', action='store_true')
259
+ parser.add_argument('--baseline', choices=['single', 'roundrobin'])
260
+ parser.add_argument('--trained', action='store_true',
261
+ help='use locally trained CoS policy (training/checkpoints/cos_final.pt)')
262
+ parser.add_argument('--task')
263
+ parser.add_argument('--ablation', action='store_true')
264
+ parser.add_argument(
265
+ '--rag',
266
+ action='store_true',
267
+ help='enable organizational memory (RAG) in experts and grounding in the grader (default: off, team parity)',
268
+ )
269
+ parser.add_argument(
270
+ '--export',
271
+ metavar='DIR',
272
+ help='save one JSON per task (plus summary.json) under DIR; uses all tasks from env unless --task is set',
273
+ )
274
+ args = parser.parse_args()
275
+ use_rag = bool(args.rag)
276
+
277
+ if args.trained:
278
+ picker = _trained_action
279
+ label = 'trained-cos'
280
+ elif args.baseline == 'single':
281
+ picker = _single_baseline
282
+ label = 'single-baseline'
283
+ elif args.baseline == 'roundrobin':
284
+ picker = _roundrobin_baseline
285
+ label = 'roundrobin-baseline'
286
+ elif args.oracle or not API_KEY:
287
+ picker = oracle_action_for_observation
288
+ label = 'oracle'
289
+ else:
290
+ picker = _llm_action
291
+ label = MODEL_NAME
292
+
293
+ tasks = [args.task] if args.task else TASKS
294
+
295
+ if args.export:
296
+ out_dir = Path(args.export).resolve()
297
+ out_dir.mkdir(parents=True, exist_ok=True)
298
+ by_task: dict[str, dict[str, Any]] = {}
299
+ for task in tasks:
300
+ row = run_episode_collect(task, picker, label, use_rag=use_rag, quiet=True)
301
+ by_task[task] = row
302
+ (out_dir / f'{task}.json').write_text(
303
+ json.dumps(row, indent=2, default=str), encoding='utf-8'
304
+ )
305
+ print(
306
+ f'[export] {task} terminal={row["terminal_score"]} steps={row["steps"]} success={row["success"]}',
307
+ flush=True,
308
+ )
309
+ mean_term = float(sum(t['terminal_score'] for t in by_task.values()) / max(len(by_task), 1))
310
+ summary: dict[str, Any] = {
311
+ 'policy_label': label,
312
+ 'use_rag': use_rag,
313
+ 'checkpoint_load': _TRAINED_POLICY.get('load_status') if label == 'trained-cos' else None,
314
+ 'tasks': {
315
+ t: {
316
+ 'terminal_score': by_task[t]['terminal_score'],
317
+ 'success': by_task[t]['success'],
318
+ 'steps': by_task[t]['steps'],
319
+ 'cumulative_reward': by_task[t]['cumulative_reward'],
320
+ }
321
+ for t in by_task
322
+ },
323
+ 'mean_terminal': round(mean_term, 4),
324
+ 'export_dir': str(out_dir),
325
+ }
326
+ (out_dir / 'summary.json').write_text(json.dumps(summary, indent=2), encoding='utf-8')
327
+ print(f'[export] wrote {len(tasks) + 1} files to {out_dir}', flush=True)
328
+ return 0
329
+ else:
330
+ results = {}
331
+ for task in tasks:
332
+ results[task] = run_episode(task, picker, label, use_rag=use_rag)
333
+
334
+ if args.ablation and not args.export:
335
+ ablations: dict[str, dict[str, float]] = {}
336
+ if picker is _single_baseline:
337
+ ablations['single'] = dict(results)
338
+ else:
339
+ ablations['single'] = {
340
+ task: run_episode(task, _single_baseline, 'single-baseline', use_rag=use_rag) for task in tasks
341
+ }
342
+ if picker is _roundrobin_baseline:
343
+ ablations['roundrobin'] = dict(results)
344
+ else:
345
+ ablations['roundrobin'] = {
346
+ task: run_episode(task, _roundrobin_baseline, 'roundrobin-baseline', use_rag=use_rag) for task in tasks
347
+ }
348
+ ablations['oracle_or_llm'] = dict(results)
349
+ trained_ckpt = REPO / 'training' / 'checkpoints' / 'cos_final.pt'
350
+ if trained_ckpt.exists():
351
+ if picker is _trained_action:
352
+ ablations['trained_cos'] = dict(results)
353
+ else:
354
+ ablations['trained_cos'] = {
355
+ task: run_episode(task, _trained_action, 'trained-cos', use_rag=use_rag) for task in tasks
356
+ }
357
+ cache_dir = REPO / 'cache'
358
+ cache_dir.mkdir(exist_ok=True)
359
+ (cache_dir / 'ablation_results.json').write_text(json.dumps(ablations, indent=2), encoding='utf-8')
360
+
361
+ return 0
362
+
363
+
364
+ if __name__ == '__main__':
365
+ raise SystemExit(main())
memory/__init__.py ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Organizational memory (RAG pillar) for AutoDataLab Solo.
2
+
3
+ Exposes a module-level retriever keyed at ``memory/`` so every specialist
4
+ and the grader can share the same corpus index without passing it through
5
+ every expert signature.
6
+ """
7
+ from __future__ import annotations
8
+
9
+ from pathlib import Path
10
+
11
+ from .retriever import MemoryHit, Retriever
12
+
13
+ _CORPUS_DIR = Path(__file__).resolve().parent
14
+ _retriever: Retriever | None = None
15
+
16
+
17
+ def get_retriever() -> Retriever:
18
+ """Return the process-wide retriever, building it lazily on first use."""
19
+ global _retriever
20
+ if _retriever is None:
21
+ _retriever = Retriever(_CORPUS_DIR)
22
+ return _retriever
23
+
24
+
25
+ def corpus_dir() -> Path:
26
+ return _CORPUS_DIR
27
+
28
+
29
+ __all__ = ["MemoryHit", "Retriever", "get_retriever", "corpus_dir"]
memory/history/exemplar_memo.md ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # EXEMPLAR-MEMO: Canonical HR Memo from Last Quarter
2
+
3
+ Audience: Ops leads.
4
+
5
+ Hook: Electronics is still our revenue anchor and needs a defend-first posture this week.
6
+
7
+ Highlights:
8
+ - Analyst flagged Electronics as the top category at 38 percent of total revenue.
9
+ - Finance projection for next quarter is plus 6.2 percent with a plus-or-minus 15 percent band.
10
+ - Variance versus plan is plus 4.1 percent, so we are favorable but not safe.
11
+
12
+ Call to action: Ops leads, lock the Electronics staffing plan by Thursday and align promotion windows to the break-even unit target.
memory/history/last_quarter_review.md ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # HIST-Q1: Last Quarter Executive Review
2
+
3
+ ## Headline numbers
4
+ - Top revenue category: Electronics.
5
+ - Data quality score on ingest: 0.82.
6
+ - Variance versus plan: +4.1 percent (favorable).
7
+ - Break-even pressure: moderate; staffing tightened in weeks 10 and 11.
8
+
9
+ ## Lessons recorded for future briefs
10
+ 1. Always include a break-even reference when promotions are being considered.
11
+ 2. HR memos landed better with the Ops team when the first line named them explicitly.
12
+ 3. Strategy recommendations that skipped the variance signal were rated lower by the CEO.
13
+
14
+ ## Precedent for this quarter
15
+ The CEO expects every brief to cite `variance_pct` and `projection_next_quarter` somewhere in the Strategy and HR layers.
memory/policies/compliance_policy.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # POLICY-COMP-01: Company Compliance Policy
2
+
3
+ ## Publication gate
4
+ A CEO brief cannot be published when any of the following is true:
5
+ 1. `data_quality_score` is below 0.70.
6
+ 2. Strategy recommendations do not cite at least one Analyst metric and one Finance metric.
7
+ 3. HR memo does not name its intended audience.
8
+
9
+ ## Grounding rule
10
+ Every specialist report in the final brief must cite at least one source from `memory/`. This ensures that reasoning is grounded in our SOPs, historical precedents, and compliance policies rather than improvised at rollout time.
11
+
12
+ ## Audit
13
+ Citations are programmatically verified against the live `memory/` index. A citation that does not resolve to a real chunk is treated as hallucinated and drops the grounding reward for that specialist.
memory/retriever.py ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """Zero-dependency TF-IDF retriever over the company-memory corpus.
2
+
3
+ Design choices
4
+ --------------
5
+ * Pure Python (re + math) so it runs inside OpenEnv/HF Space containers
6
+ without pulling sentence-transformers / faiss / langchain.
7
+ * Each markdown file is split into paragraph-level chunks, indexed with
8
+ token-frequency + inverse-document-frequency, and queried with cosine
9
+ over sparse TF-IDF vectors.
10
+ * The retriever is the *single source of grounding truth* consumed by
11
+ both the specialists (at rollout time) and the grader (at scoring
12
+ time), so the reward becomes verifiable instead of fuzzy.
13
+ """
14
+ from __future__ import annotations
15
+
16
+ import math
17
+ import re
18
+ from dataclasses import dataclass
19
+ from pathlib import Path
20
+ from typing import Dict, Iterable, List, Sequence, Tuple
21
+
22
+ _WORD_RE = re.compile(r"[a-zA-Z][a-zA-Z0-9_-]{1,}")
23
+
24
+
25
+ def _tokenize(text: str) -> List[str]:
26
+ return [tok.lower() for tok in _WORD_RE.findall(text or "")]
27
+
28
+
29
+ @dataclass
30
+ class MemoryHit:
31
+ source: str
32
+ snippet: str
33
+ score: float
34
+
35
+ def as_citation(self) -> str:
36
+ """Stable string form used in ExpertReport.citations and briefs."""
37
+ return f"memory:{self.source}"
38
+
39
+
40
+ class Retriever:
41
+ """Lightweight TF-IDF retriever over a directory of markdown files."""
42
+
43
+ def __init__(self, corpus_dir: Path) -> None:
44
+ self.corpus_dir = Path(corpus_dir)
45
+ self._docs: List[Tuple[str, str]] = []
46
+ self._vocab: Dict[str, int] = {}
47
+ self._tf: List[Dict[int, float]] = []
48
+ self._df: Dict[int, int] = {}
49
+ self._norms: List[float] = []
50
+ self._load()
51
+ self._build_index()
52
+
53
+ # -- indexing ----------------------------------------------------------
54
+
55
+ def _load(self) -> None:
56
+ for path in sorted(self.corpus_dir.rglob("*.md")):
57
+ rel = str(path.relative_to(self.corpus_dir)).replace("\\", "/")
58
+ text = path.read_text(encoding="utf-8")
59
+ chunks = [chunk.strip() for chunk in re.split(r"\n\s*\n", text) if chunk.strip()]
60
+ for i, chunk in enumerate(chunks):
61
+ self._docs.append((f"{rel}#chunk{i}", chunk))
62
+
63
+ def _build_index(self) -> None:
64
+ for _, text in self._docs:
65
+ tokens = _tokenize(text)
66
+ tf_doc: Dict[int, float] = {}
67
+ for tok in tokens:
68
+ if tok not in self._vocab:
69
+ self._vocab[tok] = len(self._vocab)
70
+ idx = self._vocab[tok]
71
+ tf_doc[idx] = tf_doc.get(idx, 0.0) + 1.0
72
+ self._tf.append(tf_doc)
73
+ for idx in tf_doc:
74
+ self._df[idx] = self._df.get(idx, 0) + 1
75
+ self._num_docs = len(self._docs)
76
+ # cache L2 norms of tf-idf vectors for cosine similarity.
77
+ self._norms = []
78
+ for tf_doc in self._tf:
79
+ sq = 0.0
80
+ for idx, tf in tf_doc.items():
81
+ idf = math.log((self._num_docs + 1) / (self._df.get(idx, 1) + 1)) + 1.0
82
+ sq += (tf * idf) ** 2
83
+ self._norms.append(math.sqrt(sq) or 1.0)
84
+
85
+ # -- public API --------------------------------------------------------
86
+
87
+ def query(self, text: str, k: int = 3) -> List[MemoryHit]:
88
+ if not text or not self._docs:
89
+ return []
90
+ tokens = _tokenize(text)
91
+ if not tokens:
92
+ return []
93
+ q_tf: Dict[int, float] = {}
94
+ for tok in tokens:
95
+ if tok in self._vocab:
96
+ idx = self._vocab[tok]
97
+ q_tf[idx] = q_tf.get(idx, 0.0) + 1.0
98
+ if not q_tf:
99
+ return []
100
+ # query norm
101
+ q_sq = 0.0
102
+ for idx, tf in q_tf.items():
103
+ idf = math.log((self._num_docs + 1) / (self._df.get(idx, 1) + 1)) + 1.0
104
+ q_sq += (tf * idf) ** 2
105
+ q_norm = math.sqrt(q_sq) or 1.0
106
+
107
+ scores: List[Tuple[float, int]] = []
108
+ for doc_idx, tf_doc in enumerate(self._tf):
109
+ dot = 0.0
110
+ for idx, qt in q_tf.items():
111
+ tfd = tf_doc.get(idx)
112
+ if tfd is None:
113
+ continue
114
+ idf = math.log((self._num_docs + 1) / (self._df.get(idx, 1) + 1)) + 1.0
115
+ dot += (qt * idf) * (tfd * idf)
116
+ if dot <= 0.0:
117
+ continue
118
+ cosine = dot / (q_norm * self._norms[doc_idx])
119
+ scores.append((cosine, doc_idx))
120
+ scores.sort(reverse=True)
121
+ hits: List[MemoryHit] = []
122
+ for score, doc_idx in scores[: max(k, 0)]:
123
+ source, chunk = self._docs[doc_idx]
124
+ snippet = chunk.replace("\n", " ").strip()
125
+ if len(snippet) > 280:
126
+ snippet = snippet[:277] + "..."
127
+ hits.append(MemoryHit(source=source, snippet=snippet, score=round(float(score), 4)))
128
+ return hits
129
+
130
+ def sources(self) -> List[str]:
131
+ return [src for src, _ in self._docs]
132
+
133
+ def has_source(self, source: str) -> bool:
134
+ return any(src == source for src, _ in self._docs)
135
+
136
+ def contains_any(self, text: str, sources: Sequence[str]) -> bool:
137
+ """Return True if any of ``sources`` appears verbatim in ``text``.
138
+
139
+ Used by the grader to verify citations are grounded in the corpus
140
+ rather than hallucinated strings.
141
+ """
142
+ if not text:
143
+ return False
144
+ return any(src and src in text for src in sources)
145
+
146
+ def count_grounded_citations(self, citations: Iterable[str]) -> int:
147
+ known = set(self.sources())
148
+ n = 0
149
+ for citation in citations or []:
150
+ if not isinstance(citation, str) or not citation.startswith("memory:"):
151
+ continue
152
+ if citation[len("memory:"):] in known:
153
+ n += 1
154
+ return n
155
+
156
+
157
+ __all__ = ["MemoryHit", "Retriever"]